Advanced Usage

The User Guide covers basic usage of drgn, but drgn also supports more advanced use cases which are covered here.

Loading Debugging Symbols

drgn will automatically load debugging information based on the debugged program (e.g., from loaded kernel modules or loaded shared libraries). drgn.Program.load_debug_info() can be used to load additional debugging information:

>>> prog.load_debug_info(['./libfoo.so', '/usr/lib/libbar.so'])

Library

In addition to the CLI, drgn is also available as a library. drgn.program_from_core_dump(), drgn.program_from_kernel(), and drgn.program_from_pid() correspond to the -c, -k, and -p command line options, respectively; they return a drgn.Program that can be used just like the one initialized by the CLI:

>>> import drgn
>>> prog = drgn.program_from_kernel()

C Library

The core functionality of drgn is implemented in C and is available as a C library, libdrgn. See drgn.h.

Full documentation can be generated by running doxygen in the libdrgn directory of the source code. Note that the API and ABI are not yet stable.

Custom Programs

The main components of a drgn.Program are the program memory, types, and symbols. The CLI and equivalent library interfaces automatically determine these. However, it is also possible to create a “blank” Program and plug in the main components.

drgn.Program.add_memory_segment() defines a range of memory and how to read that memory. The following example uses a Btrfs filesystem image as the program “memory”:

import drgn
import os
import sys


def btrfs_debugger(dev):
    file = open(dev, 'rb')
    size = file.seek(0, 2)

    def read_file(address, count, physical, offset):
        file.seek(offset)
        return file.read(count)

    platform = drgn.Platform(drgn.Architecture.UNKNOWN,
                             drgn.PlatformFlags.IS_LITTLE_ENDIAN)
    prog = drgn.Program(platform)
    prog.add_memory_segment(0, size, read_file)
    prog.load_debug_info([f'/lib/modules/{os.uname().release}/kernel/fs/btrfs/btrfs.ko'])
    return prog


prog = btrfs_debugger(sys.argv[1] if len(sys.argv) >= 2 else '/dev/sda')
print(drgn.Object(prog, 'struct btrfs_super_block', address=65536))

drgn.Program.add_type_finder() and drgn.Program.add_object_finder() are the equivalent methods for plugging in types and objects.

Environment Variables

Some of drgn’s behavior can be modified through environment variables:

DRGN_MAX_DEBUG_INFO_ERRORS

The maximum number of individual errors to report in a drgn.MissingDebugInfoError. Any additional errors are truncated. The default is 5; -1 is unlimited.

DRGN_PREFER_ORC_UNWINDER

Whether to prefer using ORC over DWARF for stack unwinding (0 or 1). The default is 0. Note that drgn will always fall back to ORC for functions lacking DWARF call frame information and vice versa. This environment variable is mainly intended for testing and may be ignored in the future.

DRGN_USE_LIBDWFL_REPORT

Whether drgn should use libdwfl to find debugging information for core dumps instead of its own implementation (0 or 1). The default is 0. This environment variable is mainly intended as an escape hatch in case of bugs in drgn’s implementation and will be ignored in the future.

DRGN_USE_LIBKDUMPFILE_FOR_ELF

Whether drgn should use libkdumpfile for ELF vmcores (0 or 1). The default is 0. This functionality will be removed in the future.

DRGN_USE_SYS_MODULE

Whether drgn should use /sys/module to find information about loaded kernel modules for the running kernel instead of getting them from the core dump (0 or 1). The default is 1. This environment variable is mainly intended for testing and may be ignored in the future.