def execute(self, args: argparse.Namespace) -> None: if args.c: raise CommandError("support for the -c argument is unimplemented") trans = CrashAddressTranslation() # Silly mypy bug means the base class needs come first if not trans.is_non_auto: pgt = LinuxPGT(trans.context, trans.system) else: pgt = LinuxNonAutoPGT(trans.context, trans.system) for addr in args.args: try: addr = int(addr, 16) except ValueError: raise CommandLineError(f"{addr} is not a hex address") from None fulladdr = addrxlat.FullAddress(addrxlat.KVADDR, addr) print('{:16} {:16}'.format('VIRTUAL', 'PHYSICAL')) try: fulladdr.conv(addrxlat.KPHYSADDR, trans.context, trans.system) phys = '{:x}'.format(fulladdr.addr) except addrxlat.BaseException: phys = '---' print('{:<16x} {:<16}\n'.format(addr, phys)) if pgt.begin(addr): while pgt.next(): print('{:>4}: {} => {}'.format(pgt.table, pgt.address(), pgt.value())) if pgt.step.remain: pgt.ptr = pgt.step.base print('PAGE: {}'.format(pgt.address())) else: print('NO TRANSLATION') print()
def print_vmstats(self) -> None: try: vm_stat = get_symbol_value("vm_stat") except MissingSymbolError: raise CommandError("Support for new-style vmstat is unimplemented.") from None print(" VM_STAT:") #TODO put this... where? nr_items = VmStat.nr_stat_items stats = [0] * nr_items for item in range(0, nr_items): # TODO abstract atomic? stats[item] = int(vm_stat[item]["counter"]) diffs = [0] * nr_items for zone in for_each_populated_zone(): zone.add_vmstat_diffs(diffs) self.__print_vmstat(stats, diffs) print() print(" VM_EVENT_STATES:") vm_events = VmStat.get_events() names = VmStat.get_event_names() just = max(map(len, names)) for name, val in zip(names, vm_events): print("%s: %d" % (name.rjust(just), val))
def command_ls(self, args: argparse.Namespace) -> None: kn = find_kn(args.kn) if not kn['flags'] & KERNFS_DIR: raise CommandError("{} is not a kernfs directory".format(args.kn)) print("{:^6} {:^6} {:^32} {:^16}".format("flags", "mode", "name", "kernfs_node")) self._ls_dir(kn, args.R, args)
def execute(self, args: argparse.Namespace) -> None: # Unimplemented if args.p or args.c or args.t or args.a or args.g or args.r: raise CommandError( "Support for the -p, -c, -t, -a, -g, and -r options is unimplemented." ) if not self.task_states: self.setup_task_states() regex = None if args.args: regex = re.compile(fnmatch.translate(args.args[0])) taskformat = TaskFormat(args, regex) count = 0 header = taskformat.format_header() for thread in sorted(gdb.selected_inferior().threads(), key=taskformat.sort): task = thread.info if task: if not taskformat.should_print_task(task): continue if header: print(header) header = "" task.update_mem_usage() state = self.task_state_string(task) line = taskformat.format_one_task(task, state) print(line) count += 1 if count == 0: if regex: print(f"No matches for {args.args[0]}.") else: raise CommandError("Unfiltered output has no matches. BUG?")
def dump_buftargs(cls, args: argparse.Namespace) -> None: try: sb = get_super_block(args.addr) except gdb.NotAvailableError as e: raise CommandError(str(e)) from e mp = xfs_mount(sb) ddev = mp['m_ddev_targp'] ldev = mp['m_logdev_targp'] print("Data device queue @ {:x}:".format(int(ddev))) cls.dump_buftarg(ddev) if int(ddev) != int(ldev): print("Log device queue:") cls.dump_buftarg(ldev)
def show_xfs(self, args: argparse.Namespace) -> None: try: sb = get_super_block(args.addr) except gdb.NotAvailableError as e: raise CommandError(str(e)) from e mp = xfs_mount(sb) print("Device: {}".format(sb['s_id'].string())) print("UUID: {}".format(xfs_mount_uuid(mp))) print("VFS superblock flags: {}".format(super_flags(sb))) print("Flags: {}".format(xfs_mount_flags(mp))) print("Version: {}".format(xfs_mount_version(mp))) if list_empty(mp['m_ail']['xa_ail']): print("AIL is empty") else: print("AIL has items queued")
def execute(self, args: argparse.Namespace) -> None: try: self.handle_structured_log(args) return except LogTypeException: pass try: self.handle_logbuf(args) return except LogTypeException: pass except LogInvalidOption as lio: raise CommandError(str(lio)) from lio print("Can't find valid log") print(args)
def execute(self, args: argparse.Namespace) -> None: if not args.args: print("Available commands:") for cmd in sorted(self._commands): summary = None doc = self._commands[cmd].__doc__ if doc: summary = doc.strip() if not summary: summary = "no help text provided" print("{:<15} - {}".format(cmd, summary)) else: for cmd in args.args: try: text = self._commands[cmd].format_help().strip() except KeyError: raise CommandError("No such command `{}'".format(cmd)) if text is None: print("No help text available.") else: print(text)
def show_task(self, pid: int) -> None: try: ltask = get_task(pid) print("{:^12} {:^16} {:^32} {:^16} {:^20}".format( "hierarchy_id", "cgroup_root", "controllers/name", "cgroup", "path" )) for h in sorted(for_each_hierarchy(), key=lambda h: int(h['hierarchy_id'])): controllers = subsys_mask_to_names(h['subsys_mask']) if h['name'].string(): controllers.append("name={}".format(h['name'].string())) cgroup = cgroup_from_root(ltask.task_struct, h) print("{:>12} {:016x} {:<32} {:016x} {:<20}".format( int(h['hierarchy_id']), int(h.address), ','.join(controllers), int(cgroup.address), path_from_node(cgroup['kn'].dereference()) )) except KeyError: raise CommandError("No such task with pid {}".format(pid)) from None
def dump_ail(self, args: argparse.Namespace) -> None: try: sb = get_super_block(args.addr) except gdb.NotAvailableError as e: raise CommandError(str(e)) from e mp = xfs_mount(sb) ail = mp['m_ail'] itemno = 0 print("AIL @ {:x}".format(int(ail))) print("target={} last_pushed_lsn={} log_flush=".format( int(ail['xa_target']), int(ail['xa_last_pushed_lsn'])), end='') # This was added in Linux v3.2 (670ce93fef93b) if struct_has_member(ail, 'xa_log_flush'): print("{}".format(int(ail['xa_log_flush']))) else: print("[N/A]") for bitem in xfs_for_each_ail_log_item(mp): li_type = int(bitem['li_type']) lsn = int(bitem['li_lsn']) item = xfs_log_item_typed(bitem) print("{}: item={:x} lsn={} {} ".format(itemno, int(bitem.address), lsn, XFS_LI_TYPES[li_type][7:]), end='') if li_type == XFS_LI_BUF: buf = item['bli_buf'] flags = decode_flags(item['bli_flags'], XFS_BLI_FLAGS) print(" buf@{:x} bli_flags={}".format(int(buf), flags)) print(" {}".format(xfs_format_xfsbuf(buf))) elif li_type == XFS_LI_INODE: ili_flags = int(item['ili_lock_flags']) xfs_inode = item['ili_inode'] print("inode@{:x} i_ino={} ili_lock_flags={:x} ".format( int(xfs_inode['i_vnode'].address), int(xfs_inode['i_ino']), ili_flags)) elif li_type == XFS_LI_EFI: efi = item['efi_format'] print("efi@{:x} size={}, nextents={}, id={:x}".format( int(item.address), int(efi['efi_size']), int(efi['efi_nextents']), int(efi['efi_id']))) elif li_type == XFS_LI_EFI: efd = item['efd_format'] print("efd@{:x} size={}, nextents={}, id={:x}".format( int(item.address), int(efd['efd_size']), int(efd['efd_nextents']), int(efd['efd_id']))) elif li_type == XFS_LI_DQUOT: dquot = item['qli_dquot'] flags = decode_flags(dquot['dq_flags'], XFS_DQ_FLAGS) print("dquot@{:x} flags={}".format(int(dquot), flags)) elif li_type == XFS_LI_QUOTAOFF: qoff = item['qql_format'] print("qoff@{:x} type={} size={} flags={}".format( int(qoff), int(qoff['qf_type']), int(qoff['qf_size']), int(qoff['qf_flags']))) else: print("item@{:x}".format(int(item.address))) itemno += 1
def execute(self, args: argparse.Namespace) -> None: if args.z: self.print_zones() return if args.V: self.print_vmstats() return cache = None if args.slabcheck: if args.address is None: print("Checking all kmem caches...") for cache in kmem_cache_get_all(): print(cache.name) cache.check_all() print("Checking done.") return cache_name = args.address cache = self._find_kmem_cache(cache_name) if cache is not None: print(f"Checking kmem cache {cache_name}") cache.check_all() print("Checking done.") return if args.slablist: if args.address is None: print("Listing all kmem caches...") for cache in kmem_cache_get_all(): cache.list_all(args.slablist) return cache_name = args.address cache = self._find_kmem_cache(cache_name) if cache is not None: cache.list_all(args.slablist) return if not args.address: raise CommandLineError("no address specified") addr = safe_int(args.address) if addr is None: raise CommandLineError("address must be numeric") slab = None page = safe_page_from_page_addr(addr) if page is not None: #TODO improve print(f"0x{addr:x} belongs to a struct page 0x{page.address:x} " f"pfn {page.pfn}") if page.compound_head().is_slab(): slab = slab_from_page(page) name = slab.kmem_cache.name if args.slabcheck or args.slablist: print(f"page belongs to cache {name} slab " f"{slab.short_header()}") if args.slablist: print("") print(f"Slab details: {slab.long_header()}") slab.print_objects() return else: slab = slab_from_obj_addr(addr) if not slab: raise CommandError(f"Kmem cache not found: '{args.address}' is not " f"a valid name of a kmem cache or an address " f"known to the kmem subsystem.") if slab is None: return (valid, obj, reason) = slab.contains_obj(addr) name = slab.kmem_cache.name if valid: (is_used, details) = slab.obj_in_use(obj) offset = addr - obj offset_str = "" if offset == 0 else f" offset 0x{offset:x} ({offset})" details_str = "" if details is None else f" (in {details})" objsize = slab.kmem_cache.object_size state = "ALLOCATED" if is_used else "FREE" print(f"{state}{details_str} object 0x{obj:x}{offset_str} " f"size 0x{objsize:x} ({objsize}) from cache {name} " f"slab {slab.short_header()}") else: obj_str = "" if obj is not None: obj_str = f" object 0x{obj:x}" reason_str = "" if reason is not None: reason_str = f" ({reason})" print(f"INVALID address on slab {slab.gdb_obj.address} " f"from cache {name}{obj_str}{reason_str}") if args.slablist: print("") print(f"Slab details: {slab.long_header()}") slab.print_objects()
def execute(self, args: argparse.Namespace) -> None: if args.z: self.print_zones() return if args.V: self.print_vmstats() return cache = None if args.slabcheck: if args.address is None: print("Checking all kmem caches...") for cache in kmem_cache_get_all(): print(cache.name) cache.check_all() print("Checking done.") return cache_name = args.address cache = self._find_kmem_cache(cache_name) if cache is not None: print(f"Checking kmem cache {cache_name}") cache.check_all() print("Checking done.") return if args.slablist: if args.address is None: print("Listing all kmem caches...") for cache in kmem_cache_get_all(): cache.list_all(args.slablist) return cache_name = args.address cache = self._find_kmem_cache(cache_name) if cache is not None: cache.list_all(args.slablist) return if not args.address: raise CommandLineError("no address specified") addr = safe_int(args.address) if addr is None: raise CommandLineError("address must be numeric") slab = None page = safe_page_from_page_addr(addr) if page is not None: #TODO improve print(f"0x{addr:x} belongs to a struct page 0x{page.address:x} " f"pfn {page.pfn}") page.dump() if page.compound_head().is_slab(): slab = slab_from_page(page) name = slab.kmem_cache.name if args.slabcheck or args.slablist: print(f"page belongs to cache {name} slab " f"{slab.short_header()}") if args.slablist: print("") print(f"Slab details: {slab.long_header()}") slab.print_objects() return else: slab = slab_from_obj_addr(addr) if not slab: raise CommandError( f"Kmem cache not found: '{args.address}' is not " f"a valid name of a kmem cache or an address " f"known to the kmem subsystem.") if slab is None: return print(slab_describe_addr(addr)) if args.slablist: print("") print(f"Slab details: {slab.long_header()}") slab.print_objects()
def execute(self, args: argparse.Namespace) -> None: if args.z: self.print_zones() return if args.V: self.print_vmstats() return if slub_kernel: # not supported for now print("-s and address options not supported on non-SLAB systems") return if args.slabname: if args.slabname is True: print("Checking all kmem caches...") for cache in kmem_cache_get_all(): print(cache.name) cache.check_all() else: cache_name = args.slabname print(f"Checking kmem cache {cache_name}") try: cache = kmem_cache_from_name(cache_name) except KmemCacheNotFound: raise CommandError(f"Cache {cache_name} not found.") cache.check_all() print("Checking done.") return if not args.address: raise CommandLineError("no address specified") try: addr = int(args.address[0], 0) except ValueError: raise CommandLineError("address must be numeric") slab = slab_from_obj_addr(addr) if not slab: raise CommandError("Address not found in any kmem cache.") obj = slab.contains_obj(addr) name = slab.kmem_cache.name if obj[0]: print("ALLOCATED object %x from slab %s" % (obj[1], name)) else: if obj[1] == 0: print("Address on slab %s but not within valid object slot" % name) elif not obj[2]: print("FREE object %x from slab %s" % (obj[1], name)) elif obj[2] is not None: ac = obj[2] ac_type = ac['ac_type'] # pylint: disable=unsubscriptable-object nid_tgt = int(ac['nid_tgt']) # pylint: disable=unsubscriptable-object if ac_type == "percpu": ac_desc = "cpu %d cache" % nid_tgt elif ac_type == "shared": ac_desc = "shared cache on node %d" % nid_tgt elif ac_type == "alien": nid_src = int(ac['nid_src']) # pylint: disable=unsubscriptable-object ac_desc = "alien cache of node %d for node %d" % \ (nid_src, nid_tgt) else: raise CommandError( f"unexpected array cache type {str(ac)}") print("FREE object %x from slab %s (in %s)" % (obj[1], name, ac_desc)) else: raise RuntimeError("odd return value from contains_obj")