Пример #1
0
def archive_kernel_dump(path: str) -> None:
    """
    Packages the dump together with its vmlinux and modules in a
    gzipped archive in the working directory.
    """
    # pylint: disable=too-many-locals
    #
    # We import drgn and libkdumpfile specifically here and
    # not in the top-level to allow users that don't have
    # it installed to still be able to use savedump for
    # userland core files.
    #
    import kdumpfile  # pylint: disable=import-outside-toplevel

    kdump_info = kdumpfile.kdumpfile(path)
    dumpname = os.path.basename(path)
    nodename = kdump_info.attr['linux.uts.nodename']
    osrelease = kdump_info.attr['linux.uts.release']

    vmlinux_path = f"/usr/lib/debug/boot/vmlinux-{osrelease}"
    if not os.path.exists(vmlinux_path):
        sys.exit(f"error: cannot find vmlinux at: {vmlinux_path}")
    print(f"vmlinux found: {vmlinux_path}")

    mod_paths = get_module_paths(osrelease, path)

    archive_dir = f"{nodename}.archive-{dumpname}"
    pathlib.Path(archive_dir).mkdir(parents=True, exist_ok=True)
    shutil.copy(path, archive_dir)
    shutil.copy(vmlinux_path, archive_dir)

    for mod_path in mod_paths:
        archive_mod_path = f"{archive_dir}{mod_path}"
        os.makedirs(os.path.dirname(archive_mod_path), exist_ok=True)
        shutil.copy(mod_path, archive_mod_path)

    #
    # Generate run-sdb.sh.
    #
    run_sdb_path = f"{archive_dir}/run-sdb.sh"
    with open(run_sdb_path, "w") as sdb_script:
        print(RUN_CRASH_SDB_CONTENTS.format(os.path.basename(vmlinux_path),
                                            dumpname),
              file=sdb_script)
    os.chmod(run_sdb_path, 0o755)

    #
    # Generate run-pycrash.sh.
    #
    run_pycrash_path = f"{archive_dir}/run-pycrash.sh"
    with open(run_pycrash_path, "w") as pycrash_script:
        print(RUN_PYCRASH_CONTENTS.format(os.path.basename(vmlinux_path),
                                          dumpname),
              file=pycrash_script)
    os.chmod(run_pycrash_path, 0o755)

    msg = compress_archive(archive_dir)
    shutil.rmtree(archive_dir)
    if msg:
        sys.exit(f"error: {msg}")
Пример #2
0
 def __init__(self, fil):
     if isinstance(fil, str):
         fil = file(fil)
         self.fil = fil
         print "kdump (%s)" % fil
         self.kdump = kdumpfile(fil)
         self.kdump.symbol_func = symbol_func
         self.kdump.vtop_init()
         super(Target, self).__init__()
         gdb.execute('set print thread-events 0')
         self.setup_tasks()
Пример #3
0
    def __init__(self, fil):
        if isinstance(fil, str):
            fil = file(fil)
            self.fil = fil
            print "kdump (%s)" % fil
            self.kdump = kdumpfile(fil)
            self.kdump.symbol_func = symbol_func
            self.kdump.vtop_init()
            super(Target, self).__init__()
	    gdb.execute('set print thread-events 0')
	    self.setup_tasks()
Пример #4
0
    def attach_vmcore(self, vmcore_filename, debug=False):
        self.vmcore_filename = vmcore_filename
        self.vmcore = kdumpfile(vmcore_filename)
        self.target = crash.kdump.target.Target(self.vmcore, debug)

        self.base_offset = 0
        try:
            KERNELOFFSET = "linux.vmcoreinfo.lines.KERNELOFFSET"
            attr = self.vmcore.attr.get(KERNELOFFSET, "0")
            self.base_offset = long(attr, base=16)
        except Exception as e:
            print(e)
Пример #5
0
    def open(self, args: str, from_tty: bool) -> None:
        argv = shlex.split(args)
        if len(argv) < 2:
            raise gdb.GdbError("kdumpfile target requires kernel image and vmcore")

        vmlinux = argv[0]
        filename = argv[1]

        try:
            self.kdump = kdumpfile(file=filename)
        except Exception as e:
            raise gdb.GdbError("Failed to open `{}': {}"
                               .format(filename, str(e)))

        # pylint: disable=unsupported-assignment-operation
        self.kdump.attr['addrxlat.ostype'] = 'linux'

        KERNELOFFSET = "linux.vmcoreinfo.lines.KERNELOFFSET"
        try:
            attr = self.kdump.attr.get(KERNELOFFSET, "0") # pylint: disable=no-member
            self.base_offset = int(attr, base=16)
        except (TypeError, ValueError):
            pass

        # Load the kernel at the relocated address
        # Unfortunately, the percpu section has an offset of 0 and
        # ends up getting placed at the offset base.  This is easy
        # enough to handle in the percpu code.
        result = gdb.execute("symbol-file {} -o {:#x}"
                             .format(vmlinux, self.base_offset),
                             to_string=True)

        if self.debug:
            print(result)

        # We don't have an exec-file so we need to set the architecture
        # explicitly.
        arch = gdb.objfiles()[0].architecture.name()
        result = gdb.execute("set architecture {}".format(arch), to_string=True)
        if self.debug:
            print(result)
Пример #6
0
    def __init__(self, filename, debug=False):
        self.filename = filename
        self.arch = None
        self.debug = debug
        try:
            self.kdump = kdumpfile(filename)
        except OSErrorException as e:
            raise RuntimeError(str(e))
        ctx = self.kdump.get_addrxlat_ctx()
        ctx.cb_sym = SymbolCallback(ctx)
        self.kdump.attr['addrxlat.ostype'] = 'linux'

        gdb.execute('set print thread-events 0')

        self.setup_arch()

        # So far we've read from the kernel image, now that we've setup
        # the architecture, we're ready to plumb into the target
        # infrastructure.
        super(Target, self).__init__()

        # Now we're reading from the dump file
        self.setup_tasks()
Пример #7
0
    def open(self, filename: str, from_tty: bool) -> None:

        objfiles = gdb.objfiles()
        if not objfiles:
            raise gdb.GdbError(
                "kdumpfile target requires kernel to be already loaded for symbol resolution"
            )
        try:
            self.kdump = kdumpfile(file=filename)
        except Exception as e:
            raise gdb.GdbError("Failed to open `{}': {}".format(
                filename, str(e)))

        # pylint: disable=unsupported-assignment-operation
        self.kdump.attr['addrxlat.ostype'] = 'linux'

        KERNELOFFSET = "linux.vmcoreinfo.lines.KERNELOFFSET"
        try:
            attr = self.kdump.attr.get(KERNELOFFSET, "0")  # pylint: disable=no-member
            self.base_offset = int(attr, base=16)
        except (TypeError, ValueError):
            pass

        vmlinux = gdb.objfiles()[0].filename

        # Load the kernel at the relocated address
        # Unfortunately, the percpu section has an offset of 0 and
        # ends up getting placed at the offset base.  This is easy
        # enough to handle in the percpu code.
        result = gdb.execute("add-symbol-file {} -o {:#x}".format(
            vmlinux, self.base_offset),
                             to_string=True)
        if self.debug:
            print(result)

        # Clear out the old symbol cache
        gdb.execute("file {}".format(vmlinux))
Пример #8
0
    def __init__(self, kernel_exec=None, vmcore=None, kernelpath=None,
                 searchpath=None, debug=False):
        print("crash-python initializing...")
        if searchpath is None:
            searchpath = []

        autoload_submodules('crash.cache')
        autoload_submodules('crash.subsystem')
        autoload_submodules('crash.commands')

        self.searchpath = searchpath

        if not kernel_exec:
            return

        try:
            kdump = kdumpfile(vmcore)
        except OSErrorException as e:
            raise RuntimeError(str(e))

        kaslr_off = long(
            kdump.attr.get("linux.vmcoreinfo.lines.KERNELOFFSET", "0"),
            base=16)

        error = gdb.execute("exec-file {}".format(kernel_exec), to_string=True)
        tinfo = gdb.execute("info target", to_string=True)
        args=""
        textaddr = 0
        in_exec = False
        for line in tinfo.splitlines():
            if line.startswith((" ", "\t")):
                if not in_exec:
                    continue
                try:
                    (addrs, sect) = line.strip().split(" is ")
                except ValueError:
                    continue
                (start, end) = addrs.split(" - ")
                sect = sect.split(' ')[0]
                startaddr = long(start, base=0) + kaslr_off
                if sect == ".text":
                    textaddr = startaddr
                    args += " 0x{:x}".format(startaddr)
                elif startaddr >= textaddr:
                    args += " -s {} 0x{:x}".format(sect, startaddr)
            elif line.startswith("Local exec file:"):
                in_exec = True
            elif not line.startswith("warning: "):
                in_exec = False

        error = gdb.execute("add-symbol-file {}{}".format(kernel_exec, args), to_string=True)

        try:
            list_type = gdb.lookup_type('struct list_head')
        except gdb.error as e:
            load_debuginfo(searchpath, gdb.objfiles()[0], kernelpath)
            try:
                list_type = gdb.lookup_type('struct list_head')
            except gdb.error as e:
                raise RuntimeError("Couldn't locate debuginfo for {}".format(kernel_exec))

        self.target = crash.kdump.target.Target(kdump, debug)
        load_modules(self.searchpath)
Пример #9
0
            addr.addr += step.idx[step.remain - 1] * step.elemsz
        else:
            addr = step.base
        remark = note.note(addr, ' ({})')
        print('{:>4}: {:16x}{}'.format(tbl, addr.addr, remark), end='')

        try:
            step.step()
            if step.remain and step.raw is not None:
                print(' => {:x}'.format(step.raw))
        except addrxlat.NotPresentError:
            print(' => {:x}  NOT PRESENT'.format(step.raw))
            return
    print()

if len(argv) != 3:
    print('Usage: {} <dumpfile> <virtual address>'.format(argv[0]))
    exit(1)

kdf = kdumpfile.kdumpfile(argv[1])
kdf.addrxlat_convert = addrxlat.convert
kdf.attr['addrxlat.ostype'] = 'linux'
sys = kdf.get_addrxlat_sys()
ctx = kdf.get_addrxlat_ctx()

addr = int(argv[2], base=0)
try:
    vtop(addr, ctx, sys)
except addrxlat.BaseException as e:
    print('Translation failed: {}'.format(e.message))
Пример #10
0
        else:
            addr = step.base
        remark = note.note(addr, ' ({})')
        print('{:>4}: {:16x}{}'.format(tbl, addr.addr, remark), end='')

        try:
            step.step()
            if step.remain and step.raw is not None:
                print(' => {:x}'.format(step.raw))
        except addrxlat.NotPresentError:
            print(' => {:x}  NOT PRESENT'.format(step.raw))
            return
    print()


if len(argv) != 3:
    print('Usage: {} <dumpfile> <virtual address>'.format(argv[0]))
    exit(1)

kdf = kdumpfile.kdumpfile(argv[1])
kdf.addrxlat_convert = addrxlat.convert
kdf.attr['addrxlat.ostype'] = 'linux'
sys = kdf.get_addrxlat_sys()
ctx = kdf.get_addrxlat_ctx()

addr = int(argv[2], base=0)
try:
    vtop(addr, ctx, sys)
except addrxlat.BaseException as e:
    print('Translation failed: {}'.format(e.message))
Пример #11
0
    print_meth(system, 'MACHPHYS_KPHYS')
    print_meth(system, 'KPHYS_MACHPHYS')

    print_map(system, 'HW')
    print()
    print_map(system, 'KV_PHYS')
    print()
    print_map(system, 'KPHYS_DIRECT')
    print()
    print_map(system, 'MACHPHYS_KPHYS')
    print()
    print_map(system, 'KPHYS_MACHPHYS')

if __name__ == '__main__':
    if len(sys.argv) < 2 or len(sys.argv) > 3:
        print('Usage: {} <dumpfile> [<ostype>]'.format(sys.argv[0]),
              file=sys.stderr)
        exit(1)

    k = kdumpfile.kdumpfile(sys.argv[1])

    meth_names = {}
    for name, val in addrxlat.__dict__.items():
        if name.startswith('SYS_METH_') and name != 'SYS_METH_NUM':
            meth_names[val] = name[9:]

    if len(sys.argv) > 2:
        k.attr['addrxlat.ostype'] = sys.argv[2]

    dump_addrxlat(k)
Пример #12
0
    print_meth(system, 'KPHYS_MACHPHYS')

    print_map(system, 'HW')
    print()
    print_map(system, 'KV_PHYS')
    print()
    print_map(system, 'KPHYS_DIRECT')
    print()
    print_map(system, 'MACHPHYS_KPHYS')
    print()
    print_map(system, 'KPHYS_MACHPHYS')


if __name__ == '__main__':
    if len(sys.argv) < 2 or len(sys.argv) > 3:
        print('Usage: {} <dumpfile> [<ostype>]'.format(sys.argv[0]),
              file=sys.stderr)
        exit(1)

    k = kdumpfile.kdumpfile(sys.argv[1])

    meth_names = {}
    for name, val in addrxlat.__dict__.items():
        if name.startswith('SYS_METH_') and name != 'SYS_METH_NUM':
            meth_names[val] = name[9:]

    if len(sys.argv) > 2:
        k.attr['addrxlat.ostype'] = sys.argv[2]

    dump_addrxlat(k)