예제 #1
0
    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()
예제 #2
0
    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))
예제 #3
0
    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)
예제 #4
0
파일: ps.py 프로젝트: zhongwuq/crash-python
    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?")
예제 #5
0
    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)
예제 #6
0
    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")
예제 #7
0
    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)
예제 #8
0
 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)
예제 #9
0
    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
예제 #10
0
    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
예제 #11
0
    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()
예제 #12
0
    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()
예제 #13
0
    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")