Skip to content

drgn 0.0.31

Choose a tag to compare

@osandov osandov released this 16 Apr 19:02
· 505 commits to main since this release

This is the largest release of drgn since 0.0.1 (the first release). It adds brand new command line options and APIs for controlling how debugging information is found, improved debuginfod integration, stack tracing through unknown kernel modules with ORC, a few new helpers, bug fixes, and more.

New features:

  • The way drgn finds debugging symbols was completely rewritten in order to add command line options and APIs providing more control over this process. Special thanks to Stephen Brennan for feedback and improvements.
    • New classes were added for representing modules (i.e., binaries, shared libraries, kernel modules, etc.): drgn.MainModule, drgn.SharedLibraryModule, drgn.VdsoModule, drgn.RelocatableModule, and drgn.ExtraModule.
    • New methods were added to drgn.Program for querying what modules are loaded in a program and manually overriding what drgn determines: modules(), loaded_modules(), create_loaded_modules(), main_module(), shared_library_module(), vdso_module(), relocatable_module(), linux_kernel_loadable_module(), extra_module(), and module().
    • Options for controlling how debugging information is found were added as drgn.Program.debug_info_options.
    • New command line options were added to the drgn CLI for controlling how debugging information is found: --try-symbols-by, --no-symbols-by, --debug-directory, --no-default-debug-directories, --kernel-directory, and --no-default-kernel-directories.
    • New methods for adding custom debugging information finders were added to drgn.Program: register_debug_info_finder(), registered_debug_info_finders(), set_enabled_debug_info_finders(), enabled_debug_info_finders(), and find_standard_debug_info().
    • drgn now logs the process of finding modules and debugging symbols. To see these logs, use the command line option --log-level debug.
  • depmod(8) metadata is no longer required for finding debugging symbols for Linux kernel modules (but it is still used as an optimization when available).
  • A progress bar is now shown when downloading debugging symbols from debuginfod.
  • Kernel debugging information can now be downloaded from debuginfod (although due to debuginfod server limitations, this is currently only enabled for Fedora Linux kernels).
  • A plugin system was added. Plugins can hook into program initialization to register debugging information finders, object/type/symbol finders, and more.
  • Support was added for indexing DWARF imported units and gnu_debugaltlink files, which are used by some Linux distributions.
  • Snippets of code can now be run directly from the command line using the new -e option. Contributed by Stephen Brennan.
  • drgn.StackFrame.name will now fall back to the symbol name or program counter when full debugging information is not available for a function. The old behavior (fall back to None) is now available as drgn.StackFrame.function_name. Contributed by Stephen Brennan.
  • Support was added for kernel stack unwinding using ORC even when debugging symbol files are not available. Contributed by Stephen Brennan.
  • Stack traces from a struct pt_regs are now always allowed even in live userspace processes. Contributed by Stephen Brennan.
  • NULL function pointer calls can now be unwound in stack traces on AArch64.
  • When stack_trace(0) fails for the Linux kernel, it now suggests using stack_trace(idle_task(cpu)).
  • drgn.cli.default_globals() was added. It returns the dictionary of globals that drgn would use in an interactive session. Contributed by Stephen Brennan.
  • Absent objects now record the reason that they are absent: drgn.Object.absence_reason_.
  • The drgn.helpers.linux.kthread module was added. It provides two helpers for working with kernel threads, to_kthread() and kthread_data().
  • The kernfs_parent() and kernfs_root() helpers for examining the kernfs hierarchy were added to the drgn.helpers.linux.kernfs module.
  • Linux 6.14 and 6.15 are now supported.
    • Kernel module support was updated for Linux 6.14.
    • The drgn.helpers.linux.fs.path_lookup() and drgn.helpers.linux.kernfs helpers were updated for Linux 6.15.
  • drgn.helpers.linux.sched.task_cpu() and stack traces were fixed for CentOS/RHEL 9 kernels. Contributed by Georges Aureau.

Incompatible changes:

  • Debugging symbol files provided by the user are now matched more strictly (by build ID). This fixes a common source of confusion but unfortunately isn't backwards compatible.
    • If a file provided with the command line option -s/--symbols or passed to drgn.Program.load_debug_info() doesn't match a loaded module, a warning will be printed and the file will be ignored.
    • If you really want to use a file for a specific module, then find the module (e.g., with drgn.Program.modules() or drgn.Program.module()) and add the file with drgn.Module.try_file(path, force=True).
    • If you really want to load debugging symbols from a file without associating it with a loaded module, use the --extra-symbols command line option or drgn.Program.extra_module(...).try_file(path).

Bug fixes:

  • The -s option now finds the correct addresses for userspace programs.
  • The drgn CLI was fixed to handle its standard input not being a terminal.
  • Downloads from debuginfod can now be interrupted with Ctrl-C.
  • drgn.helpers.experimental.kmodify.call_function() now type checks arguments passed as Python values correctly (more strictly).
  • drgn.helpers.experimental.kmodify.call_function() now works around a Clang sign extension bug.
  • The rbp register is now recovered correctly when unwinding through an interrupt handler on a kernel using the ORC unwinder.
  • The addresses of member functions in C++ with both out-of-line and inline instances are now properly reported.
  • DWARF expressions with a DW_OP_addr operation in the middle of the expression are now handled correctly with (K)ASLR.
  • The DW_CFA_GNU_args_size DWARF expression operation is now handled (ignored).
  • Core dumps with a non-null-terminated process name (such as those generated by gcore(1)) are now handled instead of failing. Contributed by Stephen Brennan.
  • drgn.FaultErrors raised from Python memory readers are now properly propagated instead of turning into a hard error. Contributed by Stephen Brennan.
  • A use-after-free or double-free when parsing invalid DWARF information was fixed.
  • del prog.language now raises an exception instead of segfaulting.

Other improvements:

  • Optimized out variables are now printed as <optimized out> instead of <absent>.
  • libkdumpfile support was updated for incompatible changes in libkdumpfile 0.5.5. Contributed by Petr Tesarik.

Documentation:

  • An interactive tutorial (also available as a video) was added.
  • The documentation for getting debugging symbols was updated and expanded.
    • This page also now uses the shell builtin command -v instead of which since the latter is not always available. Contributed by Septatrix.
  • A man page was added.

contrib directory:

  • stack_trace_call_fault.py now supports AArch64.
  • negdentdelete.py was fixed for Linux < 6.8. Contributed by Septatrix.

Packaging changes:

  • drgn now depends on libdebuginfod. This can be configured as a soft runtime dependency (--with-debuginfod --enable-dlopen-debuginfod, which is the default and the recommended setting for distributions), a hard runtime dependency (--with-debuginfod --disable-dlopen-debuginfod), or disabled entirely (--without-debuginfod).
  • setup.py no longer builds libdrgn.so. It can still be built with --enable-libdrgn, but that's not recommended for distributions.