drgn (pronounced "dragon") is a debugger with an emphasis on programmability. drgn exposes the types and variables in a program for easy, expressive scripting in Python. For example, you can debug the Linux kernel:
>>> from drgn.helpers.linux import list_for_each_entry >>> for mod in list_for_each_entry('struct module', ... prog['modules'].address_of_(), ... 'list'): ... if mod.refcnt.counter > 10: ... print(mod.name) ... (char )"snd" (char )"evdev" (char )"i915"
Although other debuggers like GDB have scripting support, drgn aims to make scripting as natural as possible so that debugging feels like coding. This makes it well-suited for introspecting the complex, inter-connected state in large programs. It is also designed as a library that can be used to build debugging and introspection tools; see the official tools.
drgn was developed for debugging the Linux kernel (as an alternative to the crash utility), but it can also debug userspace programs written in C. C++ support is in progress.
Documentation can be found at drgn.readthedocs.io.
$ sudo pacman -S --needed gcc libelf make pkgconf python python-pip python-setuptools
$ sudo apt-get install gcc liblzma-dev libelf-dev libdw-dev make pkgconf python3 python3-dev python3-pip python3-setuptools zlib1g-dev
Note that Debian Stretch, Ubuntu Trusty, and Ubuntu Xenial (and older) ship Python versions which are too old. Python 3.6 or newer must be installed manually.
$ sudo dnf install elfutils-devel gcc make pkgconf python3 python3-devel python3-pip python3-setuptools
- libkdumpfile if you want support for kdump-compressed kernel core dumps
$ sudo pip3 install drgn
See the installation documentation for more options.
drgn debugs the running kernel by default; run
sudo drgn. To debug a
running program, run
sudo drgn -p $PID. To debug a core dump (either a
kernel vmcore or a userspace core dump), run
drgn -c $PATH. The program
must have debugging symbols available.
Then, you can access variables in the program with
prog['name'] and access
structure members with
$ sudo drgn >>> prog['init_task'].comm (char )"swapper/0"
You can use various predefined helpers:
>>> len(list(bpf_prog_for_each(prog))) 11 >>> task = find_task(prog, 115) >>> cmdline(task) [b'findmnt', b'-p']
You can get stack traces with
prog.stack_trace() and access parameters or
local variables with
>>> trace = prog.stack_trace(task) >>> trace #5 at 0xffffffff8a5a32d0 (do_sys_poll+0x400/0x578) in do_poll at ./fs/select.c:961:8 (inlined) >>> poll_list = trace['list'] >>> file = fget(task, poll_list.entries.fd) >>> d_path(file.f_path.address_of_()) b'/proc/115/mountinfo'
See the user guide for more details and features.
Copyright (c) Facebook, Inc. and its affiliates.
drgn is licensed under the GPLv3 or later.