diff options
Diffstat (limited to 'scripts/gdb')
-rw-r--r-- | scripts/gdb/linux/constants.py.in | 10 | ||||
-rw-r--r-- | scripts/gdb/linux/cpus.py | 15 | ||||
-rw-r--r-- | scripts/gdb/linux/device.py | 16 | ||||
-rw-r--r-- | scripts/gdb/linux/page_owner.py | 58 | ||||
-rw-r--r-- | scripts/gdb/linux/slab.py | 3 | ||||
-rw-r--r-- | scripts/gdb/linux/stackdepot.py | 6 | ||||
-rw-r--r-- | scripts/gdb/linux/symbols.py | 23 | ||||
-rw-r--r-- | scripts/gdb/linux/tasks.py | 33 | ||||
-rw-r--r-- | scripts/gdb/linux/vmalloc.py | 8 |
9 files changed, 76 insertions, 96 deletions
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index e3517d4ab8ec..e810e0c27ff1 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -66,10 +66,11 @@ LX_GDBPARSED(IRQD_LEVEL) LX_GDBPARSED(IRQ_HIDDEN) /* linux/module.h */ -LX_GDBPARSED(MOD_TEXT) -LX_GDBPARSED(MOD_DATA) -LX_GDBPARSED(MOD_RODATA) -LX_GDBPARSED(MOD_RO_AFTER_INIT) +if IS_BUILTIN(CONFIG_MODULES): + LX_GDBPARSED(MOD_TEXT) + LX_GDBPARSED(MOD_DATA) + LX_GDBPARSED(MOD_RODATA) + LX_GDBPARSED(MOD_RO_AFTER_INIT) /* linux/mount.h */ LX_VALUE(MNT_NOSUID) @@ -157,3 +158,4 @@ LX_CONFIG(CONFIG_STACKDEPOT) LX_CONFIG(CONFIG_PAGE_OWNER) LX_CONFIG(CONFIG_SLUB_DEBUG) LX_CONFIG(CONFIG_SLAB_FREELIST_HARDENED) +LX_CONFIG(CONFIG_MMU) diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index 255dc18cb9da..cba589e5b57d 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -179,6 +179,21 @@ def get_current_task(cpu): else: raise gdb.GdbError("Sorry, obtaining the current task is not allowed " "while running in userspace(EL0)") + elif utils.is_target_arch("riscv"): + current_tp = gdb.parse_and_eval("$tp") + scratch_reg = gdb.parse_and_eval("$sscratch") + + # by default tp points to current task + current_task = current_tp.cast(task_ptr_type) + + # scratch register is set 0 in trap handler after entering kernel. + # When hart is in user mode, scratch register is pointing to task_struct. + # and tp is used by user mode. So when scratch register holds larger value + # (negative address as ulong is larger value) than tp, then use scratch register. + if (scratch_reg.cast(utils.get_ulong_type()) > current_tp.cast(utils.get_ulong_type())): + current_task = scratch_reg.cast(task_ptr_type) + + return current_task.dereference() else: raise gdb.GdbError("Sorry, obtaining the current task is not yet " "supported with this arch") diff --git a/scripts/gdb/linux/device.py b/scripts/gdb/linux/device.py index 16376c5cfec6..0eabc5f4f8ca 100644 --- a/scripts/gdb/linux/device.py +++ b/scripts/gdb/linux/device.py @@ -36,26 +36,26 @@ def for_each_bus(): for kobj in kset_for_each_object(gdb.parse_and_eval('bus_kset')): subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') - yield subsys_priv['bus'] + yield subsys_priv def for_each_class(): for kobj in kset_for_each_object(gdb.parse_and_eval('class_kset')): subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') - yield subsys_priv['class'] + yield subsys_priv def get_bus_by_name(name): for item in for_each_bus(): - if item['name'].string() == name: + if item['bus']['name'].string() == name: return item raise gdb.GdbError("Can't find bus type {!r}".format(name)) def get_class_by_name(name): for item in for_each_class(): - if item['name'].string() == name: + if item['class']['name'].string() == name: return item raise gdb.GdbError("Can't find device class {!r}".format(name)) @@ -70,13 +70,13 @@ def klist_for_each(klist): def bus_for_each_device(bus): - for kn in klist_for_each(bus['p']['klist_devices']): + for kn in klist_for_each(bus['klist_devices']): dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_bus') yield dp['device'] def class_for_each_device(cls): - for kn in klist_for_each(cls['p']['klist_devices']): + for kn in klist_for_each(cls['klist_devices']): dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_class') yield dp['device'] @@ -103,7 +103,7 @@ class LxDeviceListBus(gdb.Command): def invoke(self, arg, from_tty): if not arg: for bus in for_each_bus(): - gdb.write('bus {}:\t{}\n'.format(bus['name'].string(), bus)) + gdb.write('bus {}:\t{}\n'.format(bus['bus']['name'].string(), bus)) for dev in bus_for_each_device(bus): _show_device(dev, level=1) else: @@ -123,7 +123,7 @@ class LxDeviceListClass(gdb.Command): def invoke(self, arg, from_tty): if not arg: for cls in for_each_class(): - gdb.write("class {}:\t{}\n".format(cls['name'].string(), cls)) + gdb.write("class {}:\t{}\n".format(cls['class']['name'].string(), cls)) for dev in class_for_each_device(cls): _show_device(dev, level=1) else: diff --git a/scripts/gdb/linux/page_owner.py b/scripts/gdb/linux/page_owner.py index 844fd5d0c912..8e713a09cfe7 100644 --- a/scripts/gdb/linux/page_owner.py +++ b/scripts/gdb/linux/page_owner.py @@ -122,27 +122,24 @@ class DumpPageOwner(gdb.Command): if not (page_ext['flags'] & (1 << PAGE_EXT_OWNER_ALLOCATED)): gdb.write("page_owner is not allocated\n") - try: - page_owner = self.get_page_owner(page_ext) - gdb.write("Page last allocated via order %d, gfp_mask: 0x%x, pid: %d, tgid: %d (%s), ts %u ns, free_ts %u ns\n" %\ - (page_owner["order"], page_owner["gfp_mask"],\ - page_owner["pid"], page_owner["tgid"], page_owner["comm"],\ - page_owner["ts_nsec"], page_owner["free_ts_nsec"])) - gdb.write("PFN: %d, Flags: 0x%x\n" % (pfn, page['flags'])) - if page_owner["handle"] == 0: - gdb.write('page_owner allocation stack trace missing\n') - else: - stackdepot.stack_depot_print(page_owner["handle"]) + page_owner = self.get_page_owner(page_ext) + gdb.write("Page last allocated via order %d, gfp_mask: 0x%x, pid: %d, tgid: %d (%s), ts %u ns, free_ts %u ns\n" %\ + (page_owner["order"], page_owner["gfp_mask"],\ + page_owner["pid"], page_owner["tgid"], page_owner["comm"].string(),\ + page_owner["ts_nsec"], page_owner["free_ts_nsec"])) + gdb.write("PFN: %d, Flags: 0x%x\n" % (pfn, page['flags'])) + if page_owner["handle"] == 0: + gdb.write('page_owner allocation stack trace missing\n') + else: + stackdepot.stack_depot_print(page_owner["handle"]) - if page_owner["free_handle"] == 0: - gdb.write('page_owner free stack trace missing\n') - else: - gdb.write('page last free stack trace:\n') - stackdepot.stack_depot_print(page_owner["free_handle"]) - if page_owner['last_migrate_reason'] != -1: - gdb.write('page has been migrated, last migrate reason: %s\n' % self.migrate_reason_names[page_owner['last_migrate_reason']]) - except: - gdb.write("\n") + if page_owner["free_handle"] == 0: + gdb.write('page_owner free stack trace missing\n') + else: + gdb.write('page last free stack trace:\n') + stackdepot.stack_depot_print(page_owner["free_handle"]) + if page_owner['last_migrate_reason'] != -1: + gdb.write('page has been migrated, last migrate reason: %s\n' % self.migrate_reason_names[page_owner['last_migrate_reason']]) def read_page_owner(self): pfn = self.min_pfn @@ -173,18 +170,13 @@ class DumpPageOwner(gdb.Command): pfn += 1 continue - try: - page_owner = self.get_page_owner(page_ext) - gdb.write("Page allocated via order %d, gfp_mask: 0x%x, pid: %d, tgid: %d (%s), ts %u ns, free_ts %u ns\n" %\ - (page_owner["order"], page_owner["gfp_mask"],\ - page_owner["pid"], page_owner["tgid"], page_owner["comm"],\ - page_owner["ts_nsec"], page_owner["free_ts_nsec"])) - gdb.write("PFN: %d, Flags: 0x%x\n" % (pfn, page['flags'])) - stackdepot.stack_depot_print(page_owner["handle"]) - pfn += (1 << page_owner["order"]) - continue - except: - gdb.write("\n") - pfn += 1 + page_owner = self.get_page_owner(page_ext) + gdb.write("Page allocated via order %d, gfp_mask: 0x%x, pid: %d, tgid: %d (%s), ts %u ns, free_ts %u ns\n" %\ + (page_owner["order"], page_owner["gfp_mask"],\ + page_owner["pid"], page_owner["tgid"], page_owner["comm"].string(),\ + page_owner["ts_nsec"], page_owner["free_ts_nsec"])) + gdb.write("PFN: %d, Flags: 0x%x\n" % (pfn, page['flags'])) + stackdepot.stack_depot_print(page_owner["handle"]) + pfn += (1 << page_owner["order"]) DumpPageOwner() diff --git a/scripts/gdb/linux/slab.py b/scripts/gdb/linux/slab.py index f012ba38c7d9..0e2d93867fe2 100644 --- a/scripts/gdb/linux/slab.py +++ b/scripts/gdb/linux/slab.py @@ -228,8 +228,7 @@ def slabtrace(alloc, cache_name): nr_cpu = gdb.parse_and_eval('__num_online_cpus')['counter'] if nr_cpu > 1: gdb.write(" cpus=") - for i in loc['cpus']: - gdb.write("%d," % i) + gdb.write(','.join(str(cpu) for cpu in loc['cpus'])) gdb.write("\n") if constants.LX_CONFIG_STACKDEPOT: if loc['handle']: diff --git a/scripts/gdb/linux/stackdepot.py b/scripts/gdb/linux/stackdepot.py index 047d329a6a12..0281d9de4b7c 100644 --- a/scripts/gdb/linux/stackdepot.py +++ b/scripts/gdb/linux/stackdepot.py @@ -25,10 +25,10 @@ def stack_depot_fetch(handle): handle_parts_t = gdb.lookup_type("union handle_parts") parts = handle.cast(handle_parts_t) offset = parts['offset'] << DEPOT_STACK_ALIGN - pool_index_cached = gdb.parse_and_eval('pool_index') + pools_num = gdb.parse_and_eval('pools_num') - if parts['pool_index'] > pool_index_cached: - gdb.write("pool index %d out of bounds (%d) for stack id 0x%08x\n" % (parts['pool_index'], pool_index_cached, handle)) + if parts['pool_index'] > pools_num: + gdb.write("pool index %d out of bounds (%d) for stack id 0x%08x\n" % (parts['pool_index'], pools_num, handle)) return gdb.Value(0), 0 stack_pools = gdb.parse_and_eval('stack_pools') diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 5179edd1b627..c8047f4441e6 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -111,12 +111,11 @@ lx-symbols command.""" return "{textaddr} {sections}".format( textaddr=textaddr, sections="".join(args)) - def load_module_symbols(self, module, module_file=None): + def load_module_symbols(self, module): module_name = module['name'].string() module_addr = str(module['mem'][constants.LX_MOD_TEXT]['base']).split()[0] - if not module_file: - module_file = self._get_module_file(module_name) + module_file = self._get_module_file(module_name) if not module_file and not self.module_files_updated: self._update_module_files() module_file = self._get_module_file(module_name) @@ -139,19 +138,6 @@ lx-symbols command.""" else: gdb.write("no module object found for '{0}'\n".format(module_name)) - def load_ko_symbols(self, mod_path): - self.loaded_modules = [] - module_list = modules.module_list() - - for module in module_list: - module_name = module['name'].string() - module_pattern = ".*/{0}\.ko(?:.debug)?$".format( - module_name.replace("_", r"[_\-]")) - if re.match(module_pattern, mod_path) and os.path.exists(mod_path): - self.load_module_symbols(module, mod_path) - return - raise gdb.GdbError("%s is not a valid .ko\n" % mod_path) - def load_all_symbols(self): gdb.write("loading vmlinux\n") @@ -190,11 +176,6 @@ lx-symbols command.""" self.module_files = [] self.module_files_updated = False - argv = gdb.string_to_argv(arg) - if len(argv) == 1: - self.load_ko_symbols(argv[0]) - return - self.load_all_symbols() if hasattr(gdb, 'Breakpoint'): diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index 17ec19e9b5bf..6793d6e86e77 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py @@ -13,7 +13,7 @@ import gdb -from linux import utils +from linux import utils, lists task_type = utils.CachedType("struct task_struct") @@ -22,19 +22,15 @@ task_type = utils.CachedType("struct task_struct") def task_lists(): task_ptr_type = task_type.get_type().pointer() init_task = gdb.parse_and_eval("init_task").address - t = g = init_task + t = init_task while True: - while True: - yield t + thread_head = t['signal']['thread_head'] + for thread in lists.list_for_each_entry(thread_head, task_ptr_type, 'thread_node'): + yield thread - t = utils.container_of(t['thread_group']['next'], - task_ptr_type, "thread_group") - if t == g: - break - - t = g = utils.container_of(g['tasks']['next'], - task_ptr_type, "tasks") + t = utils.container_of(t['tasks']['next'], + task_ptr_type, "tasks") if t == init_task: return @@ -86,21 +82,12 @@ LxPs() thread_info_type = utils.CachedType("struct thread_info") -ia64_task_size = None - def get_thread_info(task): thread_info_ptr_type = thread_info_type.get_type().pointer() - if utils.is_target_arch("ia64"): - global ia64_task_size - if ia64_task_size is None: - ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)") - thread_info_addr = task.address + ia64_task_size - thread_info = thread_info_addr.cast(thread_info_ptr_type) - else: - if task.type.fields()[0].type == thread_info_type.get_type(): - return task['thread_info'] - thread_info = task['stack'].cast(thread_info_ptr_type) + if task.type.fields()[0].type == thread_info_type.get_type(): + return task['thread_info'] + thread_info = task['stack'].cast(thread_info_ptr_type) return thread_info.dereference() diff --git a/scripts/gdb/linux/vmalloc.py b/scripts/gdb/linux/vmalloc.py index 48e4a4fae7bb..d3c8a0274d1e 100644 --- a/scripts/gdb/linux/vmalloc.py +++ b/scripts/gdb/linux/vmalloc.py @@ -10,8 +10,9 @@ import gdb import re from linux import lists, utils, stackdepot, constants, mm -vmap_area_type = utils.CachedType('struct vmap_area') -vmap_area_ptr_type = vmap_area_type.get_type().pointer() +if constants.LX_CONFIG_MMU: + vmap_area_type = utils.CachedType('struct vmap_area') + vmap_area_ptr_type = vmap_area_type.get_type().pointer() def is_vmalloc_addr(x): pg_ops = mm.page_ops().ops @@ -25,6 +26,9 @@ class LxVmallocInfo(gdb.Command): super(LxVmallocInfo, self).__init__("lx-vmallocinfo", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): + if not constants.LX_CONFIG_MMU: + raise gdb.GdbError("Requires MMU support") + vmap_area_list = gdb.parse_and_eval('vmap_area_list') for vmap_area in lists.list_for_each_entry(vmap_area_list, vmap_area_ptr_type, "list"): if not vmap_area['vm']: |