|
@@ -0,0 +1,104 @@
|
|
|
|
|
+#!/usr/bin/env python3
|
|
|
|
|
+#
|
|
|
|
|
+# Copyright (C) 2021 XiaoMi Corporation. All rights reserved.
|
|
|
|
|
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
|
+#
|
|
|
|
|
+
|
|
|
|
|
+import os
|
|
|
|
|
+import gdb
|
|
|
|
|
+
|
|
|
|
|
+# Get object file path from environment variable or use default value
|
|
|
|
|
+path_objs = os.getenv("OBJ_PATH", "~/objects/")
|
|
|
|
|
+
|
|
|
|
|
+# Expand user directory symbol (~)
|
|
|
|
|
+path_objs = os.path.expanduser(path_objs)
|
|
|
|
|
+print(f"Object files will be loaded from: {path_objs} on localhost")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def add_symbol_with_aot_info(aot_module_info):
|
|
|
|
|
+ """Add symbol file with AOT information to GDB and list current breakpoints."""
|
|
|
|
|
+ try:
|
|
|
|
|
+ text_addr = aot_module_info.get("code")
|
|
|
|
|
+ file_name = aot_module_info.get("name")
|
|
|
|
|
+
|
|
|
|
|
+ if not text_addr or not file_name:
|
|
|
|
|
+ print("Error: 'code' or 'name' missing in AOT module info.")
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # Extract base file name without extension
|
|
|
|
|
+ file_name_without_extension, _ = os.path.splitext(file_name)
|
|
|
|
|
+
|
|
|
|
|
+ # Remove directory part if present
|
|
|
|
|
+ file_name = os.path.basename(file_name_without_extension)
|
|
|
|
|
+
|
|
|
|
|
+ # Add .obj extension to the file name
|
|
|
|
|
+ file_name = file_name + ".obj"
|
|
|
|
|
+
|
|
|
|
|
+ # Construct the path for the symbol file
|
|
|
|
|
+ path_symfile = os.path.join(path_objs, file_name)
|
|
|
|
|
+
|
|
|
|
|
+ # Construct the command to add the symbol file
|
|
|
|
|
+ cmd = f"add-symbol-file {path_symfile} {text_addr}"
|
|
|
|
|
+ gdb.execute(cmd)
|
|
|
|
|
+
|
|
|
|
|
+ # Print current breakpoints
|
|
|
|
|
+ breakpoints = gdb.execute("info breakpoints", to_string=True)
|
|
|
|
|
+ print("Current breakpoints:", breakpoints)
|
|
|
|
|
+
|
|
|
|
|
+ except gdb.error as e:
|
|
|
|
|
+ print(f"GDB error: {e}")
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ print(f"Unexpected error: {e}")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class ReadGDynamicAotModule(gdb.Command):
|
|
|
|
|
+ """Command to read the g_dynamic_aot_module structure and extract information."""
|
|
|
|
|
+
|
|
|
|
|
+ def __init__(self):
|
|
|
|
|
+ super(self.__class__, self).__init__("read_gda", gdb.COMMAND_USER)
|
|
|
|
|
+
|
|
|
|
|
+ def invoke(self, args, from_tty):
|
|
|
|
|
+ """Retrieve and process the g_dynamic_aot_module structure."""
|
|
|
|
|
+ try:
|
|
|
|
|
+ aot_module = gdb.parse_and_eval("g_dynamic_aot_module")
|
|
|
|
|
+ aot_module_info = {}
|
|
|
|
|
+
|
|
|
|
|
+ # Ensure aot_module is a pointer and dereference it
|
|
|
|
|
+ if aot_module.type.code == gdb.TYPE_CODE_PTR:
|
|
|
|
|
+ aot_module = aot_module.dereference()
|
|
|
|
|
+
|
|
|
|
|
+ # Check if it's a structure type
|
|
|
|
|
+ if aot_module.type.strip_typedefs().code == gdb.TYPE_CODE_STRUCT:
|
|
|
|
|
+ for field in aot_module.type.fields():
|
|
|
|
|
+ field_name = field.name
|
|
|
|
|
+ var = aot_module[field_name]
|
|
|
|
|
+
|
|
|
|
|
+ if field_name == "name":
|
|
|
|
|
+ aot_module_info["name"] = var.string()
|
|
|
|
|
+ elif field_name == "code":
|
|
|
|
|
+ aot_module_info["code"] = str(var)
|
|
|
|
|
+
|
|
|
|
|
+ if "name" in aot_module_info and "code" in aot_module_info:
|
|
|
|
|
+ add_symbol_with_aot_info(aot_module_info)
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("Could not find 'name' or 'code' in Aot_module.")
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("Aot_module is not of struct type.")
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("Aot_module is not a pointer type.")
|
|
|
|
|
+ except gdb.error as e:
|
|
|
|
|
+ print(f"An error occurred: {e}")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def init():
|
|
|
|
|
+ """Initialize environment and set up debugger."""
|
|
|
|
|
+ # Register the command to gdb
|
|
|
|
|
+ ReadGDynamicAotModule()
|
|
|
|
|
+
|
|
|
|
|
+ # Set a breakpoint at function __enable_dynamic_aot_debug
|
|
|
|
|
+ breakpoint = gdb.Breakpoint("__enable_dynamic_aot_debug")
|
|
|
|
|
+ # Attach the self-defined command to the created breakpoint, read_gda means read global dynamic aot info.
|
|
|
|
|
+ breakpoint.commands = "read_gda"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+init()
|