Programmable debugger
Go to file
Peilin Ye e9915886f6 helpers: Add netdev_get_by_index()
Add a helper to find the corresponding "struct net_device *" object
given an interface index number.  As an example:

    >>> netdev = netdev_get_by_index(prog["init_net"], 1)
    >>> netdev.name.string_().decode()
    'lo'

Or pass a "Program" as the first argument, and let the helper find in
its initial network namespace (i.e. "init_net"):

    >>> netdev = netdev_get_by_index(prog, 3)
    >>> netdev.name.string_().decode()
    'enp0s3'

Also add a test for this new helper to tests/helpers/linux/test_net.py.

For now, a user may combine this new helper with socket.if_nametoindex()
to look up by interface name:

    >>> netdev = find_netdev_by_index(prog, socket.if_nametoindex("dummy0"))
    >>> netdev.name.string_().decode()
    'dummy0'

However, as mentioned by Cong, one should keep in mind that
socket.if_nametoindex() is based on system's current name-to-index
mapping, which may be different from that of e.g. a kdump.

Thus, as suggested by Omar, a better way to do name lookups would be
simply linear-searching the name hash table, which is slower, but less
erorr-prone.

Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
2021-08-11 13:36:32 -07:00
.github/workflows CI: install correct version of libomp 2021-06-01 17:52:00 -07:00
docs docs: improve stack trace documentation in user guide 2021-08-02 16:20:33 -07:00
drgn helpers: Add netdev_get_by_index() 2021-08-11 13:36:32 -07:00
examples/linux examples: add missing shebangs 2021-04-20 11:20:06 -07:00
libdrgn libdrgn: python: add Object.to_bytes_() 2021-07-26 17:12:34 -07:00
scripts libdrgn: dwarf_index: improve file path hashing for deduplication 2021-06-25 18:03:01 -07:00
tests helpers: Add netdev_get_by_index() 2021-08-11 13:36:32 -07:00
tools Use GPL-3.0-or-later license identifier instead of GPL-3.0+ 2021-04-03 01:10:35 -07:00
vmtest vmtest: add CONFIG_NUMA=y 2021-07-29 17:04:52 -07:00
_drgn.pyi docs: update repr(drgn.Type) and type constructors in documentation 2021-08-02 15:59:43 -07:00
.editorconfig editorconfig: Update styles for pyi and c files 2020-02-27 09:37:26 -08:00
.git-blame-ignore-revs Add .git-blame-ignore-revs 2020-01-14 12:03:26 -08:00
.gitignore Generate version.py instead of using pkg_resources 2020-10-20 02:40:16 -07:00
.readthedocs.yml Add type hint stubs and generate documentation from them 2020-02-25 13:39:06 -08:00
CONTRIBUTING.rst CONTRIBUTING: add guidelines for good commits 2021-01-12 16:56:54 -08:00
COPYING License under GPL-3.0 or later 2018-04-15 15:03:33 -07:00
MANIFEST.in add COPYING to sdist 2021-04-20 11:17:51 -07:00
pyproject.toml Format imports with isort 2020-08-20 16:55:07 -07:00
README.rst docs: improve quick start documentation 2021-08-02 16:20:30 -07:00
setup.py setup.py: add 5.14 to vmtest kernels 2021-07-29 17:52:58 -07:00
util.py Move vmtest assets to GitHub releases 2021-05-05 00:28:56 -07:00

drgn
====

.. image:: https://img.shields.io/pypi/v/drgn
    :target: https://pypi.org/project/drgn/
    :alt: PyPI

.. image:: https://github.com/osandov/drgn/workflows/CI/badge.svg
    :target: https://github.com/osandov/drgn/actions
    :alt: CI Status

.. image:: https://readthedocs.org/projects/drgn/badge/?version=latest
    :target: https://drgn.readthedocs.io/en/latest/?badge=latest
    :alt: Documentation Status

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/psf/black

.. start-introduction

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:

.. code-block:: pycon

    >>> 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 [56])"snd"
    (char [56])"evdev"
    (char [56])"i915"

Although other debuggers like `GDB <https://www.gnu.org/software/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 <https://github.com/osandov/drgn/tree/main/tools>`_.

drgn was developed for debugging the Linux kernel (as an alternative to the
`crash <http://people.redhat.com/anderson/>`_ utility), but it can also debug
userspace programs written in C. C++ support is in progress.

.. end-introduction

Documentation can be found at `drgn.readthedocs.io
<https://drgn.readthedocs.io>`_.

Installation
------------

.. start-install-dependencies

Install dependencies:

Arch Linux:

.. code-block:: console

    $ sudo pacman -S --needed gcc libelf make pkgconf python python-pip python-setuptools

Debian/Ubuntu:

.. code-block:: console

    $ 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.

Fedora:

.. code-block:: console

    $ sudo dnf install elfutils-devel gcc make pkgconf python3 python3-devel python3-pip python3-setuptools

Optionally, install:

* `libkdumpfile <https://github.com/ptesarik/libkdumpfile>`_ if you want
  support for kdump-compressed kernel core dumps

.. end-install-dependencies

Then, run:

.. code-block:: console

    $ sudo pip3 install drgn

See the `installation documentation
<https://drgn.readthedocs.io/en/latest/installation.html>`_ for more options.

Quick Start
-----------

.. start-quick-start

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 ``.``:

.. code-block:: pycon

    $ sudo drgn
    >>> prog['init_task'].comm
    (char [16])"swapper/0"

You can use various predefined helpers:

.. code-block:: pycon

    >>> 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 ``stack_trace['name']``:

.. code-block:: pycon

    >>> trace = prog.stack_trace(task)
    >>> trace[5]
    #5 at 0xffffffff8a5a32d0 (do_sys_poll+0x400/0x578) in do_poll at ./fs/select.c:961:8 (inlined)
    >>> poll_list = trace[5]['list']
    >>> file = fget(task, poll_list.entries[0].fd)
    >>> d_path(file.f_path.address_of_())
    b'/proc/115/mountinfo'

.. end-quick-start

See the `user guide <https://drgn.readthedocs.io/en/latest/user_guide.html>`_
for more details and features.

License
-------

.. start-license

Copyright (c) Facebook, Inc. and its affiliates.

drgn is licensed under the `GPLv3
<https://www.gnu.org/licenses/gpl-3.0.en.html>`_ or later.

.. end-license