Helpers¶
The drgn.helpers package contains subpackages which provide helpers for
working with particular types of programs. Currently, there are common helpers
and helpers for the Linux kernel. In the future, there may be helpers for,
e.g., glibc and libstdc++.
- class drgn.helpers.ValidationError¶
Bases:
ExceptionError raised by a validator when an inconsistent or invalid state is detected.
Common¶
The drgn.helpers.common package provides helpers that can be used with any
program. 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.common.memory import identify_address
>>> from drgn.helpers.common import identify_address
Some of these helpers may have additional program-specific behavior but are otherwise generic.
Formatting¶
The drgn.helpers.common.format module provides generic helpers for
formatting different things as text.
- drgn.helpers.common.format.escape_ascii_character(c: int, escape_single_quote: bool = False, escape_double_quote: bool = False, escape_backslash: bool = False) str¶
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\rare escaped in hexadecimal format (e.g.,\x7f). By default, printable characters are never escaped.- Parameters
c – Character to escape.
escape_single_quote – Whether to escape single quotes to
\'.escape_double_quote – Whether to escape double quotes to
\".escape_backslash – Whether to escape backslashes to
\\.
- drgn.helpers.common.format.escape_ascii_string(buffer: Iterable[int], escape_single_quote: bool = False, escape_double_quote: bool = False, escape_backslash: bool = False) str¶
Escape an iterable of ASCII byte values (e.g.,
bytesorbytearray). Seeescape_ascii_character().- Parameters
buffer – Byte array to escape.
- drgn.helpers.common.format.decode_flags(value: drgn.IntegerLike, flags: Iterable[Tuple[str, int]], bit_numbers: bool = True) str¶
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 – Bitmask to decode.
flags – List of flag names and their bit numbers or values.
bit_numbers – Whether flags specifies the bit numbers (where 0 is the least significant bit) or values of the flags.
- drgn.helpers.common.format.decode_enum_type_flags(value: drgn.IntegerLike, type: drgn.Type, bit_numbers: bool = True) str¶
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 – Bitmask to decode.
type – Enumerated type with bit numbers for enumerators.
bit_numbers – Whether the enumerator values specify the bit numbers or values of the flags.
Memory¶
The drgn.helpers.common.memory module provides helpers for working with memory and addresses.
- drgn.helpers.common.memory.identify_address(addr: drgn.Object) Optional[str]¶
- drgn.helpers.common.memory.identify_address(prog: drgn.Program, addr: drgn.IntegerLike) Optional[str]
Try to identify what an address refers to.
For all programs, this will identify addresses as follows:
Object symbols (e.g., addresses in global variables):
object symbol: {symbol_name}+{hex_offset}(wherehex_offsetis the offset from the beginning of the symbol in hexadecimal).Function symbols (i.e., addresses in functions):
function symbol: {symbol_name}+{hex_offset}.Other symbols:
symbol: {symbol_name}+{hex_offset}.
Additionally, for the Linux kernel, this will identify:
Allocated slab objects:
slab object: {slab_cache_name}+{hex_offset}(wherehex_offsetis the offset from the beginning of the object in hexadecimal).Free slab objects:
free slab object: {slab_cache_name}+{hex_offset}.
This may recognize other types of addresses in the future.
The address can be given as an
Objector as aProgramand an integer.- Parameters
addr –
void *- Returns
Identity as string, or
Noneif the address is unrecognized.
Stack¶
The drgn.helpers.common.stack module provides helpers for working with
stack traces.
- drgn.helpers.common.stack.print_annotated_stack(trace: drgn.StackTrace) None¶
Print the contents of stack memory in a stack trace, annotating values that can be identified.
Currently, this will identify any addresses on the stack with
identify_address().>>> print_annotated_stack(prog.stack_trace(1)) STACK POINTER VALUE [stack frame #0 at 0xffffffff8dc93c41 (__schedule+0x429/0x488) in context_switch at ./kernel/sched/core.c:5209:2 (inlined)] [stack frame #1 at 0xffffffff8dc93c41 (__schedule+0x429/0x488) in __schedule at ./kernel/sched/core.c:6521:8] ffffa903c0013d28: ffffffff8d8497bf [function symbol: __flush_tlb_one_user+0x5] ffffa903c0013d30: 000000008d849eb5 ffffa903c0013d38: 0000000000000001 ffffa903c0013d40: 0000000000000004 ffffa903c0013d48: efdea37bb7cb1f00 ffffa903c0013d50: ffff926641178000 [slab object: task_struct+0x0] ffffa903c0013d58: ffff926641178000 [slab object: task_struct+0x0] ffffa903c0013d60: ffffa903c0013e10 ffffa903c0013d68: ffff926641177ff0 [slab object: mm_struct+0x70] ffffa903c0013d70: ffff926641178000 [slab object: task_struct+0x0] ffffa903c0013d78: ffff926641178000 [slab object: task_struct+0x0] ffffa903c0013d80: ffffffff8dc93d29 [function symbol: schedule+0x89] ...
- Parameters
trace – Stack trace to print.
Types¶
The drgn.helpers.common.type module provides generic helpers for working
with types in ways that aren’t provided by the core drgn library.
- drgn.helpers.common.type.enum_type_to_class(type: drgn.Type, name: str, exclude: Container[str] = (), prefix: str = '') Type[enum.IntEnum]¶
Get an
enum.IntEnumclass from an enumerateddrgn.Type.- Parameters
type – Enumerated type to convert.
name – Name of the
IntEnumtype to create.exclude – Container (e.g., list or set) of enumerator names to exclude from the created
IntEnum.prefix – Prefix to strip from the beginning of enumerator names.
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: drgn.Object, size: drgn.IntegerLike) Iterator[int]¶
Iterate over all set (one) bits in a bitmap.
- Parameters
bitmap –
unsigned long *size – Size of bitmap in bits.
- drgn.helpers.linux.bitops.for_each_clear_bit(bitmap: drgn.Object, size: drgn.IntegerLike) Iterator[int]¶
Iterate over all clear (zero) bits in a bitmap.
- Parameters
bitmap –
unsigned long *size – Size of bitmap in bits.
- drgn.helpers.linux.bitops.test_bit(nr: drgn.IntegerLike, bitmap: drgn.Object) bool¶
Return whether a bit in a bitmap is set.
- Parameters
nr – Bit number.
bitmap –
unsigned long *
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: drgn.Object) drgn.Object¶
Get a disk’s device number.
- Parameters
disk –
struct gendisk *- Returns
dev_t
- drgn.helpers.linux.block.disk_name(disk: drgn.Object) bytes¶
Get the name of a disk (e.g.,
sda).- Parameters
disk –
struct gendisk *
- drgn.helpers.linux.block.for_each_disk(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all disks in the system.
- Returns
Iterator of
struct gendisk *objects.
- drgn.helpers.linux.block.print_disks(prog: drgn.Program) None¶
Print all of the disks in the system.
- drgn.helpers.linux.block.part_devt(part: drgn.Object) drgn.Object¶
Get a partition’s device number.
- Parameters
part –
struct block_device *orstruct hd_struct *depending on the kernel version.- Returns
dev_t
- drgn.helpers.linux.block.part_name(part: drgn.Object) bytes¶
Get the name of a partition (e.g.,
sda1).- Parameters
part –
struct block_device *orstruct hd_struct *depending on the kernel version.
- drgn.helpers.linux.block.for_each_partition(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all partitions in the system.
- Returns
Iterator of
struct block_device *orstruct hd_struct *objects depending on the kernel version.
- drgn.helpers.linux.block.print_partitions(prog: drgn.Program) None¶
Print all of the partitions in the system.
Boot¶
The drgn.helpers.linux.boot module provides helpers for inspecting the
Linux kernel boot configuration.
- drgn.helpers.linux.boot.kaslr_offset(prog: drgn.Program) int¶
Get the kernel address space layout randomization offset (zero if it is disabled).
- drgn.helpers.linux.boot.pgtable_l5_enabled(prog: drgn.Program) bool¶
Return whether 5-level paging is enabled.
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: drgn.Program) Iterator[drgn.Object]¶
Iterate over all BTF objects.
This is only supported since Linux v4.18.
- Returns
Iterator of
struct btf *objects.
- drgn.helpers.linux.bpf.bpf_link_for_each(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all BPF links.
This is only supported since Linux v5.8.
- Returns
Iterator of
struct bpf_link *objects.
- drgn.helpers.linux.bpf.bpf_map_for_each(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all BPF maps.
This is only supported since Linux v4.13.
- Returns
Iterator of
struct bpf_map *objects.
- drgn.helpers.linux.bpf.bpf_prog_for_each(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all BPF programs.
This is only supported since Linux v4.13.
- Returns
Iterator of
struct bpf_prog *objects.
- drgn.helpers.linux.bpf.cgroup_bpf_prog_for_each(cgrp: drgn.Object, bpf_attach_type: drgn.IntegerLike) Iterator[drgn.Object]¶
Iterate over all cgroup BPF programs of the given attach type attached to the given cgroup.
- Parameters
cgrp –
struct cgroup *bpf_attach_type –
enum bpf_attach_type
- Returns
Iterator of
struct bpf_prog *objects.
- drgn.helpers.linux.bpf.cgroup_bpf_prog_for_each_effective(cgrp: drgn.Object, bpf_attach_type: drgn.IntegerLike) Iterator[drgn.Object]¶
Iterate over all effective cgroup BPF programs of the given attach type for the given cgroup.
- Parameters
cgrp –
struct cgroup *bpf_attach_type –
enum bpf_attach_type
- Returns
Iterator of
struct bpf_prog *objects.
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: drgn.Object) drgn.Object¶
Get the cgroup for a socket from the given
struct sock_cgroup_data *(usually fromstruct sock::sk_cgrp_data).- Parameters
skcd –
struct sock_cgroup_data *- Returns
struct cgroup *
- drgn.helpers.linux.cgroup.cgroup_parent(cgrp: drgn.Object) drgn.Object¶
Return the parent cgroup of the given cgroup if it exists,
NULLotherwise.- Parameters
cgrp –
struct cgroup *- Returns
struct cgroup *
- drgn.helpers.linux.cgroup.cgroup_name(cgrp: drgn.Object) bytes¶
Get the name of the given cgroup.
- Parameters
cgrp –
struct cgroup *
- drgn.helpers.linux.cgroup.cgroup_path(cgrp: drgn.Object) bytes¶
Get the full path of the given cgroup.
- Parameters
cgrp –
struct cgroup *
- drgn.helpers.linux.cgroup.cgroup_get_from_path(prog: drgn.Program, path: drgn.Path) drgn.Object¶
Look up a cgroup from its default hierarchy path .
- Parameters
path – Path name.
- drgn.helpers.linux.cgroup.css_next_child(pos: drgn.Object, parent: drgn.Object) drgn.Object¶
Get the next child (or
NULLif there is none) of the given parent starting from the given position (NULLto initiate traversal).- Parameters
pos –
struct cgroup_subsys_state *parent –
struct cgroup_subsys_state *
- Returns
struct cgroup_subsys_state *
- drgn.helpers.linux.cgroup.css_next_descendant_pre(pos: drgn.Object, root: drgn.Object) drgn.Object¶
Get the next pre-order descendant (or
NULLif there is none) of the given css root starting from the given position (NULLto initiate traversal).- Parameters
pos –
struct cgroup_subsys_state *root –
struct cgroup_subsys_state *
- Returns
struct cgroup_subsys_state *
- drgn.helpers.linux.cgroup.css_for_each_child(css: drgn.Object) Iterator[drgn.Object]¶
Iterate through children of the given css.
- Parameters
css –
struct cgroup_subsys_state *- Returns
Iterator of
struct cgroup_subsys_state *objects.
- drgn.helpers.linux.cgroup.css_for_each_descendant_pre(css: drgn.Object) Iterator[drgn.Object]¶
Iterate through the given css’s descendants in pre-order.
- Parameters
css –
struct cgroup_subsys_state *- Returns
Iterator of
struct cgroup_subsys_state *objects.
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: drgn.Object) Iterator[int]¶
Iterate over all of the CPUs in the given mask.
- Parameters
mask –
struct cpumask
- drgn.helpers.linux.cpumask.for_each_online_cpu(prog: drgn.Program) Iterator[int]¶
Iterate over all online CPUs.
- drgn.helpers.linux.cpumask.for_each_possible_cpu(prog: drgn.Program) Iterator[int]¶
Iterate over all possible CPUs.
- drgn.helpers.linux.cpumask.for_each_present_cpu(prog: drgn.Program) Iterator[int]¶
Iterate over all present CPUs.
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: drgn.IntegerLike) int¶
Return the major ID of a kernel
dev_t.- Parameters
dev –
dev_tobject or :class:int.
- drgn.helpers.linux.device.MINOR(dev: drgn.IntegerLike) int¶
Return the minor ID of a kernel
dev_t.- Parameters
dev –
dev_tobject or :class:int.
- drgn.helpers.linux.device.MKDEV(major: drgn.IntegerLike, minor: drgn.IntegerLike) int¶
Return a kernel
dev_tfrom the major and minor IDs.- Parameters
major – Device major ID.
minor – Device minor ID.
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: Union[drgn.Program, drgn.Object], path: drgn.Path, allow_negative: bool = False) drgn.Object¶
Look up the given path name.
- Parameters
prog_or_root –
struct path *object to use as root directory, orProgramto 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_negativeisFalse, 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., withopen()oros.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, }
- drgn.helpers.linux.fs.d_path(path: drgn.Object) bytes¶
Return the full path of a dentry given a
struct path.- Parameters
path –
struct pathorstruct path *
- drgn.helpers.linux.fs.d_path(vfsmnt: drgn.Object, dentry: drgn.Object) bytes
Return the full path of a dentry given a mount and dentry.
- Parameters
vfsmnt –
struct vfsmount *dentry –
struct dentry *
- drgn.helpers.linux.fs.dentry_path(dentry: drgn.Object) bytes¶
Return the path of a dentry from the root of its filesystem.
- Parameters
dentry –
struct dentry *
- drgn.helpers.linux.fs.inode_path(inode: drgn.Object) Optional[bytes]¶
Return any path of an inode from the root of its filesystem.
- Parameters
inode –
struct inode *- Returns
Path, or
Noneif the inode has no aliases.
- drgn.helpers.linux.fs.inode_paths(inode: drgn.Object) Iterator[bytes]¶
Return an iterator over all of the paths of an inode from the root of its filesystem.
- Parameters
inode –
struct inode *
- drgn.helpers.linux.fs.mount_src(mnt: drgn.Object) bytes¶
Get the source device name for a mount.
- Parameters
mnt –
struct mount *
- drgn.helpers.linux.fs.mount_dst(mnt: drgn.Object) bytes¶
Get the path of a mount point.
- Parameters
mnt –
struct mount *
- drgn.helpers.linux.fs.mount_fstype(mnt: drgn.Object) bytes¶
Get the filesystem type of a mount.
- Parameters
mnt –
struct mount *
- drgn.helpers.linux.fs.for_each_mount(prog_or_ns: Union[drgn.Program, drgn.Object], src: Optional[drgn.Path] = None, dst: Optional[drgn.Path] = None, fstype: Optional[Union[str, bytes]] = None) Iterator[drgn.Object]¶
Iterate over all of the mounts in a given namespace.
- Parameters
prog_or_ns –
struct mnt_namespace *to iterate over, orProgramto iterate over initial mount namespace.src – Only include mounts with this source device name.
dst – Only include mounts with this destination path.
fstype – Only include mounts with this filesystem type.
- Returns
Iterator of
struct mount *objects.
- drgn.helpers.linux.fs.print_mounts(prog_or_ns: Union[drgn.Program, drgn.Object], src: Optional[drgn.Path] = None, dst: Optional[drgn.Path] = None, fstype: Optional[Union[str, bytes]] = None) 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/mountsbut prints the value of eachstruct mount *.
- drgn.helpers.linux.fs.fget(task: drgn.Object, fd: drgn.IntegerLike) drgn.Object¶
Return the kernel file descriptor of the fd of a given task.
- Parameters
task –
struct task_struct *fd – File descriptor.
- Returns
struct file *
- drgn.helpers.linux.fs.for_each_file(task: drgn.Object) Iterator[Tuple[int, drgn.Object]]¶
Iterate over all of the files open in a given task.
- Parameters
task –
struct task_struct *- Returns
Iterator of (fd,
struct file *) tuples.
- drgn.helpers.linux.fs.print_files(task: drgn.Object) None¶
Print the open files of a given task.
- Parameters
task –
struct task_struct *
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: drgn.Object, id: drgn.IntegerLike) drgn.Object¶
Look up the entry with the given ID in an IDR.
- Parameters
idr –
struct idr *id – Entry ID.
- Returns
void *found entry, orNULLif not found.
- drgn.helpers.linux.idr.idr_for_each(idr: drgn.Object) Iterator[Tuple[int, drgn.Object]]¶
Iterate over all of the entries in an IDR.
- Parameters
idr –
struct idr *- Returns
Iterator of (index,
void *) tuples.
Kconfig¶
The drgn.helpers.linux.kconfig module provides helpers for reading the
Linux kernel build configuration.
- drgn.helpers.linux.kconfig.get_kconfig(prog: drgn.Program) Mapping[str, str]¶
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.
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: drgn.Object) bytes¶
Get the name of the given kernfs node.
- Parameters
kn –
struct kernfs_node *
- drgn.helpers.linux.kernfs.kernfs_path(kn: drgn.Object) bytes¶
Get full path of the given kernfs node.
- Parameters
kn –
struct kernfs_node *
- drgn.helpers.linux.kernfs.kernfs_walk(parent: drgn.Object, path: drgn.Path) drgn.Object¶
Find the kernfs node with the given path from the given parent kernfs node.
- Parameters
parent –
struct kernfs_node *path – Path name.
- Returns
struct kernfs_node *(NULLif not found)
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: drgn.Object) bool¶
Return whether a list is empty.
- Parameters
head –
struct list_head *
- drgn.helpers.linux.list.list_is_singular(head: drgn.Object) bool¶
Return whether a list has only one element.
- Parameters
head –
struct list_head *
- drgn.helpers.linux.list.list_first_entry(head: drgn.Object, type: Union[str, drgn.Type], member: str) drgn.Object¶
Return the first entry in a list.
The list is assumed to be non-empty.
See also
list_first_entry_or_null().- Parameters
head –
struct list_head *type – Entry type.
member – Name of list node member in entry type.
- Returns
type *
- drgn.helpers.linux.list.list_first_entry_or_null(head: drgn.Object, type: Union[str, drgn.Type], member: str) drgn.Object¶
Return the first entry in a list or
NULLif the list is empty.See also
list_first_entry().- Parameters
head –
struct list_head *type – Entry type.
member – Name of list node member in entry type.
- Returns
type *
- drgn.helpers.linux.list.list_last_entry(head: drgn.Object, type: Union[str, drgn.Type], member: str) drgn.Object¶
Return the last entry in a list.
The list is assumed to be non-empty.
- Parameters
head –
struct list_head *type – Entry type.
member – Name of list node member in entry type.
- Returns
type *
- drgn.helpers.linux.list.list_next_entry(pos: drgn.Object, member: str) drgn.Object¶
Return the next entry in a list.
- Parameters
pos –
type*member – Name of list node member in entry type.
- Returns
type *
- drgn.helpers.linux.list.list_prev_entry(pos: drgn.Object, member: str) drgn.Object¶
Return the previous entry in a list.
- Parameters
pos –
type*member – Name of list node member in entry type.
- Returns
type *
- drgn.helpers.linux.list.list_for_each(head: drgn.Object) Iterator[drgn.Object]¶
Iterate over all of the nodes in a list.
- Parameters
head –
struct list_head *- Returns
Iterator of
struct list_head *objects.
- drgn.helpers.linux.list.list_for_each_reverse(head: drgn.Object) Iterator[drgn.Object]¶
Iterate over all of the nodes in a list in reverse order.
- Parameters
head –
struct list_head *- Returns
Iterator of
struct list_head *objects.
- drgn.helpers.linux.list.list_for_each_entry(type: Union[str, drgn.Type], head: drgn.Object, member: str) Iterator[drgn.Object]¶
Iterate over all of the entries in a list.
- Parameters
type – Entry type.
head –
struct list_head *member – Name of list node member in entry type.
- Returns
Iterator of
type *objects.
- drgn.helpers.linux.list.list_for_each_entry_reverse(type: Union[str, drgn.Type], head: drgn.Object, member: str) Iterator[drgn.Object]¶
Iterate over all of the entries in a list in reverse order.
- Parameters
type – Entry type.
head –
struct list_head *member – Name of list node member in entry type.
- Returns
Iterator of
type *objects.
- drgn.helpers.linux.list.validate_list(head: drgn.Object) None¶
Validate that the
nextandprevpointers in a list are consistent.- Parameters
head –
struct list_head *- Raises
ValidationError – if the list is invalid
- drgn.helpers.linux.list.validate_list_for_each(head: drgn.Object) Iterator[drgn.Object]¶
Like
list_for_each(), but validates the list likevalidate_list()while iterating.- Parameters
head –
struct list_head *- Raises
ValidationError – if the list is invalid
- drgn.helpers.linux.list.validate_list_for_each_entry(type: Union[str, drgn.Type], head: drgn.Object, member: str) Iterator[drgn.Object]¶
Like
list_for_each_entry(), but validates the list likevalidate_list()while iterating.- Parameters
type – Entry type.
head –
struct list_head *member – Name of list node member in entry type.
- Raises
ValidationError – if the list is invalid
- drgn.helpers.linux.list.hlist_empty(head: drgn.Object) bool¶
Return whether a hash list is empty.
- Parameters
head –
struct hlist_head *
- drgn.helpers.linux.list.hlist_for_each(head: drgn.Object) Iterator[drgn.Object]¶
Iterate over all of the nodes in a hash list.
- Parameters
head –
struct hlist_head *- Returns
Iterator of
struct hlist_node *objects.
- drgn.helpers.linux.list.hlist_for_each_entry(type: Union[str, drgn.Type], head: drgn.Object, member: str) Iterator[drgn.Object]¶
Iterate over all of the entries in a hash list.
- Parameters
type – Entry type.
head –
struct hlist_head *member – Name of list node member in entry type.
- Returns
Iterator of
type *objects.
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: drgn.Object) bool¶
Return whether a a pointer is a nulls marker.
- Parameters
pos –
struct hlist_nulls_node *
- drgn.helpers.linux.list_nulls.hlist_nulls_empty(head: drgn.Object) bool¶
Return whether a nulls hash list is empty.
- Parameters
head –
struct hlist_nulls_head *
- drgn.helpers.linux.list_nulls.hlist_nulls_for_each_entry(type: Union[str, drgn.Type], head: drgn.Object, member: str) Iterator[drgn.Object]¶
Iterate over all the entries in a nulls hash list.
- Parameters
type – Entry type.
head –
struct hlist_nulls_head *member – Name of list node member in entry type.
- Returns
Iterator of
type *objects.
Lockless Lists¶
The drgn.helpers.linux.llist module provides helpers for working with the
lockless, NULL-terminated, singly-linked list implementation in
include/linux/llist.h (struct llist_head and struct
llist_node).
- drgn.helpers.linux.llist.llist_empty(head: drgn.Object) bool¶
Return whether an llist is empty.
- Parameters
head –
struct llist_head *
- drgn.helpers.linux.llist.llist_is_singular(head: drgn.Object) bool¶
Return whether an llist has only one element.
- Parameters
head –
struct llist_head *
- drgn.helpers.linux.llist.llist_first_entry(head: drgn.Object, type: Union[str, drgn.Type], member: str) drgn.Object¶
Return the first entry in an llist.
The list is assumed to be non-empty.
See also
llist_first_entry_or_null().- Parameters
head –
struct llist_head *type – Entry type.
member – Name of
struct llist_nodemember in entry type.
- Returns
type *
- drgn.helpers.linux.llist.llist_first_entry_or_null(head: drgn.Object, type: Union[str, drgn.Type], member: str) drgn.Object¶
Return the first entry in an llist or
NULLif the llist is empty.See also
llist_first_entry().- Parameters
head –
struct llist_head *type – Entry type.
member – Name of
struct llist_nodemember in entry type.
- Returns
type *
- drgn.helpers.linux.llist.llist_next_entry(pos: drgn.Object, member: str) drgn.Object¶
Return the next entry in an llist.
- Parameters
pos –
type*member – Name of
struct llist_nodemember in entry type.
- Returns
type *
- drgn.helpers.linux.llist.llist_for_each(node: drgn.Object) Iterator[drgn.Object]¶
Iterate over all of the nodes in an llist starting from a given node.
- Parameters
node –
struct llist_node *- Returns
Iterator of
struct llist_node *objects.
- drgn.helpers.linux.llist.llist_for_each_entry(type: Union[str, drgn.Type], node: drgn.Object, member: str) Iterator[drgn.Object]¶
Iterate over all of the entries in an llist starting from a given node.
- Parameters
type – Entry type.
node –
struct llist_node *member – Name of
struct llist_nodemember in entry type.
- Returns
Iterator of
type *objects.
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.PageActive(page: drgn.Object) bool¶
Return whether the
PG_activeflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageChecked(page: drgn.Object) bool¶
Return whether the
PG_checkedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageDirty(page: drgn.Object) bool¶
Return whether the
PG_dirtyflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageDoubleMap(page: drgn.Object) bool¶
Return whether the
PG_double_mapflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageError(page: drgn.Object) bool¶
Return whether the
PG_errorflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageForeign(page: drgn.Object) bool¶
Return whether the
PG_foreignflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageHWPoison(page: drgn.Object) bool¶
Return whether the
PG_hwpoisonflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageHasHWPoisoned(page: drgn.Object) bool¶
Return whether the
PG_has_hwpoisonedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageIdle(page: drgn.Object) bool¶
Return whether the
PG_idleflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageIsolated(page: drgn.Object) bool¶
Return whether the
PG_isolatedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageLRU(page: drgn.Object) bool¶
Return whether the
PG_lruflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageLocked(page: drgn.Object) bool¶
Return whether the
PG_lockedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageMappedToDisk(page: drgn.Object) bool¶
Return whether the
PG_mappedtodiskflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageMlocked(page: drgn.Object) bool¶
Return whether the
PG_mlockedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageOwnerPriv1(page: drgn.Object) bool¶
Return whether the
PG_owner_priv_1flag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PagePinned(page: drgn.Object) bool¶
Return whether the
PG_pinnedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PagePrivate(page: drgn.Object) bool¶
Return whether the
PG_privateflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PagePrivate2(page: drgn.Object) bool¶
Return whether the
PG_private_2flag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageReadahead(page: drgn.Object) bool¶
Return whether the
PG_readaheadflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageReclaim(page: drgn.Object) bool¶
Return whether the
PG_reclaimflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageReferenced(page: drgn.Object) bool¶
Return whether the
PG_referencedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageReported(page: drgn.Object) bool¶
Return whether the
PG_reportedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageReserved(page: drgn.Object) bool¶
Return whether the
PG_reservedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageSavePinned(page: drgn.Object) bool¶
Return whether the
PG_savepinnedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageSkipKASanPoison(page: drgn.Object) bool¶
Return whether the
PG_skip_kasan_poisonflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageSlab(page: drgn.Object) bool¶
Return whether the
PG_slabflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageSlobFree(page: drgn.Object) bool¶
Return whether the
PG_slob_freeflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageSwapBacked(page: drgn.Object) bool¶
Return whether the
PG_swapbackedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageUncached(page: drgn.Object) bool¶
Return whether the
PG_uncachedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageUnevictable(page: drgn.Object) bool¶
Return whether the
PG_unevictableflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageUptodate(page: drgn.Object) bool¶
Return whether the
PG_uptodateflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageVmemmapSelfHosted(page: drgn.Object) bool¶
Return whether the
PG_vmemmap_self_hostedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageWaiters(page: drgn.Object) bool¶
Return whether the
PG_waitersflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageWorkingset(page: drgn.Object) bool¶
Return whether the
PG_workingsetflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageWriteback(page: drgn.Object) bool¶
Return whether the
PG_writebackflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageXenRemapped(page: drgn.Object) bool¶
Return whether the
PG_xen_remappedflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageYoung(page: drgn.Object) bool¶
Return whether the
PG_youngflag is set on a page.- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageCompound(page: drgn.Object) bool¶
Return whether a page is part of a compound page.
- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageHead(page: drgn.Object) bool¶
Return whether a page is a head page in a compound page.
- Parameters
page –
struct page *
- drgn.helpers.linux.mm.PageTail(page: drgn.Object) bool¶
Return whether a page is a tail page in a compound page.
- Parameters
page –
struct page *
- drgn.helpers.linux.mm.compound_head(page: drgn.Object) drgn.Object¶
Get the head page associated with a page.
If page is a tail page, this returns the head page of the compound page it belongs to. Otherwise, it returns page.
- Parameters
page –
struct page *- Returns
struct page *
- drgn.helpers.linux.mm.compound_order(page: drgn.Object) drgn.Object¶
Return the allocation order of a potentially compound page.
- Parameters
page –
struct page *- Returns
unsigned int
- drgn.helpers.linux.mm.compound_nr(page: drgn.Object) drgn.Object¶
Return the number of pages in a potentially compound page.
- Parameters
page –
struct page *- Returns
unsigned long
- drgn.helpers.linux.mm.page_size(page: drgn.Object) drgn.Object¶
Return the number of bytes in a potentially compound page.
- Parameters
page –
struct page *- Returns
unsigned long
- drgn.helpers.linux.mm.decode_page_flags(page: drgn.Object) str¶
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 –
struct page *
- drgn.helpers.linux.mm.for_each_page(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over every
struct page *from the minimum to the maximum page.Note
This may include offline pages which don’t have a valid
struct page. Wrap accesses in atry…exceptdrgn.FaultError:>>> for page in for_each_page(prog): ... try: ... if PageLRU(page): ... print(hex(page)) ... except drgn.FaultError: ... continue 0xfffffb4a000c0000 0xfffffb4a000c0040 ...
This may be fixed in the future.
- Returns
Iterator of
struct page *objects.
- drgn.helpers.linux.mm.PFN_PHYS(pfn: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.PFN_PHYS(prog: drgn.Program, pfn: drgn.IntegerLike) drgn.Object
Get the physical address of a page frame number (PFN).
The PFN can be given as an
Objector as aProgramand an integer.- Parameters
pfn –
unsigned long- Returns
phys_addr_t
- drgn.helpers.linux.mm.PHYS_PFN(addr: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.PHYS_PFN(prog: drgn.Program, addr: int) drgn.Object
Get the page frame number (PFN) of a physical address.
The address can be given as an
Objector as aProgramand an integer.- Parameters
addr –
phys_addr_t- Returns
unsigned long
- drgn.helpers.linux.mm.page_to_pfn(page: drgn.Object) drgn.Object¶
Get the page frame number (PFN) of a page.
- Parameters
page –
struct page *- Returns
unsigned long
- drgn.helpers.linux.mm.page_to_phys(page: drgn.Object) drgn.Object¶
Get the physical address of a page.
- Parameters
page –
struct page *- Returns
phys_addr_t
- drgn.helpers.linux.mm.page_to_virt(page: drgn.Object) drgn.Object¶
Get the directly mapped virtual address of a page.
- Parameters
page –
struct page *- Returns
void *
- drgn.helpers.linux.mm.pfn_to_page(pfn: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.pfn_to_page(prog: drgn.Program, pfn: drgn.IntegerLike) drgn.Object
Get the page with a page frame number (PFN).
The PFN can be given as an
Objector as aProgramand an integer.- Parameters
pfn –
unsigned long- Returns
struct page *
- drgn.helpers.linux.mm.pfn_to_virt(pfn: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.pfn_to_virt(prog: drgn.Program, pfn: drgn.IntegerLike) drgn.Object
Get the directly mapped virtual address of a page frame number (PFN).
The PFN can be given as an
Objector as aProgramand an integer.- Parameters
pfn –
unsigned long- Returns
void *
- drgn.helpers.linux.mm.phys_to_page(addr: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.phys_to_page(prog: drgn.Program, addr: drgn.IntegerLike) drgn.Object
Get the page containing a physical address.
The address can be given as an
Objector as aProgramand an integer.- Parameters
addr –
phys_addr_t- Returns
struct page *
- drgn.helpers.linux.mm.phys_to_virt(addr: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.phys_to_virt(prog: drgn.Program, addr: drgn.IntegerLike) drgn.Object
Get the directly mapped virtual address of a physical address.
The address can be given as an
Objector as aProgramand an integer.- Parameters
addr –
phys_addr_t- Returns
void *
- drgn.helpers.linux.mm.virt_to_page(addr: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.virt_to_page(prog: drgn.Program, addr: drgn.IntegerLike) drgn.Object
Get the page containing a directly mapped virtual address.
The address can be given as an
Objector as aProgramand an integer.- Parameters
addr –
void *- Returns
struct page *
- drgn.helpers.linux.mm.virt_to_pfn(addr: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.virt_to_pfn(prog: drgn.Program, addr: drgn.IntegerLike) drgn.Object
Get the page frame number (PFN) of a directly mapped virtual address.
The address can be given as an
Objector as aProgramand an integer.- Parameters
addr –
void *- Returns
unsigned long
- drgn.helpers.linux.mm.virt_to_phys(addr: drgn.Object) drgn.Object¶
- drgn.helpers.linux.mm.virt_to_phys(prog: drgn.Program, addr: drgn.IntegerLike) drgn.Object
Get the physical address of a directly mapped virtual address.
The address can be given as an
Objector as aProgramand an integer.- Parameters
addr –
void *- Returns
phys_addr_t
- drgn.helpers.linux.mm.access_process_vm(task: drgn.Object, address: drgn.IntegerLike, size: drgn.IntegerLike) bytes¶
Read memory from a task’s virtual address space.
>>> task = find_task(prog, 1490152) >>> access_process_vm(task, 0x7f8a62b56da0, 12) b'hello, world'
- Parameters
task –
struct task_struct *address – Starting address.
size – Number of bytes to read.
- drgn.helpers.linux.mm.access_remote_vm(mm: drgn.Object, address: drgn.IntegerLike, size: drgn.IntegerLike) bytes¶
Read memory from a virtual address space. This is similar to
access_process_vm(), but it takes astruct mm_struct *instead of astruct task_struct *.>>> task = find_task(prog, 1490152) >>> access_remote_vm(task.mm, 0x7f8a62b56da0, 12) b'hello, world'
- Parameters
mm –
struct mm_struct *address – Starting address.
size – Number of bytes to read.
- drgn.helpers.linux.mm.cmdline(task: drgn.Object) List[bytes]¶
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 –
struct task_struct *
- drgn.helpers.linux.mm.environ(task: drgn.Object) List[bytes]¶
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 –
struct task_struct *
Networking¶
The drgn.helpers.linux.net module provides helpers for working with the
Linux kernel networking subsystem.
- drgn.helpers.linux.net.SOCKET_I(inode: drgn.Object) drgn.Object¶
Get a socket from an inode referring to the socket.
- Parameters
inode –
struct inode *- Returns
struct socket *- Raises
ValueError – If inode does not refer to a socket
- drgn.helpers.linux.net.SOCK_INODE(sock: drgn.Object) drgn.Object¶
Get the inode of a socket.
- Parameters
sock –
struct socket *- Returns
struct inode *
- drgn.helpers.linux.net.for_each_net(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all network namespaces in the system.
- Returns
Iterator of
struct net *objects.
- drgn.helpers.linux.net.get_net_ns_by_inode(inode: drgn.Object) drgn.Object¶
Get a network namespace from a network namespace NSFS inode, e.g.
/proc/$PID/ns/netor/var/run/netns/$NAME.- Parameters
inode –
struct inode *- Returns
struct net *- Raises
ValueError – if inode is not a network namespace inode
- drgn.helpers.linux.net.get_net_ns_by_fd(task: drgn.Object, fd: drgn.IntegerLike) drgn.Object¶
Get a network namespace from a task and a file descriptor referring to a network namespace NSFS inode, e.g.
/proc/$PID/ns/netor/var/run/netns/$NAME.- Parameters
task –
struct task_struct *fd – File descriptor.
- Returns
struct net *- Raises
ValueError – If fd does not refer to a network namespace inode
- drgn.helpers.linux.net.netdev_for_each_tx_queue(dev: drgn.Object) Iterator[drgn.Object]¶
Iterate over all TX queues for a network device.
- Parameters
dev –
struct net_device *- Returns
Iterator of
struct netdev_queue *objects.
- drgn.helpers.linux.net.netdev_get_by_index(prog_or_net: Union[drgn.Program, drgn.Object], ifindex: drgn.IntegerLike) drgn.Object¶
Get the network device with the given interface index number.
- Parameters
prog_or_net –
struct net *containing the device, orProgramto use the initial network namespace.ifindex – Network interface index number.
- Returns
struct net_device *(NULLif not found)
- drgn.helpers.linux.net.netdev_get_by_name(prog_or_net: Union[drgn.Program, drgn.Object], name: Union[str, bytes]) drgn.Object¶
Get the network device with the given interface name.
- Parameters
prog_or_net –
struct net *containing the device, orProgramto use the initial network namespace.name – Network interface name.
- Returns
struct net_device *(NULLif not found)
- drgn.helpers.linux.net.sk_fullsock(sk: drgn.Object) bool¶
Check whether a socket is a full socket, i.e., not a time-wait or request socket.
- Parameters
sk –
struct sock *
- drgn.helpers.linux.net.sk_nulls_for_each(head: drgn.Object) Iterator[drgn.Object]¶
Iterate over all the entries in a nulls hash list of sockets specified by
struct hlist_nulls_headhead.- Parameters
head –
struct hlist_nulls_head *- Returns
Iterator of
struct sock *objects.
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: drgn.Object) Iterator[int]¶
Iterate over all of the NUMA nodes in the given mask.
- Parameters
mask –
nodemask_t
- drgn.helpers.linux.nodemask.for_each_node_state(prog: drgn.Program, state: drgn.IntegerLike) Iterator[int]¶
Iterate over all NUMA nodes in the given state.
- Parameters
state –
enum node_states(e.g.,N_NORMAL_MEMORY)
- drgn.helpers.linux.nodemask.for_each_node(prog: drgn.Program) Iterator[int]¶
Iterate over all possible NUMA nodes.
- drgn.helpers.linux.nodemask.for_each_online_node(prog: drgn.Program) Iterator[int]¶
Iterate over all online NUMA nodes.
- drgn.helpers.linux.nodemask.node_state(node: drgn.IntegerLike, state: drgn.Object) bool¶
Return whether the given NUMA node has the given state.
- Parameters
node – NUMA node number.
state –
enum node_states(e.g.,N_NORMAL_MEMORY)
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: drgn.Object, cpu: drgn.IntegerLike) drgn.Object¶
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
ptr – Per-CPU pointer, i.e.,
type __percpu *. For global variables, it’s usually easier to useper_cpu().cpu – CPU number.
- Returns
type *object.
- drgn.helpers.linux.percpu.per_cpu(var: drgn.Object, cpu: drgn.IntegerLike) drgn.Object¶
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
var – Per-CPU variable, i.e.,
type __percpu(not a pointer; useper_cpu_ptr()for that).cpu – CPU number.
- Returns
typeobject.
- drgn.helpers.linux.percpu.percpu_counter_sum(fbc: drgn.Object) int¶
Return the sum of a per-CPU counter.
- Parameters
fbc –
struct percpu_counter *
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: Union[drgn.Program, drgn.Object], pid: drgn.IntegerLike) drgn.Object¶
Return the
struct pid *for the given PID number.- Parameters
prog_or_ns –
struct pid_namespace *object, orProgramto use initial PID namespace.- Returns
struct pid *
- drgn.helpers.linux.pid.find_task(prog_or_ns: Union[drgn.Program, drgn.Object], pid: drgn.IntegerLike) drgn.Object¶
Return the task with the given PID.
- Parameters
prog_or_ns –
struct pid_namespace *object, orProgramto use initial PID namespace.- Returns
struct task_struct *
- drgn.helpers.linux.pid.pid_task(pid: drgn.Object, pid_type: drgn.IntegerLike) drgn.Object¶
Return the
struct task_struct *containing the givenstruct pid *of the given type.- Parameters
pid –
struct pid *pid_type –
enum pid_type
- Returns
struct task_struct *
- drgn.helpers.linux.pid.for_each_pid(prog_or_ns: Union[drgn.Program, drgn.Object]) Iterator[drgn.Object]¶
Iterate over all PIDs in a namespace.
- Parameters
prog_or_ns –
struct pid_namespace *to iterate over, orProgramto iterate over initial PID namespace.- Returns
Iterator of
struct pid *objects.
- drgn.helpers.linux.pid.for_each_task(prog_or_ns: Union[drgn.Program, drgn.Object]) Iterator[drgn.Object]¶
Iterate over all of the tasks visible in a namespace.
- Parameters
prog_or_ns –
struct pid_namespace *to iterate over, orProgramto iterate over initial PID namespace.- Returns
Iterator of
struct task_struct *objects.
Log Buffer¶
The drgn.helpers.linux.printk module provides helpers for reading the Linux
kernel log buffer.
- class drgn.helpers.linux.printk.PrintkRecord¶
Bases:
NamedTupleKernel log record.
- text: bytes¶
Message text.
- level: int¶
Log level.
- seq: int¶
Sequence number.
- timestamp: int¶
Timestamp in nanoseconds.
- caller_tid: Optional[int]¶
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.
- caller_cpu: Optional[int]¶
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_tidfor when the kernel saves the caller ID.
- continuation: bool¶
Whether this record is a continuation of a previous record.
- context: Dict[bytes, bytes]¶
Additional metadata for the message.
See the
/dev/kmsgdocumentation for an explanation of the keys and values.
- drgn.helpers.linux.printk.get_printk_records(prog: drgn.Program) List[PrintkRecord]¶
Get a list of records in the kernel log buffer.
- drgn.helpers.linux.printk.get_dmesg(prog: drgn.Program) bytes¶
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.
Radix Trees¶
The drgn.helpers.linux.radixtree module provides helpers for working with
radix trees from include/linux/radix-tree.h.
See also
XArrays, which were introduced in Linux 4.20 as a replacement for radix trees.
- drgn.helpers.linux.radixtree.radix_tree_lookup(root: drgn.Object, index: drgn.IntegerLike) drgn.Object¶
Look up the entry at a given index in a radix tree.
- Parameters
root –
struct radix_tree_root *index – Entry index.
- Returns
void *found entry, orNULLif not found.
- drgn.helpers.linux.radixtree.radix_tree_for_each(root: drgn.Object) Iterator[Tuple[int, drgn.Object]]¶
Iterate over all of the entries in a radix tree.
- Parameters
root –
struct radix_tree_root *- Returns
Iterator of (index,
void *) tuples.
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: drgn.Object) bool¶
Return whether a red-black tree is empty.
- Parameters
node –
struct rb_root *
- drgn.helpers.linux.rbtree.RB_EMPTY_NODE(node: drgn.Object) bool¶
Return whether a red-black tree node is empty, i.e., not inserted in a tree.
- Parameters
node –
struct rb_node *
- drgn.helpers.linux.rbtree.rb_parent(node: drgn.Object) drgn.Object¶
Return the parent node of a red-black tree node.
- Parameters
node –
struct rb_node *- Returns
struct rb_node *
- drgn.helpers.linux.rbtree.rb_first(root: drgn.Object) drgn.Object¶
Return the first node (in sort order) in a red-black tree, or
NULLif the tree is empty.- Parameters
root –
struct rb_root *- Returns
struct rb_node *
- drgn.helpers.linux.rbtree.rb_last(root: drgn.Object) drgn.Object¶
Return the last node (in sort order) in a red-black tree, or
NULLif the tree is empty.- Parameters
root –
struct rb_root *- Returns
struct rb_node *
- drgn.helpers.linux.rbtree.rb_next(node: drgn.Object) drgn.Object¶
Return the next node (in sort order) after a red-black node, or
NULLif the node is the last node in the tree or is empty.- Parameters
node –
struct rb_node *- Returns
struct rb_node *
- drgn.helpers.linux.rbtree.rb_prev(node: drgn.Object) drgn.Object¶
Return the previous node (in sort order) before a red-black node, or
NULLif the node is the first node in the tree or is empty.- Parameters
node –
struct rb_node *- Returns
struct rb_node *
- drgn.helpers.linux.rbtree.rbtree_inorder_for_each(root: drgn.Object) Iterator[drgn.Object]¶
Iterate over all of the nodes in a red-black tree, in sort order.
- Parameters
root –
struct rb_root *- Returns
Iterator of
struct rb_node *objects.
- drgn.helpers.linux.rbtree.rbtree_inorder_for_each_entry(type: Union[str, drgn.Type], root: drgn.Object, member: str) Iterator[drgn.Object]¶
Iterate over all of the entries in a red-black tree in sorted order.
- Parameters
type – Entry type.
root –
struct rb_root *member – Name of
struct rb_nodemember in entry type.
- Returns
Iterator of
type *objects.
- drgn.helpers.linux.rbtree.rb_find(type: Union[str, drgn.Type], root: drgn.Object, member: str, key: KeyType, cmp: Callable[[KeyType, drgn.Object], int]) drgn.Object¶
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 – Entry type.
root –
struct rb_root *member – Name of
struct rb_nodemember in entry type.key – Key to find.
cmp – 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, orNULLif not found.
- drgn.helpers.linux.rbtree.validate_rbtree(type: Union[str, drgn.Type], root: drgn.Object, member: str, cmp: Callable[[drgn.Object, drgn.Object], int], allow_equal: bool) None¶
Validate a red-black tree.
This checks that:
The tree is a valid binary search tree ordered according to cmp.
If allow_equal is
False, there are no nodes that compare equal according to cmp.The
rb_parentpointers are consistent.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 – Entry type.
root –
struct rb_root *member – Name of
struct rb_nodemember in entry type.cmp – 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 – Whether the tree may contain entries that compare equal to each other.
- Raises
ValidationError – if the tree is invalid
- drgn.helpers.linux.rbtree.validate_rbtree_inorder_for_each_entry(type: Union[str, drgn.Type], root: drgn.Object, member: str, cmp: Callable[[drgn.Object, drgn.Object], int], allow_equal: bool) Iterator[drgn.Object]¶
Like
rbtree_inorder_for_each_entry(), but validates the red-black tree likevalidate_rbtree()while iterating.- Parameters
type – Entry type.
root –
struct rb_root *member – Name of
struct rb_nodemember in entry type.cmp – 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 – Whether the tree may contain entries that compare equal to each other.
- Raises
ValidationError – if the tree is invalid
CPU Scheduler¶
The drgn.helpers.linux.sched module provides helpers for working with the
Linux CPU scheduler.
- drgn.helpers.linux.sched.idle_task(prog: drgn.Program, cpu: drgn.IntegerLike) drgn.Object¶
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 – CPU number.
- Returns
struct task_struct *
- drgn.helpers.linux.sched.task_cpu(task: drgn.Object) int¶
Return the CPU number that the given task last ran on.
- Parameters
task –
struct task_struct *
- drgn.helpers.linux.sched.task_state_to_char(task: drgn.Object) str¶
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 –
struct task_struct *
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: drgn.Object) bool¶
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_nomergein 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 fooandstruct bar, which have the same size but are otherwise unrelated. If the kernel creates a slab cache namedfooforstruct foo, then another slab cache namedbarforstruct bar, then slab cachefoowill be reused instead of creating another cache forbar. So the following will fail:find_slab_cache(prog, "bar")
And the following will also return
struct bar *objects errantly casted tostruct 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 –
struct kmem_cache *
- drgn.helpers.linux.slab.get_slab_cache_aliases(prog: drgn.Program) Dict[str, str]¶
Return a dict mapping slab cache name to the cache it was merged with.
The SLAB and SLUB subsystems can merge caches with similar settings and object sizes, as described in the documentation of
slab_cache_is_merged(). In some cases, the information about which caches were merged is lost, but in other cases, we can reconstruct the info. This function reconstructs the mapping, but requires that the kernel is configured withCONFIG_SLUBandCONFIG_SYSFS.The returned dict maps from original cache name, to merged cache name. You can use this mapping to discover the correct cache to lookup via
find_slab_cache(). The dict contains an entry only for caches which were merged into a cache of a different name.>>> cache_to_merged = get_slab_cache_aliases(prog) >>> cache_to_merged["dnotify_struct"] 'avc_xperms_data' >>> "avc_xperms_data" in cache_to_merged False >>> find_slab_cache(prog, "dnotify_struct") is None True >>> find_slab_cache(prog, "avc_xperms_data") is None False
- Warning
This function will only work on kernels which are built with
CONFIG_SLUBandCONFIG_SYSFSenabled.- Parameters
prog – Program to search
- Returns
Mapping of slab cache name to final merged name
- Raises
LookupError – If the helper fails because the debugged kernel doesn’t have the required configuration
- drgn.helpers.linux.slab.for_each_slab_cache(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all slab caches.
- Returns
Iterator of
struct kmem_cache *objects.
- drgn.helpers.linux.slab.find_slab_cache(prog: drgn.Program, name: Union[str, bytes]) Optional[drgn.Object]¶
Return the slab cache with the given name.
- Parameters
name – Slab cache name.
- Returns
struct kmem_cache *
- drgn.helpers.linux.slab.print_slab_caches(prog: drgn.Program) None¶
Print the name and
struct kmem_cache *value of all slab caches.
- drgn.helpers.linux.slab.slab_cache_for_each_allocated_object(slab_cache: drgn.Object, type: Union[str, drgn.Type]) Iterator[drgn.Object]¶
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
slab_cache –
struct kmem_cache *type – Type of object in the slab cache.
- Returns
Iterator of
type *objects.
- drgn.helpers.linux.slab.slab_object_info(addr: drgn.Object) Optional['SlabObjectInfo']¶
- drgn.helpers.linux.slab.slab_object_info(prog: drgn.Program, addr: drgn.IntegerLike) Optional[SlabObjectInfo]
Get information about an address if it is in a slab object.
>>> ptr = find_task(prog, 1).comm.address_of_() >>> info = slab_object_info(ptr) >>> info SlabObjectInfo(slab_cache=Object(prog, 'struct kmem_cache *', address=0xffffdb93c0045e18), slab=Object(prog, 'struct slab *', value=0xffffdb93c0045e00), address=0xffffa2bf81178000, allocated=True)
Note that
SlabObjectInfo.addressis the start address of the object, which may be less than addr if addr points to a member inside of the object:>>> ptr.value_() - info.address 1496 >>> offsetof(prog.type("struct task_struct"), "comm") 1496
The address can be given as an
Objector as aProgramand an integer.Note that SLOB does not store enough information to identify slab objects, so if the kernel is configured to use SLOB, this will always return
None.- Parameters
addr –
void *- Returns
SlabObjectInfoif addr is in a slab object, orNoneif not.
- class drgn.helpers.linux.slab.SlabObjectInfo¶
Information about an object in the slab allocator.
- slab_cache: drgn.Object¶
struct kmem_cache *that the slab object is from.
- slab: drgn.Object¶
Slab containing the slab object.
Since Linux v5.17, this is a
struct slab *. Before that, it is astruct page *.
- address: int¶
Address of the slab object.
- allocated: bool¶
Trueif the object is allocated,Falseif it is free.
- drgn.helpers.linux.slab.find_containing_slab_cache(addr: drgn.Object) drgn.Object¶
- drgn.helpers.linux.slab.find_containing_slab_cache(prog: drgn.Program, addr: drgn.IntegerLike) drgn.Object
Get the slab cache that an address was allocated from, if any.
The address can be given as an
Objector as aProgramand an integer.Note that SLOB does not store enough information to identify objects in a slab cache, so if the kernel is configured to use SLOB, this will always return
NULL.- Parameters
addr –
void *- Returns
struct kmem_cache *containing addr, orNULLif addr is not from a slab cache.
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: drgn.Object, major: drgn.IntegerLike) drgn.Object¶
Get a Qdisc from a device and a major handle number. It is worth noting that conventionally handles are hexadecimal, e.g.
10:in atccommand means major handle 0x10.- Parameters
dev –
struct net_device *major – Qdisc major handle number.
- Returns
struct Qdisc *(NULLif not found)
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: drgn.Object) drgn.Object¶
Return the TCP protocol state of a socket.
- Parameters
sk –
struct sock *- Returns
TCP state enum value.
Users¶
The drgn.helpers.linux.user module provides helpers for working with users
in the Linux kernel.
- drgn.helpers.linux.user.find_user(prog: drgn.Program, uid: Union[drgn.Object, drgn.IntegerLike]) drgn.Object¶
Return the user structure with the given UID.
- Parameters
uid –
kuid_tobject or integer.- Returns
struct user_struct *(NULLif not found)
- drgn.helpers.linux.user.for_each_user(prog: drgn.Program) Iterator[drgn.Object]¶
Iterate over all users in the system.
- Returns
Iterator of
struct user_struct *objects.
XArrays¶
The drgn.helpers.linux.xarray module provides helpers for working with the
XArray data structure from
include/linux/xarray.h.
Note
XArrays were introduced in Linux 4.20 as a replacement for radix trees.
To make it easier to work with data structures that were changed from a
radix tree to an XArray (like struct address_space::i_pages), drgn
treats XArrays and radix trees interchangeably in some cases.
Specifically, xa_load() is equivalent to
radix_tree_lookup(), and
xa_for_each() is equivalent to
radix_tree_for_each(), except that
the radix tree helpers assume advanced=False. (Therefore,
xa_load() and
xa_for_each() also accept a struct
radix_tree_root *, and
radix_tree_lookup() and
radix_tree_for_each() also accept a
struct xarray *.)
- drgn.helpers.linux.xarray.xa_load(xa: drgn.Object, index: drgn.IntegerLike, *, advanced: bool = False) drgn.Object¶
Look up the entry at a given index in an XArray.
>>> entry = xa_load(inode.i_mapping.i_pages.address_of_(), 2) >>> cast("struct page *", entry) *(struct page *)0xffffed6980306f40 = { ... }
- Parameters
xa –
struct xarray *index – Entry index.
advanced – Whether to return nodes only visible to the XArray advanced API. If
False, zero entries (seexa_is_zero()) will be returned asNULL.
- Returns
void *found entry, orNULLif not found.
- drgn.helpers.linux.xarray.xa_for_each(xa: drgn.Object, *, advanced: bool = False) Iterator[Tuple[int, drgn.Object]]¶
Iterate over all of the entries in an XArray.
>>> for index, entry in xa_for_each(inode.i_mapping.i_pages.address_of_()): ... print(index, entry) ... 0 (void *)0xffffed6980356140 1 (void *)0xffffed6980306f80 2 (void *)0xffffed6980306f40 3 (void *)0xffffed6980355b40
- Parameters
xa –
struct xarray *advanced – Whether to return nodes only visible to the XArray advanced API. If
False, zero entries (seexa_is_zero()) will be skipped.
- Returns
Iterator of (index,
void *) tuples.
- drgn.helpers.linux.xarray.xa_is_value(entry: drgn.Object) bool¶
Return whether an XArray entry is a value.
See
xa_to_value().- Parameters
entry –
void *
- drgn.helpers.linux.xarray.xa_to_value(entry: drgn.Object) drgn.Object¶
Return the value in an XArray entry.
In addition to pointers, XArrays can store integers between 0 and
LONG_MAX. Ifxa_is_value()returnsTrue, use this to get the stored integer.>>> entry = xa_load(xa, 9) >>> entry (void *)0xc9 >>> xa_is_value(entry) True >>> xa_to_value(entry) (unsigned long)100
- Parameters
entry –
void *- Returns
unsigned long
- drgn.helpers.linux.xarray.xa_is_zero(entry: drgn.Object) bool¶
Return whether an XArray entry is a “zero” entry.
A zero entry is an entry that was reserved but is not present. These are only visible to the XArray advanced API, so they are only returned by
xa_load()andxa_for_each()whenadvanced = True.>>> entry = xa_load(xa, 10, advanced=True) >>> entry (void *)0x406 >>> xa_is_zero(entry) True >>> xa_load(xa, 10) (void *)0
- Parameters
entry –
void *