Helpers

The drgn.helpers package contains subpackages which provide helpers for working with particular types of programs. Currently, there are only helpers for the Linux kernel. In the future, there may be helpers for, e.g., glibc and libstdc++.

Generic Helpers

The top-level drgn.helpers module provides generic helpers that may be useful for scripts or for implementing other helpers.

class drgn.helpers.ValidationError

Bases: Exception

Error raised by a validator when an inconsistent or invalid state is detected.

drgn.helpers.escape_ascii_character(c, escape_single_quote=False, escape_double_quote=False, escape_backslash=False)

Format an ASCII byte value as a character, possibly escaping it. Non-printable characters are always escaped. Non-printable characters other than \0, \a, \b, \t, \n, \v, \f, and \r are escaped in hexadecimal format (e.g., \x7f). By default, printable characters are never escaped.

Parameters:
  • c (int) – The character to escape.

  • escape_single_quote (bool) – Whether to escape single quotes to \'.

  • escape_double_quote (bool) – Whether to escape double quotes to \".

  • escape_backslash (bool) – Whether to escape backslashes to \\.

Return type:

str

drgn.helpers.escape_ascii_string(buffer, escape_single_quote=False, escape_double_quote=False, escape_backslash=False)

Escape an iterable of ASCII byte values (e.g., bytes or bytearray). See escape_ascii_character().

Parameters:

buffer (Iterable[int]) – The byte array.

Return type:

str

drgn.helpers.enum_type_to_class(type, name, exclude=(), prefix='')

Get an enum.IntEnum class from an enumerated drgn.Type.

Parameters:
  • type (drgn.Type) – The enumerated type to convert.

  • name (str) – The name of the IntEnum type to create.

  • exclude (Container[str]) – Container (e.g., list or set) of enumerator names to exclude from the created IntEnum.

  • prefix (str) – Prefix to strip from the beginning of enumerator names.

Return type:

Type[enum.IntEnum]

drgn.helpers.decode_flags(value, flags, bit_numbers=True)

Get a human-readable representation of a bitmask of flags.

By default, flags are specified by their bit number:

>>> decode_flags(2, [("BOLD", 0), ("ITALIC", 1), ("UNDERLINE", 2)])
'ITALIC'

They can also be specified by their value:

>>> decode_flags(2, [("BOLD", 1), ("ITALIC", 2), ("UNDERLINE", 4)],
...              bit_numbers=False)
'ITALIC'

Multiple flags are combined with “|”:

>>> decode_flags(5, [("BOLD", 0), ("ITALIC", 1), ("UNDERLINE", 2)])
'BOLD|UNDERLINE'

If there are multiple names for the same bit, they are all included:

>>> decode_flags(2, [("SMALL", 0), ("BIG", 1), ("LARGE", 1)])
'BIG|LARGE'

If there are any unknown bits, their raw value is included:

>>> decode_flags(27, [("BOLD", 0), ("ITALIC", 1), ("UNDERLINE", 2)])
'BOLD|ITALIC|0x18'

Zero is returned verbatim:

>>> decode_flags(0, [("BOLD", 0), ("ITALIC", 1), ("UNDERLINE", 2)])
'0'
Parameters:
  • value (drgn.IntegerLike) – Bitmask to decode.

  • flags (Iterable[Tuple[str, int]]) – List of flag names and their bit numbers or values.

  • bit_numbers (bool) – Whether flags specifies the bit numbers (where 0 is the least significant bit) or values of the flags.

Return type:

str

drgn.helpers.decode_enum_type_flags(value, type, bit_numbers=True)

Get a human-readable representation of a bitmask of flags where the flags are specified by an enumerated drgn.Type.

This supports enums where the values are bit numbers:

>>> print(bits_enum)
enum style_bits {
        BOLD = 0,
        ITALIC = 1,
        UNDERLINE = 2,
}
>>> decode_enum_type_flags(5, bits_enum)
'BOLD|UNDERLINE'

Or the values of the flags:

>>> print(flags_enum)
enum style_flags {
        BOLD = 1,
        ITALIC = 2,
        UNDERLINE = 4,
}
>>> decode_enum_type_flags(5, flags_enum, bit_numbers=False)
'BOLD|UNDERLINE'

See decode_flags().

Parameters:
  • value (drgn.IntegerLike) – Bitmask to decode.

  • type (drgn.Type) – Enumerated type with bit numbers for enumerators.

  • bit_numbers (bool) – Whether the enumerator values specify the bit numbers or values of the flags.

Return type:

str

Linux Kernel

The drgn.helpers.linux package contains several modules for working with data structures and subsystems in the Linux kernel. The helpers are available from the individual modules in which they are defined and from this top-level package. E.g., the following are both valid:

>>> from drgn.helpers.linux.list import list_for_each_entry
>>> from drgn.helpers.linux import list_for_each_entry

Iterator macros (for_each_foo) are a common idiom in the Linux kernel. The equivalent drgn helpers are implemented as Python generators. For example, the following code in C:

list_for_each(pos, head)
        do_something_with(pos);

Translates to the following code in Python:

for pos in list_for_each(head):
    do_something_with(pos)

Bit Operations

The drgn.helpers.linux.bitops module provides helpers for common bit operations in the Linux kernel.

drgn.helpers.linux.bitops.for_each_set_bit(bitmap, size)

Iterate over all set (one) bits in a bitmap.

Parameters:
Return type:

Iterator[int]

drgn.helpers.linux.bitops.for_each_clear_bit(bitmap, size)

Iterate over all clear (zero) bits in a bitmap.

Parameters:
Return type:

Iterator[int]

drgn.helpers.linux.bitops.test_bit(nr, bitmap)

Return whether a bit in a bitmap is set.

Parameters:
Return type:

bool

Block Layer

The drgn.helpers.linux.block module provides helpers for working with the Linux block layer, including disks (struct gendisk) and partitions.

Since Linux v5.11, partitions are represented by struct block_device. Before that, they were represented by struct hd_struct.

drgn.helpers.linux.block.disk_devt(disk)

Get a disk’s device number.

Parameters:

disk (drgn.Object) – struct gendisk *

Returns:

dev_t

Return type:

drgn.Object

drgn.helpers.linux.block.disk_name(disk)

Get the name of a disk (e.g., sda).

Parameters:

disk (drgn.Object) – struct gendisk *

Return type:

bytes

drgn.helpers.linux.block.for_each_disk(prog)

Iterate over all disks in the system.

Returns:

Iterator of struct gendisk * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.block.print_disks(prog)

Print all of the disks in the system.

Return type:

None

drgn.helpers.linux.block.part_devt(part)

Get a partition’s device number.

Parameters:

part (drgn.Object) – struct block_device * or struct hd_struct * depending on the kernel version.

Returns:

dev_t

Return type:

drgn.Object

drgn.helpers.linux.block.part_name(part)

Get the name of a partition (e.g., sda1).

Parameters:

part (drgn.Object) – struct block_device * or struct hd_struct * depending on the kernel version.

Return type:

bytes

drgn.helpers.linux.block.for_each_partition(prog)

Iterate over all partitions in the system.

Returns:

Iterator of struct block_device * or struct hd_struct * objects depending on the kernel version.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.block.print_partitions(prog)

Print all of the partitions in the system.

Return type:

None

Boot

The drgn.helpers.linux.boot module provides helpers for inspecting the Linux kernel boot configuration.

drgn.helpers.linux.boot.kaslr_offset(prog)

Get the kernel address space layout randomization offset (zero if it is disabled).

Return type:

int

drgn.helpers.linux.boot.pgtable_l5_enabled(prog)

Return whether 5-level paging is enabled.

Return type:

bool

BPF

The drgn.helpers.linux.bpf module provides helpers for working with BPF interface in include/linux/bpf.h, include/linux/bpf-cgroup.h, etc.

drgn.helpers.linux.bpf.bpf_btf_for_each(prog)

Iterate over all BTF objects.

This is only supported since Linux v4.18.

Returns:

Iterator of struct btf * objects.

Return type:

Iterator[drgn.Object]

Iterate over all BPF links.

This is only supported since Linux v5.8.

Returns:

Iterator of struct bpf_link * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.bpf.bpf_map_for_each(prog)

Iterate over all BPF maps.

This is only supported since Linux v4.13.

Returns:

Iterator of struct bpf_map * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.bpf.bpf_prog_for_each(prog)

Iterate over all BPF programs.

This is only supported since Linux v4.13.

Returns:

Iterator of struct bpf_prog * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.bpf.cgroup_bpf_prog_for_each(cgrp, bpf_attach_type)

Iterate over all cgroup BPF programs of the given attach type attached to the given cgroup.

Parameters:
Returns:

Iterator of struct bpf_prog * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.bpf.cgroup_bpf_prog_for_each_effective(cgrp, bpf_attach_type)

Iterate over all effective cgroup BPF programs of the given attach type for the given cgroup.

Parameters:
Returns:

Iterator of struct bpf_prog * objects.

Return type:

Iterator[drgn.Object]

Cgroup

The drgn.helpers.linux.cgroup module provides helpers for working with the cgroup interface in include/linux/cgroup.h. Only cgroup v2 is supported.

drgn.helpers.linux.cgroup.sock_cgroup_ptr(skcd)

Get the cgroup for a socket from the given struct sock_cgroup_data * (usually from struct sock::sk_cgrp_data).

Parameters:

skcd (drgn.Object) – struct sock_cgroup_data *

Returns:

struct cgroup *

Return type:

drgn.Object

drgn.helpers.linux.cgroup.cgroup_parent(cgrp)

Return the parent cgroup of the given cgroup if it exists, NULL otherwise.

Parameters:

cgrp (drgn.Object) – struct cgroup *

Returns:

struct cgroup *

Return type:

drgn.Object

drgn.helpers.linux.cgroup.cgroup_name(cgrp)

Get the name of the given cgroup.

Parameters:

cgrp (drgn.Object) – struct cgroup *

Return type:

bytes

drgn.helpers.linux.cgroup.cgroup_path(cgrp)

Get the full path of the given cgroup.

Parameters:

cgrp (drgn.Object) – struct cgroup *

Return type:

bytes

drgn.helpers.linux.cgroup.cgroup_get_from_path(prog, path)

Look up a cgroup from its default hierarchy path .

Parameters:

path (drgn.Path) – Path name.

Return type:

drgn.Object

drgn.helpers.linux.cgroup.css_next_child(pos, parent)

Get the next child (or NULL if there is none) of the given parent starting from the given position (NULL to initiate traversal).

Parameters:
Returns:

struct cgroup_subsys_state *

Return type:

drgn.Object

drgn.helpers.linux.cgroup.css_next_descendant_pre(pos, root)

Get the next pre-order descendant (or NULL if there is none) of the given css root starting from the given position (NULL to initiate traversal).

Parameters:
Returns:

struct cgroup_subsys_state *

Return type:

drgn.Object

drgn.helpers.linux.cgroup.css_for_each_child(css)

Iterate through children of the given css.

Parameters:

css (drgn.Object) – struct cgroup_subsys_state *

Returns:

Iterator of struct cgroup_subsys_state * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.cgroup.css_for_each_descendant_pre(css)

Iterate through the given css’s descendants in pre-order.

Parameters:

css (drgn.Object) – struct cgroup_subsys_state *

Returns:

Iterator of struct cgroup_subsys_state * objects.

Return type:

Iterator[drgn.Object]

CPU Masks

The drgn.helpers.linux.cpumask module provides helpers for working with CPU masks from include/linux/cpumask.h.

drgn.helpers.linux.cpumask.for_each_cpu(mask)

Iterate over all of the CPUs in the given mask.

Parameters:

mask (drgn.Object) – struct cpumask

Return type:

Iterator[int]

drgn.helpers.linux.cpumask.for_each_online_cpu(prog)

Iterate over all online CPUs.

Return type:

Iterator[int]

drgn.helpers.linux.cpumask.for_each_possible_cpu(prog)

Iterate over all possible CPUs.

Return type:

Iterator[int]

drgn.helpers.linux.cpumask.for_each_present_cpu(prog)

Iterate over all present CPUs.

Return type:

Iterator[int]

Devices

The drgn.helpers.linux.device module provides helpers for working with Linux devices, including the kernel encoding of dev_t.

drgn.helpers.linux.device.MAJOR(dev)

Return the major ID of a kernel dev_t.

Parameters:

dev (drgn.IntegerLike) – dev_t object or :class:int.

Return type:

int

drgn.helpers.linux.device.MINOR(dev)

Return the minor ID of a kernel dev_t.

Parameters:

dev (drgn.IntegerLike) – dev_t object or :class:int.

Return type:

int

drgn.helpers.linux.device.MKDEV(major, minor)

Return a kernel dev_t from the major and minor IDs.

Parameters:
Return type:

int

Virtual Filesystem Layer

The drgn.helpers.linux.fs module provides helpers for working with the Linux virtual filesystem (VFS) layer, including mounts, dentries, and inodes.

drgn.helpers.linux.fs.path_lookup(prog_or_root, path, allow_negative=False)

Look up the given path name.

Parameters:
  • prog_or_rootstruct path * object to use as root directory, or Program to use the initial root filesystem.

  • path – Path to lookup.

  • allow_negative – Whether to allow returning a negative dentry (i.e., a dentry for a non-existent path).

Returns:

struct path

Raises:

Exception – if the dentry is negative and allow_negative is False, or if the path is not present in the dcache. The latter does not necessarily mean that the path does not exist; it may be uncached. On a live system, you can make the kernel cache the path by accessing it (e.g., with open() or os.stat()):

>>> path_lookup(prog, '/usr/include/stdlib.h')
...
Exception: could not find '/usr/include/stdlib.h' in dcache
>>> open('/usr/include/stdlib.h').close()
>>> path_lookup(prog, '/usr/include/stdlib.h')
(struct path){
        .mnt = (struct vfsmount *)0xffff8b70413cdca0,
        .dentry = (struct dentry *)0xffff8b702ac2c480,
}
Return type:

drgn.Object

drgn.helpers.linux.fs.d_path(path)

Return the full path of a dentry given a struct path.

Parameters:

path (drgn.Object) – struct path or struct path *

Return type:

bytes

drgn.helpers.linux.fs.d_path(vfsmnt, dentry)

Return the full path of a dentry given a mount and dentry.

Parameters:
Return type:

bytes

drgn.helpers.linux.fs.dentry_path(dentry)

Return the path of a dentry from the root of its filesystem.

Parameters:

dentry (drgn.Object) – struct dentry *

Return type:

bytes

drgn.helpers.linux.fs.inode_path(inode)

Return any path of an inode from the root of its filesystem.

Parameters:

inode (drgn.Object) – struct inode *

Returns:

Path, or None if the inode has no aliases.

Return type:

Optional[bytes]

drgn.helpers.linux.fs.inode_paths(inode)

Return an iterator over all of the paths of an inode from the root of its filesystem.

Parameters:

inode (drgn.Object) – struct inode *

Return type:

Iterator[bytes]

drgn.helpers.linux.fs.mount_src(mnt)

Get the source device name for a mount.

Parameters:

mnt (drgn.Object) – struct mount *

Return type:

bytes

drgn.helpers.linux.fs.mount_dst(mnt)

Get the path of a mount point.

Parameters:

mnt (drgn.Object) – struct mount *

Return type:

bytes

drgn.helpers.linux.fs.mount_fstype(mnt)

Get the filesystem type of a mount.

Parameters:

mnt (drgn.Object) – struct mount *

Return type:

bytes

drgn.helpers.linux.fs.for_each_mount(prog_or_ns, src=None, dst=None, fstype=None)

Iterate over all of the mounts in a given namespace.

Parameters:
Returns:

Iterator of struct mount * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.fs.print_mounts(prog_or_ns, src=None, dst=None, fstype=None)

Print the mount table of a given namespace. The arguments are the same as for_each_mount(). The output format is similar to /proc/mounts but prints the value of each struct mount *.

Return type:

None

drgn.helpers.linux.fs.fget(task, fd)

Return the kernel file descriptor of the fd of a given task.

Parameters:
Returns:

struct file *

Return type:

drgn.Object

drgn.helpers.linux.fs.for_each_file(task)

Iterate over all of the files open in a given task.

Parameters:

task (drgn.Object) – struct task_struct *

Returns:

Iterator of (fd, struct file *) tuples.

Return type:

Iterator[Tuple[int, drgn.Object]]

drgn.helpers.linux.fs.print_files(task)

Print the open files of a given task.

Parameters:

task (drgn.Object) – struct task_struct *

Return type:

None

IDR

The drgn.helpers.linux.idr module provides helpers for working with the IDR data structure in include/linux/idr.h. An IDR provides a mapping from an ID to a pointer. This currently only supports Linux v4.11+; before this, IDRs were not based on radix trees.

drgn.helpers.linux.idr.idr_find(idr, id)

Look up the entry with the given ID in an IDR.

Parameters:
Returns:

void * found entry, or NULL if not found.

Return type:

drgn.Object

drgn.helpers.linux.idr.idr_for_each(idr)

Iterate over all of the entries in an IDR.

Parameters:

idr (drgn.Object) – struct idr *

Returns:

Iterator of (index, void *) tuples.

Return type:

Iterator[Tuple[int, drgn.Object]]

Kconfig

The drgn.helpers.linux.kconfig module provides helpers for reading the Linux kernel build configuration.

drgn.helpers.linux.kconfig.get_kconfig(prog)

Get the kernel build configuration as a mapping from the option name to the value.

>>> get_kconfig(prog)['CONFIG_SMP']
'y'
>>> get_kconfig(prog)['CONFIG_HZ']
'300'

This is only supported if the kernel was compiled with CONFIG_IKCONFIG. Note that most Linux distributions do not enable this option.

Return type:

Mapping[str, str]

Kernfs

The drgn.helpers.linux.kernfs module provides helpers for working with the kernfs pseudo filesystem interface in include/linux/kernfs.h.

drgn.helpers.linux.kernfs.kernfs_name(kn)

Get the name of the given kernfs node.

Parameters:

kn (drgn.Object) – struct kernfs_node *

Return type:

bytes

drgn.helpers.linux.kernfs.kernfs_path(kn)

Get full path of the given kernfs node.

Parameters:

kn (drgn.Object) – struct kernfs_node *

Return type:

bytes

drgn.helpers.linux.kernfs.kernfs_walk(parent, path)

Find the kernfs node with the given path from the given parent kernfs node.

Parameters:
Returns:

struct kernfs_node * (NULL if not found)

Return type:

drgn.Object

Linked Lists

The drgn.helpers.linux.list module provides helpers for working with the doubly-linked list implementations (struct list_head and struct hlist_head) in include/linux/list.h.

drgn.helpers.linux.list.list_empty(head)

Return whether a list is empty.

Parameters:

head (drgn.Object) – struct list_head *

Return type:

bool

drgn.helpers.linux.list.list_is_singular(head)

Return whether a list has only one element.

Parameters:

head (drgn.Object) – struct list_head *

Return type:

bool

drgn.helpers.linux.list.list_first_entry(head, type, member)

Return the first entry in a list.

The list is assumed to be non-empty.

See also list_first_entry_or_null().

Parameters:
Returns:

type *

Return type:

drgn.Object

drgn.helpers.linux.list.list_first_entry_or_null(head, type, member)

Return the first entry in a list or NULL if the list is empty.

See also list_first_entry().

Parameters:
Returns:

type *

Return type:

drgn.Object

drgn.helpers.linux.list.list_last_entry(head, type, member)

Return the last entry in a list.

The list is assumed to be non-empty.

Parameters:
Returns:

type *

Return type:

drgn.Object

drgn.helpers.linux.list.list_next_entry(pos, member)

Return the next entry in a list.

Parameters:
  • pos (drgn.Object) – type*

  • member (str) – Name of list node member in entry type.

Returns:

type *

Return type:

drgn.Object

drgn.helpers.linux.list.list_prev_entry(pos, member)

Return the previous entry in a list.

Parameters:
  • pos (drgn.Object) – type*

  • member (str) – Name of list node member in entry type.

Returns:

type *

Return type:

drgn.Object

drgn.helpers.linux.list.list_for_each(head)

Iterate over all of the nodes in a list.

Parameters:

head (drgn.Object) – struct list_head *

Returns:

Iterator of struct list_head * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.list.list_for_each_reverse(head)

Iterate over all of the nodes in a list in reverse order.

Parameters:

head (drgn.Object) – struct list_head *

Returns:

Iterator of struct list_head * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.list.list_for_each_entry(type, head, member)

Iterate over all of the entries in a list.

Parameters:
Returns:

Iterator of type * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.list.list_for_each_entry_reverse(type, head, member)

Iterate over all of the entries in a list in reverse order.

Parameters:
Returns:

Iterator of type * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.list.validate_list(head)

Validate that the next and prev pointers in a list are consistent.

Parameters:

head (drgn.Object) – struct list_head *

Raises:

ValidationError – if the list is invalid

Return type:

None

drgn.helpers.linux.list.validate_list_for_each(head)

Like list_for_each(), but validates the list like validate_list() while iterating.

Parameters:

head (drgn.Object) – struct list_head *

Raises:

ValidationError – if the list is invalid

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.list.validate_list_for_each_entry(type, head, member)

Like list_for_each_entry(), but validates the list like validate_list() while iterating.

Parameters:
Raises:

ValidationError – if the list is invalid

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.list.hlist_empty(head)

Return whether a hash list is empty.

Parameters:

head (drgn.Object) – struct hlist_head *

Return type:

bool

drgn.helpers.linux.list.hlist_for_each(head)

Iterate over all of the nodes in a hash list.

Parameters:

head (drgn.Object) – struct hlist_head *

Returns:

Iterator of struct hlist_node * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.list.hlist_for_each_entry(type, head, member)

Iterate over all of the entries in a hash list.

Parameters:
Returns:

Iterator of type * objects.

Return type:

Iterator[drgn.Object]

Nulls Lists

The drgn.helpers.linux.list_nulls module provides helpers for working with the special version of lists (struct hlist_nulls_head and struct hlist_nulls_node) in include/linux/list_nulls.h where the end of list is not a NULL pointer, but a “nulls” marker.

drgn.helpers.linux.list_nulls.is_a_nulls(pos)

Return whether a a pointer is a nulls marker.

Parameters:

pos (drgn.Object) – struct hlist_nulls_node *

Return type:

bool

drgn.helpers.linux.list_nulls.hlist_nulls_empty(head)

Return whether a nulls hash list is empty.

Parameters:

head (drgn.Object) – struct hlist_nulls_head *

Return type:

bool

drgn.helpers.linux.list_nulls.hlist_nulls_for_each_entry(type, head, member)

Iterate over all the entries in a nulls hash list.

Parameters:
Returns:

Iterator of type * objects.

Return type:

Iterator[drgn.Object]

Memory Management

The drgn.helpers.linux.mm module provides helpers for working with the Linux memory management (MM) subsystem. Only AArch64 and x86-64 are currently supported.

drgn.helpers.linux.mm.for_each_page(prog)

Iterate over all pages in the system.

Returns:

Iterator of struct page * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.mm.decode_page_flags(page)

Get a human-readable representation of the flags set on a page.

>>> decode_page_flags(page)
'PG_uptodate|PG_dirty|PG_lru|PG_reclaim|PG_swapbacked|PG_readahead|PG_savepinned|PG_isolated|PG_reported'
Parameters:

page (drgn.Object) – struct page *

Return type:

str

drgn.helpers.linux.mm.PFN_PHYS(pfn)

Get the physical address of a page frame number (PFN) given as an Object.

Parameters:

pfn (drgn.Object) – unsigned long

Returns:

phys_addr_t

Return type:

drgn.Object

drgn.helpers.linux.mm.PFN_PHYS(prog, pfn)

Get the physical address of a page frame number (PFN) given as a Program and an integer.

Parameters:

pfn (drgn.IntegerLike) – Page frame number.

Returns:

phys_addr_t

Return type:

drgn.Object

drgn.helpers.linux.mm.PHYS_PFN(addr)

Get the page frame number (PFN) of a physical address given as an Object.

Parameters:

addr (drgn.Object) – phys_addr_t

Returns:

unsigned long

Return type:

drgn.Object

drgn.helpers.linux.mm.PHYS_PFN(prog, addr)

Get the page frame number (PFN) of a physical address given as a Program and an integer.

Parameters:

addr (int) – Physical address.

Returns:

unsigned long

Return type:

drgn.Object

drgn.helpers.linux.mm.page_to_pfn(page)

Get the page frame number (PFN) of a page.

Parameters:

page (drgn.Object) – struct page *

Returns:

unsigned long

Return type:

drgn.Object

drgn.helpers.linux.mm.page_to_phys(page)

Get the physical address of a page.

Parameters:

page (drgn.Object) – struct page *

Returns:

phys_addr_t

Return type:

drgn.Object

drgn.helpers.linux.mm.page_to_virt(page)

Get the directly mapped virtual address of a page.

Parameters:

page (drgn.Object) – struct page *

Returns:

void *

Return type:

drgn.Object

drgn.helpers.linux.mm.pfn_to_page(pfn)

Get the page with a page frame number (PFN) given as an Object.

Parameters:

pfn (drgn.Object) – unsigned long

Returns:

struct page *

Return type:

drgn.Object

drgn.helpers.linux.mm.pfn_to_page(prog, pfn)

Get the page with a page frame number (PFN) given as a Program and an integer.

Parameters:

pfn (drgn.IntegerLike) – Page frame number.

Returns:

struct page *

Return type:

drgn.Object

drgn.helpers.linux.mm.pfn_to_virt(pfn)

Get the directly mapped virtual address of a page frame number (PFN) given as an Object.

Parameters:

pfn (drgn.Object) – unsigned long

Returns:

void *

Return type:

drgn.Object

drgn.helpers.linux.mm.pfn_to_virt(prog, pfn)

Get the directly mapped virtual address of a page frame number (PFN) given as a Program and an integer.

Parameters:

pfn (drgn.IntegerLike) – Page frame number.

Returns:

void *

Return type:

drgn.Object

drgn.helpers.linux.mm.phys_to_page(addr)

Get the page containing a directly mapped physical address given as an Object.

Parameters:

addr (drgn.Object) – phys_addr_t

Returns:

struct page *

Return type:

drgn.Object

drgn.helpers.linux.mm.phys_to_page(prog, addr)

Get the page containing a directly mapped physical address given as a Program and an integer.

Parameters:

addr (drgn.IntegerLike) – Physical address.

Returns:

struct page *

Return type:

drgn.Object

drgn.helpers.linux.mm.phys_to_virt(addr)

Get the directly mapped virtual address of a physical address given as an Object.

Parameters:

addr (drgn.Object) – phys_addr_t

Returns:

void *

Return type:

drgn.Object

drgn.helpers.linux.mm.phys_to_virt(prog, addr)

Get the directly mapped virtual address of a physical address given as a Program and an integer.

Parameters:

addr (drgn.IntegerLike) – Physical address.

Returns:

void *

Return type:

drgn.Object

drgn.helpers.linux.mm.virt_to_page(addr)

Get the page containing a directly mapped virtual address given as an Object.

Parameters:

addr (drgn.Object) – void *

Returns:

struct page *

Return type:

drgn.Object

drgn.helpers.linux.mm.virt_to_page(prog, addr)

Get the page containing a directly mapped virtual address given as a Program and an integer.

Parameters:

addr (drgn.IntegerLike) – Virtual address.

Returns:

struct page *

Return type:

drgn.Object

drgn.helpers.linux.mm.virt_to_pfn(addr)

Get the page frame number (PFN) of a directly mapped virtual address given as an Object.

Parameters:

addr (drgn.Object) – void *

Returns:

unsigned long

Return type:

drgn.Object

drgn.helpers.linux.mm.virt_to_pfn(prog, addr)

Get the page frame number (PFN) of a directly mapped virtual address given as a Program and an integer.

Parameters:

addr (drgn.IntegerLike) – Virtual address.

Returns:

unsigned long

Return type:

drgn.Object

drgn.helpers.linux.mm.virt_to_phys(addr)

Get the physical address of a directly mapped virtual address given as an Object.

Parameters:

addr (drgn.Object) – void *

Returns:

phys_addr_t

Return type:

drgn.Object

drgn.helpers.linux.mm.virt_to_phys(prog, addr)

Get the physical address of a directly mapped virtual address given as a Program and an integer.

Parameters:

addr (drgn.IntegerLike) – Virtual address.

Returns:

phys_addr_t

Return type:

drgn.Object

drgn.helpers.linux.mm.access_process_vm(task, address, size)

Read memory from a task’s virtual address space.

>>> task = find_task(prog, 1490152)
>>> access_process_vm(task, 0x7f8a62b56da0, 12)
b'hello, world'
Parameters:
Return type:

bytes

drgn.helpers.linux.mm.access_remote_vm(mm, address, size)

Read memory from a virtual address space. This is similar to access_process_vm(), but it takes a struct mm_struct * instead of a struct task_struct *.

>>> task = find_task(prog, 1490152)
>>> access_remote_vm(task.mm, 0x7f8a62b56da0, 12)
b'hello, world'
Parameters:
Return type:

bytes

drgn.helpers.linux.mm.cmdline(task)

Get the list of command line arguments of a task.

>>> cmdline(find_task(prog, 1495216))
[b'vim', b'drgn/helpers/linux/mm.py']
$ tr '\0' ' ' < /proc/1495216/cmdline
vim drgn/helpers/linux/mm.py
Parameters:

task (drgn.Object) – struct task_struct *

Return type:

List[bytes]

drgn.helpers.linux.mm.environ(task)

Get the list of environment variables of a task.

>>> environ(find_task(prog, 1497797))
[b'HOME=/root', b'PATH=/usr/local/sbin:/usr/local/bin:/usr/bin', b'LOGNAME=root']
$ tr '\0' '\n' < /proc/1497797/environ
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin
LOGNAME=root
Parameters:

task (drgn.Object) – struct task_struct *

Return type:

List[bytes]

Networking

The drgn.helpers.linux.net module provides helpers for working with the Linux kernel networking subsystem.

drgn.helpers.linux.net.SOCKET_I(inode)

Get a socket from an inode referring to the socket.

Parameters:

inode (drgn.Object) – struct inode *

Returns:

struct socket *

Raises:

ValueError – If inode does not refer to a socket

Return type:

drgn.Object

drgn.helpers.linux.net.SOCK_INODE(sock)

Get the inode of a socket.

Parameters:

sock (drgn.Object) – struct socket *

Returns:

struct inode *

Return type:

drgn.Object

drgn.helpers.linux.net.for_each_net(prog)

Iterate over all network namespaces in the system.

Returns:

Iterator of struct net * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.net.get_net_ns_by_inode(inode)

Get a network namespace from a network namespace NSFS inode, e.g. /proc/$PID/ns/net or /var/run/netns/$NAME.

Parameters:

inode (drgn.Object) – struct inode *

Returns:

struct net *

Raises:

ValueError – if inode is not a network namespace inode

Return type:

drgn.Object

drgn.helpers.linux.net.get_net_ns_by_fd(task, fd)

Get a network namespace from a task and a file descriptor referring to a network namespace NSFS inode, e.g. /proc/$PID/ns/net or /var/run/netns/$NAME.

Parameters:
Returns:

struct net *

Raises:

ValueError – If fd does not refer to a network namespace inode

Return type:

drgn.Object

drgn.helpers.linux.net.netdev_for_each_tx_queue(dev)

Iterate over all TX queues for a network device.

Parameters:

dev (drgn.Object) – struct net_device *

Returns:

Iterator of struct netdev_queue * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.net.netdev_get_by_index(prog_or_net, ifindex)

Get the network device with the given interface index number.

Parameters:
Returns:

struct net_device * (NULL if not found)

Return type:

drgn.Object

drgn.helpers.linux.net.netdev_get_by_name(prog_or_net, name)

Get the network device with the given interface name.

Parameters:
Returns:

struct net_device * (NULL if not found)

Return type:

drgn.Object

drgn.helpers.linux.net.sk_fullsock(sk)

Check whether a socket is a full socket, i.e., not a time-wait or request socket.

Parameters:

sk (drgn.Object) – struct sock *

Return type:

bool

drgn.helpers.linux.net.sk_nulls_for_each(head)

Iterate over all the entries in a nulls hash list of sockets specified by struct hlist_nulls_head head.

Parameters:

head (drgn.Object) – struct hlist_nulls_head *

Returns:

Iterator of struct sock * objects.

Return type:

Iterator[drgn.Object]

NUMA Node Masks

The drgn.helpers.linux.nodemask module provides helpers for working with NUMA node masks from include/linux/nodemask.h.

drgn.helpers.linux.nodemask.for_each_node_mask(mask)

Iterate over all of the NUMA nodes in the given mask.

Parameters:

mask (drgn.Object) – nodemask_t

Return type:

Iterator[int]

drgn.helpers.linux.nodemask.for_each_node_state(prog, state)

Iterate over all NUMA nodes in the given state.

Parameters:

state (drgn.IntegerLike) – enum node_states (e.g., N_NORMAL_MEMORY)

Return type:

Iterator[int]

drgn.helpers.linux.nodemask.for_each_node(prog)

Iterate over all possible NUMA nodes.

Return type:

Iterator[int]

drgn.helpers.linux.nodemask.for_each_online_node(prog)

Iterate over all online NUMA nodes.

Return type:

Iterator[int]

drgn.helpers.linux.nodemask.node_state(node, state)

Return whether the given NUMA node has the given state.

Parameters:
Return type:

bool

Per-CPU

The drgn.helpers.linux.percpu module provides helpers for working with per-CPU allocations from include/linux/percpu.h and per-CPU counters from include/linux/percpu_counter.h.

drgn.helpers.linux.percpu.per_cpu_ptr(ptr, cpu)

Return the per-CPU pointer for a given CPU.

>>> prog["init_net"].loopback_dev.pcpu_refcnt
(int *)0x2c980
>>> per_cpu_ptr(prog["init_net"].loopback_dev.pcpu_refcnt, 7)
*(int *)0xffff925e3ddec980 = 4
Parameters:
Returns:

type * object.

Return type:

drgn.Object

drgn.helpers.linux.percpu.per_cpu(var, cpu)

Return the per-CPU variable for a given CPU.

>>> print(repr(prog["runqueues"]))
Object(prog, 'struct rq', address=0x278c0)
>>> per_cpu(prog["runqueues"], 6).curr.comm
(char [16])"python3"
Parameters:
Returns:

type object.

Return type:

drgn.Object

drgn.helpers.linux.percpu.percpu_counter_sum(fbc)

Return the sum of a per-CPU counter.

Parameters:

fbc (drgn.Object) – struct percpu_counter *

Return type:

int

Process IDS

The drgn.helpers.linux.pid module provides helpers for looking up process IDs and processes.

drgn.helpers.linux.pid.find_pid(prog_or_ns, pid)

Return the struct pid * for the given PID number.

Parameters:

prog_or_ns (Union[drgn.Program, drgn.Object]) – struct pid_namespace * object, or Program to use initial PID namespace.

Returns:

struct pid *

Return type:

drgn.Object

drgn.helpers.linux.pid.find_task(prog_or_ns, pid)

Return the task with the given PID.

Parameters:

prog_or_ns (Union[drgn.Program, drgn.Object]) – struct pid_namespace * object, or Program to use initial PID namespace.

Returns:

struct task_struct *

Return type:

drgn.Object

drgn.helpers.linux.pid.pid_task(pid, pid_type)

Return the struct task_struct * containing the given struct pid * of the given type.

Parameters:
Returns:

struct task_struct *

Return type:

drgn.Object

drgn.helpers.linux.pid.for_each_pid(prog_or_ns)

Iterate over all PIDs in a namespace.

Parameters:

prog_or_ns (Union[drgn.Program, drgn.Object]) – struct pid_namespace * to iterate over, or Program to iterate over initial PID namespace.

Returns:

Iterator of struct pid * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.pid.for_each_task(prog_or_ns)

Iterate over all of the tasks visible in a namespace.

Parameters:

prog_or_ns (Union[drgn.Program, drgn.Object]) – struct pid_namespace * to iterate over, or Program to iterate over initial PID namespace.

Returns:

Iterator of struct task_struct * objects.

Return type:

Iterator[drgn.Object]

Log Buffer

The drgn.helpers.linux.printk module provides helpers for reading the Linux kernel log buffer.

class drgn.helpers.linux.printk.PrintkRecord

Bases: NamedTuple

Kernel log record.

text

Message text.

Vartype:

bytes

facility

syslog(3) facility.

Vartype:

int

level

Log level.

Vartype:

int

seq

Sequence number.

Vartype:

int

timestamp

Timestamp in nanoseconds.

Vartype:

int

caller_tid

Thread ID of thread that logged this record, if available.

This is available if the message was logged from task context and if the kernel saves the printk() caller ID.

As of Linux 5.10, the kernel always saves the caller ID. From Linux 5.1 through 5.9, it is saved only if the kernel was compiled with CONFIG_PRINTK_CALLER. Before that, it is never saved.

Vartype:

Optional[int]

caller_cpu

Processor ID of CPU that logged this record, if available.

This is available only if the message was logged when not in task context (e.g., in an interrupt handler) and if the kernel saves the printk() caller ID.

See caller_tid for when the kernel saves the caller ID.

Vartype:

Optional[int]

continuation

Whether this record is a continuation of a previous record.

Vartype:

bool

context

Additional metadata for the message.

See the /dev/kmsg documentation for an explanation of the keys and values.

Vartype:

Dict[bytes, bytes]

drgn.helpers.linux.printk.get_printk_records(prog)

Get a list of records in the kernel log buffer.

Return type:

List[PrintkRecord]

drgn.helpers.linux.printk.get_dmesg(prog)

Get the contents of the kernel log buffer formatted like dmesg(1).

The format of each line is:

[   timestamp] message

If you need to format the log buffer differently, use get_printk_records() and format it yourself.

Return type:

bytes

Radix Trees

The drgn.helpers.linux.radixtree module provides helpers for working with radix trees from include/linux/radix-tree.h.

drgn.helpers.linux.radixtree.radix_tree_lookup(root, index)

Look up the entry at a given index in a radix tree.

Parameters:
Returns:

void * found entry, or NULL if not found.

Return type:

drgn.Object

drgn.helpers.linux.radixtree.radix_tree_for_each(root)

Iterate over all of the entries in a radix tree.

Parameters:

root (drgn.Object) – struct radix_tree_root *

Returns:

Iterator of (index, void *) tuples.

Return type:

Iterator[Tuple[int, drgn.Object]]

Red-Black Trees

The drgn.helpers.linux.rbtree module provides helpers for working with red-black trees from include/linux/rbtree.h.

drgn.helpers.linux.rbtree.RB_EMPTY_ROOT(root)

Return whether a red-black tree is empty.

Parameters:

nodestruct rb_root *

Return type:

bool

drgn.helpers.linux.rbtree.RB_EMPTY_NODE(node)

Return whether a red-black tree node is empty, i.e., not inserted in a tree.

Parameters:

node (drgn.Object) – struct rb_node *

Return type:

bool

drgn.helpers.linux.rbtree.rb_parent(node)

Return the parent node of a red-black tree node.

Parameters:

node (drgn.Object) – struct rb_node *

Returns:

struct rb_node *

Return type:

drgn.Object

drgn.helpers.linux.rbtree.rb_first(root)

Return the first node (in sort order) in a red-black tree, or NULL if the tree is empty.

Parameters:

root (drgn.Object) – struct rb_root *

Returns:

struct rb_node *

Return type:

drgn.Object

drgn.helpers.linux.rbtree.rb_last(root)

Return the last node (in sort order) in a red-black tree, or NULL if the tree is empty.

Parameters:

root (drgn.Object) – struct rb_root *

Returns:

struct rb_node *

Return type:

drgn.Object

drgn.helpers.linux.rbtree.rb_next(node)

Return the next node (in sort order) after a red-black node, or NULL if the node is the last node in the tree or is empty.

Parameters:

node (drgn.Object) – struct rb_node *

Returns:

struct rb_node *

Return type:

drgn.Object

drgn.helpers.linux.rbtree.rb_prev(node)

Return the previous node (in sort order) before a red-black node, or NULL if the node is the first node in the tree or is empty.

Parameters:

node (drgn.Object) – struct rb_node *

Returns:

struct rb_node *

Return type:

drgn.Object

drgn.helpers.linux.rbtree.rbtree_inorder_for_each(root)

Iterate over all of the nodes in a red-black tree, in sort order.

Parameters:

root (drgn.Object) – struct rb_root *

Returns:

Iterator of struct rb_node * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.rbtree.rbtree_inorder_for_each_entry(type, root, member)

Iterate over all of the entries in a red-black tree in sorted order.

Parameters:
Returns:

Iterator of type * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.rbtree.rb_find(type, root, member, key, cmp)

Find an entry in a red-black tree given a key and a comparator function.

Note that this function does not have an analogue in the Linux kernel source code, as tree searches are all open-coded.

Parameters:
  • type (Union[str, drgn.Type]) – Entry type.

  • root (drgn.Object) – struct rb_root *

  • member (str) – Name of struct rb_node member in entry type.

  • key (KeyType) – Key to find.

  • cmp (Callable[[KeyType, drgn.Object], int]) – Callback taking key and entry that returns < 0 if the key is less than the entry, > 0 if the key is greater than the entry, and 0 if the key matches the entry.

Returns:

type * found entry, or NULL if not found.

Return type:

drgn.Object

drgn.helpers.linux.rbtree.validate_rbtree(type, root, member, cmp, allow_equal)

Validate a red-black tree.

This checks that:

  1. The tree is a valid binary search tree ordered according to cmp.

  2. If allow_equal is False, there are no nodes that compare equal according to cmp.

  3. The rb_parent pointers are consistent.

  4. The red-black tree requirements are satisfied: the root node is black, no red node has a red child, and every path from any node to any of its descendant leaf nodes goes through the same number of black nodes.

Parameters:
  • type (Union[str, drgn.Type]) – Entry type.

  • root (drgn.Object) – struct rb_root *

  • member (str) – Name of struct rb_node member in entry type.

  • cmp (Callable[[drgn.Object, drgn.Object], int]) – Callback taking two type * entry objects that returns < 0 if the first entry is less than the second entry, > 0 if the first entry is greater than the second entry, and 0 if they are equal.

  • allow_equal (bool) – Whether the tree may contain entries that compare equal to each other.

Raises:

ValidationError – if the tree is invalid

Return type:

None

drgn.helpers.linux.rbtree.validate_rbtree_inorder_for_each_entry(type, root, member, cmp, allow_equal)

Like rbtree_inorder_for_each_entry(), but validates the red-black tree like validate_rbtree() while iterating.

Parameters:
  • type (Union[str, drgn.Type]) – Entry type.

  • root (drgn.Object) – struct rb_root *

  • member (str) – Name of struct rb_node member in entry type.

  • cmp (Callable[[drgn.Object, drgn.Object], int]) – Callback taking two type * entry objects that returns < 0 if the first entry is less than the second entry, > 0 if the first entry is greater than the second entry, and 0 if they are equal.

  • allow_equal (bool) – Whether the tree may contain entries that compare equal to each other.

Raises:

ValidationError – if the tree is invalid

Return type:

Iterator[drgn.Object]

CPU Scheduler

The drgn.helpers.linux.sched module provides helpers for working with the Linux CPU scheduler.

drgn.helpers.linux.sched.idle_task(prog, cpu)

Return the idle thread (PID 0, a.k.a swapper) for the given CPU.

>>> idle_task(prog, 1).comm
(char [16])"swapper/1"
Parameters:

cpu (drgn.IntegerLike) – CPU number.

Returns:

struct task_struct *

Return type:

drgn.Object

drgn.helpers.linux.sched.task_state_to_char(task)

Get the state of the task as a character (e.g., 'R' for running). See ps(1) for a description of the process state codes.

Parameters:

task (drgn.Object) – struct task_struct *

Return type:

str

Slab Allocator

The drgn.helpers.linux.slab module provides helpers for working with the Linux slab allocator.

Warning

Beware of slab merging when using these helpers. See slab_cache_is_merged().

drgn.helpers.linux.slab.slab_cache_is_merged(slab_cache)

Return whether a slab cache has been merged with any other slab caches.

Unless configured otherwise, the kernel may merge slab caches of similar sizes together. See the SLUB users guide and slab_merge/slab_nomerge in the kernel parameters documentation.

This can cause confusion, as only the name of the first cache will be found, and objects of different types will be mixed in the same slab cache.

For example, suppose that we have two types, struct foo and struct bar, which have the same size but are otherwise unrelated. If the kernel creates a slab cache named foo for struct foo, then another slab cache named bar for struct bar, then slab cache foo will be reused instead of creating another cache for bar. So the following will fail:

find_slab_cache(prog, "bar")

And the following will also return struct bar * objects errantly casted to struct foo *:

slab_cache_for_each_allocated_object(
    find_slab_cache(prog, "foo"), "struct foo"
)

Unfortunately, these issues are difficult to work around generally, so one must be prepared to handle them on a case-by-case basis (e.g., by looking up the slab cache by its variable name and by checking that members of the structure make sense for the expected type).

Parameters:

slab_cache (drgn.Object) – struct kmem_cache *

Return type:

bool

drgn.helpers.linux.slab.for_each_slab_cache(prog)

Iterate over all slab caches.

Returns:

Iterator of struct kmem_cache * objects.

Return type:

Iterator[drgn.Object]

drgn.helpers.linux.slab.find_slab_cache(prog, name)

Return the slab cache with the given name.

Parameters:

name (Union[str, bytes]) – Slab cache name.

Returns:

struct kmem_cache *

Return type:

Optional[drgn.Object]

drgn.helpers.linux.slab.print_slab_caches(prog)

Print the name and struct kmem_cache * value of all slab caches.

Return type:

None

drgn.helpers.linux.slab.slab_cache_for_each_allocated_object(slab_cache, type)

Iterate over all allocated objects in a given slab cache.

Only the SLUB and SLAB allocators are supported; SLOB does not store enough information to identify objects in a slab cache.

>>> dentry_cache = find_slab_cache(prog, "dentry")
>>> next(slab_cache_for_each_allocated_object(dentry_cache, "struct dentry"))
*(struct dentry *)0xffff905e41404000 = {
    ...
}
Parameters:
Returns:

Iterator of type * objects.

Return type:

Iterator[drgn.Object]

Traffic Control (TC)

The drgn.helpers.linux.tc module provides helpers for working with the Linux kernel Traffic Control (TC) subsystem.

drgn.helpers.linux.tc.qdisc_lookup(dev, major)

Get a Qdisc from a device and a major handle number. It is worth noting that conventionally handles are hexadecimal, e.g. 10: in a tc command means major handle 0x10.

Parameters:
Returns:

struct Qdisc * (NULL if not found)

Return type:

drgn.Object

TCP

The drgn.helpers.linux.tcp module provides helpers for working with the TCP protocol in the Linux kernel.

drgn.helpers.linux.tcp.sk_tcpstate(sk)

Return the TCP protocol state of a socket.

Parameters:

sk (drgn.Object) – struct sock *

Returns:

TCP state enum value.

Return type:

drgn.Object

Users

The drgn.helpers.linux.user module provides helpers for working with users in the Linux kernel.

drgn.helpers.linux.user.find_user(prog, uid)

Return the user structure with the given UID.

Parameters:

uid (Union[drgn.Object, drgn.IntegerLike]) – kuid_t object or integer.

Returns:

struct user_struct * (NULL if not found)

Return type:

drgn.Object

drgn.helpers.linux.user.for_each_user(prog)

Iterate over all users in the system.

Returns:

Iterator of struct user_struct * objects.

Return type:

Iterator[drgn.Object]