# 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: `Exception`

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

  Validators are a special category of helpers that check the consistency of a data structure. In general, helpers assume that the data structures that they examine are valid. Validators do not make this assumption and do additional (potentially expensive) checks to detect broken invariants, corruption, etc.

  Validators raise `drgn.helpers.ValidationError` if the data structure is not valid or `drgn.FaultError` if the data structure is invalid in a way that causes a bad memory access. They have names prefixed with `validate_`.

## 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 `\r` are 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., `bytes` or `bytearray`). See `escape_ascii_character()`.

  Parameters:

    buffer – Byte array to escape.

drgn.helpers.common.format.double_quote_ascii_string(buffer: Iterable[int]) → str

  Get an iterable of ASCII byte values (e.g., `bytes` or `bytearray`) as a double-quoted string.

  This is equivalent to:

      '"' + escape_ascii_string(buffer, escape_double_quote=True, escape_backslash=True) + '"'

drgn.helpers.common.format.decode_flags(value: drgn.IntegerLike, flags: Iterable[Tuple[str, int]], bit_numbers: bool = True, aliases: 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.

    - aliases – Whether to include multiple names for the same flag. If `False`, then only the first name is included.

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.

drgn.helpers.common.format.number_in_binary_units(n: SupportsFloat, precision: int = 1) → str

  Format a number in binary units (i.e., “K” is 1024, “M” is 10242, etc.).

      >>> number_in_binary_units(1280)
      '1.2K'

  A precision can be specified:

      >>> number_in_binary_units(1280, precision=2)
      '1.25K'

  Exact numbers are printed without a fractional part:

      >>> number_in_binary_units(1024 * 1024)
      '1M'

  Numbers less than 1024 are not scaled:

      >>> number_in_binary_units(10)
      '10'

  Parameters:

    - n – Number to format.

    - precision – Number of digits to include in fractional part.

drgn.helpers.common.format.print_table(rows: Sequence[Sequence[Any]], *, sep: str = ' ', file: Optional[SupportsWrite[str]] = None) → None

  Print data as a table.

  The input is given as a sequence (e.g., `list` or `tuple`) of rows, where each row is a sequence of values. Rows can have different lengths.

      >>> print_table([[2, 2000, 4], ["", 3, 13, 19]])
      2  2000   4
            3  13  19

  By default, numbers are right-aligned and most other objects are left-aligned. This (and other format options) can be changed by wrapping the value in a `CellFormat`.

      >>> print_table(
      ...     [
      ...         ["DECIMAL", "HEXADECIMAL"],
      ...         [CellFormat(10, "<"), CellFormat(10, "<x")],
      ...     ]
      ... )
      DECIMAL  HEXADECIMAL
      10       a

  Rows can also be aligned in separate groups by wrapping them in a `RowOptions`. The default group is 0.

      >>> print_table(
      ...     [
      ...         ["LETTER", "INDEX"],
      ...         ["A", 1],
      ...         RowOptions(["WORD", "LENGTH"], group=1),
      ...         RowOptions(["angstrom", 8], group=1),
      ...         ["LETTER", "INDEX"],
      ...         ["B", 2],
      ...         RowOptions(["WORD", "LENGTH"], group=1),
      ...         RowOptions(["banana", 6], group=1),
      ...     ]
      ... )
      ...
      LETTER  INDEX
      A           1
      WORD      LENGTH
      angstrom       8
      LETTER  INDEX
      B           2
      WORD      LENGTH
      banana         6

  Parameters:

    - rows – Sequence of rows, where each row is a sequence of cells.

    - sep – Column separator.

    - file – File to write to (defaults to `sys.stdout`).

class drgn.helpers.common.format.CellFormat(value: Any, format_spec: str)

  Wrap a value with additional format options to apply when it is formatted by `print_table()`.

  Parameters:

    - value – Value to wrap.

    - format_spec – Format specification. It may not specify a width.

class drgn.helpers.common.format.RowOptions(row: Sequence[_T_co], *, group: Hashable = 0)

  Bases: `Sequence`[`_T_co`]

  > Wrap a row with additional options to apply when it is formatted by `print_table()`.

  > param row:

  >   Row to wrap.

  > param group:

  >   Align this row only with other rows in this group.

### Memory

The `drgn.helpers.common.memory` module provides helpers for working with memory and addresses.

drgn.helpers.common.memory.identify_address(prog: drgn.Program, addr: drgn.IntegerLike, *, cache: Optional[Dict[Any, Any]] = None) → 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}` (where `hex_offset` is 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:

  - Task structures: `task: {pid} ({comm}) +{hex_offset}` (where `pid` and `comm` identify the task and `hex_offset` is the optional offset from the beginning of the structure).

  - Task stacks: `task stack: {pid} ({comm}) +{hex_offset}` (where `pid` and `comm` identify the task and `hex_offset` is the offset from the beginning of the stack in hexadecimal).

  - Allocated slab objects: `slab object: {slab_cache_name}+{hex_offset}` (where `hex_offset` is the offset from the beginning of the object in hexadecimal).

  - Free slab objects: `free slab object: {slab_cache_name}+{hex_offset}`.

  - Slab objects with SLOB: `unknown slab object`.

  - Page structures: `page: pfn {pfn} +{hex_offset}` (where `pfn` is the page frame number and `hex_offset` is the optional offset from the beginning of the structure).

  - Vmap addresses (e.g., vmalloc, ioremap): `vmap: {hex_start_address}-{hex_end_address}`. If the function that allocated the vmap is known, this also includes `caller {function_name}+{hex_offset}`.

  This may recognize other types of addresses in the future.

  To get more information instead of just a string, use `identify_address_all()`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

    - cache – Opaque cache used to amortize expensive lookups. If you’re going to call this function many times in a short period, create an empty dictionary and pass the same dictionary as cache to each call. Don’t reuse it indefinitely or you may get stale results.

  Returns:

    Identity as string, or `None` if the address is unrecognized.

drgn.helpers.common.memory.identify_address_all(prog: drgn.Program, addr: drgn.IntegerLike, *, cache: Optional[Dict[Any, Any]] = None) → Iterator['IdentifiedAddress']

  Identify everything an address refers to.

  This is a more programmatic variant of `identify_address()` that provides the following additional information:

  - Instead of strings, it yields `IdentifiedAddress` instances which have attributes describing the identity of the address.

  - If the address can be identified in multiple ways, it yields each one. For example, a pointer to a Linux kernel `task_struct` can be identified as both a task and a slab object.

  For all programs, this can yield:

  - `IdentifiedSymbol`

  Additionally, for the Linux kernel, this can yield:

  - `IdentifiedTaskStruct`

  - `IdentifiedTaskStack`

  - `IdentifiedSlabObject`

  - `IdentifiedVmap`

  - `IdentifiedPage`

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

    - cache – Opaque cache used to amortize expensive lookups. If you’re going to call this function many times in a short period, create an empty dictionary and pass the same dictionary as cache to each call. Don’t reuse it indefinitely or you may get stale results.

  Returns:

    Iterator of identities, from most specific to least specific. If the address is unrecognized, this is empty.

class drgn.helpers.common.memory.IdentifiedAddress

  Bases: `Protocol`

  Address that was identified by `identify_address_all()`.

  address: int

    Address passed to `identify_address_all()`.

  __str__() → str

    Get a human-readable description of the identity.

    This is the same string that is returned from `identify_address()`.

        >>> identity
        IdentifiedSymbol(address=18446744071889293504, symbol=Symbol(name='init_task', address=0xffffffff938110c0, size=0x36c0, binding=<SymbolBinding.GLOBAL: 2>, kind=<SymbolKind.OBJECT: 1>))
        >>> str(identity)
        'object symbol: init_task+0x0'

class drgn.helpers.common.memory.IdentifiedSymbol

  `IdentifiedAddress` for an address in the symbol table.

  symbol: drgn.Symbol

    Symbol containing the address.

drgn.helpers.common.memory.print_annotated_memory(prog: drgn.Program, address: drgn.IntegerLike, size: drgn.IntegerLike, physical: bool = False) → None

  Print the contents of a range of memory, annotating values that can be identified.

  Currently, this will identify any addresses in the memory range with `identify_address()`.

  See `print_annotated_stack()` for a similar function that annotates stack traces.

      >>> print_annotated_memory(0xffffffff963eb200, 56)
      ADDRESS           VALUE
      ffffffff963eb200: 00000000000000b8
      ffffffff963eb208: 000000000000a828
      ffffffff963eb210: 0000000000000000
      ffffffff963eb218: ffff8881042948e0 [slab object: mnt_cache+0x20]
      ffffffff963eb220: ffff88810074a540 [slab object: dentry+0x0]
      ffffffff963eb228: ffff8881042948e0 [slab object: mnt_cache+0x20]
      ffffffff963eb230: ffff88810074a540 [slab object: dentry+0x0]

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - address – Starting address.

    - size – Number of bytes to read.

    - physical – Whether address is a physical memory address. If `False`, then it is a virtual memory address.

### Program Decorators

The `drgn.helpers.common.prog` module provides decorators to transparently use the default program argument.

drgn.helpers.common.prog.takes_program_or_default(f: TakesProgram[P, R]) → TakesProgramOrDefault[P, R]

  Wrap a function taking a `Program` so that it uses the default program argument if omitted.

      @takes_program_or_default
      def my_helper(prog: Program, n: IntegerLike) -> Foo:
          ...

      my_helper(1)
      # is equivalent to
      my_helper(get_default_prog(), 1)

      obj = Object(...)
      my_helper(obj)
      # is equivalent to
      my_helper(obj.prog_, obj)

drgn.helpers.common.prog.takes_object_or_program_or_default(f: Callable[Concatenate[drgn.Program, Optional[drgn.Object], P], R]) → TakesObjectOrProgramOrDefault[P, R]

  Wrap a function taking a `Program` and an optional `Object` so that it accepts a `Program` or an `Object` or neither, in which case the default program argument is used.

      @takes_object_or_program_or_default
      def my_helper(prog: Program, obj: Optional[Object], n: IntegerLike) -> Foo:
          ...

      my_helper(prog, 1)
      # is equivalent to
      my_helper.__wrapped__(prog, None, 1)

      obj = Object(...)
      my_helper(obj, 1)
      # is equivalent to
      my_helper.__wrapped__(obj.prog_, obj, 1)

      my_helper(1)
      # is equivalent to
      my_helper.__wrapped__(get_default_prog(), None, 1)

      one_obj = Object(..., 1)
      my_helper(one_obj)
      # is equivalent to
      my_helper.__wrapped__(one_obj.prog_, None, one_obj)

  Warning

  This cannot be used with positional parameters with a default value, as that would create ambiguity. Keyword-only parameters with a default value are OK.

      # NOT ALLOWED
      @takes_object_or_program_or_default
      def my_helper(prog: Program, obj: Optional[Object], foo: str = ""): ...

      # OK
      @takes_object_or_program_or_default
      def my_helper(prog: Program, obj: Optional[Object], *, foo: str = ""): ...

  Note

  The object parameter can be passed as a keyword, but because of limitations of the Python type system, type checkers do not recognize this.

### 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()`.

  See `print_annotated_memory()` for a similar function that annotates arbitrary memory ranges.

      >>> print_annotated_stack(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.

drgn.helpers.common.stack.print_registers(prog: drgn.Program, regs: Dict[str, int], indent: str = ' ') → None

  Print a CPU register dump, in a format similar to that of crash(8)

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - regs – a dictionary of registers, named in a similar way to the dictionary returned by `drgn.StackTrace.registers()`.

    - indent – a string prepended to each line of output

### 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.IntEnum` class from an enumerated `drgn.Type`.

  Parameters:

    - type – Enumerated type to convert.

    - name – Name of the `IntEnum` type 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.

drgn.helpers.common.type.member_at_offset(type: Union[drgn.Type, str], offset: drgn.IntegerLike) → str

  Return the name of the member at an offset in a type.

  This is effectively the opposite of `offsetof()`.

      >>> prog.type("struct list_head")
      struct list_head {
              struct list_head *next;
              struct list_head *prev;
      }
      >>> member_at_offset("struct list_head", 0)
      'next'
      >>> member_at_offset("struct list_head", 8)
      'prev'

  This includes nested structures and array elements:

      >>> prog.type("struct sigpending")
      struct sigpending {
              struct list_head list;
              sigset_t signal;
      }
      >>> prog.type("sigset_t")
      typedef struct {
              unsigned long sig[1];
      } sigset_t
      >>> member_at_offset("struct sigpending", 0)
      'list.next'
      >>> member_at_offset("struct sigpending", 8)
      'list.prev'
      >>> member_at_offset("struct sigpending", 16)
      'signal.sig[0]'

  This also includes all possible matches for a union:

      >>> prog.type("union mc_target")
      union mc_target {
              struct folio *folio;
              swp_entry_t ent;
      }
      >>> prog.type("swp_entry_t")
      typedef struct {
              unsigned long val;
      } swp_entry_t
      >>> member_at_offset("union mc_target", 0)
      'folio or ent.val'

  Offsets in the middle of a member are represented:

      >>> member_at_offset("struct list_head", 4)
      'next+0x4'

  Offsets in padding or past the end of the type are also represented:

      >>> prog.type("struct autogroup")
      struct autogroup {
              struct kref kref;
              struct task_group *tg;
              struct rw_semaphore lock;
              unsigned long id;
              int nice;
      }
      >>> member_at_offset("struct autogroup", 4)
      '<padding between kref and tg>'
      >>> member_at_offset("struct autogroup", 70)
      '<padding at end>'
      >>> member_at_offset("struct autogroup", 72)
      '<end>'
      >>> member_at_offset("struct autogroup", 80)
      '<past end>'

  Parameters:

    - type – Type to check. If given as a string, it is looked up in the default program.

    - offset – Offset in bytes.

  Raises:

    TypeError – if type is not a structure, union, class, or array type (or a typedef of one of those)

drgn.helpers.common.type.typeof_member(type: Union[drgn.Type, str], member: str) → drgn.Type

  Get the type of a member in a `Type`.

  This corresponds to the `typeof_member()` macro used in the Linux kernel and other projects.

  Parameters:

    - type – Structure, union, or class type. If given as a string, it is looked up in the default program.

    - member – Name of member. May include one or more member references and zero or more array subscripts.

  Raises:

    - TypeError – if type is not a structure, union, or class type

    - LookupError – if type does not have a member with the given name

## 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)

### Bitmaps

The `drgn.helpers.linux.bitmap` module provides helpers for working with bitmaps from `include/linux/bitmap.h`.

The following helpers from `drgn.helpers.linux.bitops` also apply to bitmaps:

- `for_each_set_bit()`

- `for_each_clear_bit()`

- `test_bit()`

drgn.helpers.linux.bitmap.bitmap_weight(bitmap: drgn.Object, size: drgn.IntegerLike) → int

  Return the number of set (one) bits in a bitmap

  Parameters:

    - bitmap – `unsigned long *`

    - size – Size of bitmap in bits.

### 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.bdev_partno(bdev: drgn.Object) → drgn.Object

  Get the partition number of a block device.

  Parameters:

    bdev – `struct block_device *`

  Returns:

    `u8`

drgn.helpers.linux.block.for_each_disk(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over all disks in the system.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct gendisk *` objects.

drgn.helpers.linux.block.print_disks(prog: drgn.Program) → None

  Print all of the disks in the system.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.block.part_devt(part: drgn.Object) → drgn.Object

  Get a partition’s device number.

  Parameters:

    part – `struct block_device *` or `struct 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 *` or `struct 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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct block_device *` or `struct 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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.block.nr_blockdev_pages(prog: drgn.Program) → int

  Get the number of memory pages used for block device buffers.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.block.req_op(rq: drgn.Object) → drgn.Object

  Get the operation of a block request.

      >>> req_op(rq)
      (enum req_op)REQ_OP_WRITE

  Parameters:

    rq – `struct request *`

  Returns:

    `enum req_op` (or `enum req_opf` between Linux 4.10 and Linux 6.0)

drgn.helpers.linux.block.op_is_write(op: drgn.Object) → bool

  Return whether a block request operation is a “write”/”data out” operation.

      >>> op_is_write(prog["REQ_OP_READ"])
      False
      >>> op_is_write(prog["REQ_OP_WRITE"])
      True
      >>> op_is_write(prog["REQ_OP_DISCARD"])
      True

  Parameters:

    op – `enum req_op` (or `enum req_opf` between Linux 4.10 and Linux 6.0)

drgn.helpers.linux.block.rq_data_dir(rq: drgn.Object) → int

  Return 1 if a block request is a “write”/”data out” operation and 0 otherwise.

  Parameters:

    rq – `struct request *`

drgn.helpers.linux.block.blk_rq_pos(rq: drgn.Object) → drgn.Object

  Get the current sector of a block request.

  Parameters:

    rq – `struct request *`

  Returns:

    `sector_t`

drgn.helpers.linux.block.blk_rq_bytes(rq: drgn.Object) → drgn.Object

  Get the number of bytes left in a block request.

  Parameters:

    rq – `struct request *`

  Returns:

    `unsigned int`

drgn.helpers.linux.block.blk_mq_rq_to_pdu(rq: drgn.Object) → drgn.Object

  Get the driver command data for a block request.

  Parameters:

    rq – `struct request *`

  Returns:

    `void *`

drgn.helpers.linux.block.blk_mq_rq_from_pdu(pdu: drgn.Object) → drgn.Object

  Get a block request from its driver command data.

  Parameters:

    pdu – `void *`

  Returns:

    `struct request *`

drgn.helpers.linux.block.request_queue_busy_iter(q: drgn.Object, tags: Optional[Literal['driver', 'sched']] = None) → Iterator[drgn.Object]

  Iterate over all busy requests on a block request queue.

  Note

  This does not support the legacy block layer, which was removed in Linux 5.0.

  Parameters:

    - q – `struct request_queue *`

    - tags –

      If `"driver"`, iterate over requests with an allocated driver tag. If `"sched"`, iterate over requests with an allocated scheduler tag. Defaults to `"driver"` if the I/O scheduler is `none` and `"sched"` otherwise.

      Typically, a scheduler tag is allocated when a request is first submitted, then a driver tag is allocated later when the I/O scheduler dispatches the request. Both are freed when the request completes. If the I/O scheduler is `none`, then no scheduler tags are allocated.

      Therefore, the default includes all submitted requests regardless of the I/O scheduler. (For flush operations, `"sched"` will include the original request but not the dedicated flush request; see `block/blk-flush.c`.)

  Returns:

    Iterator of `struct request *` objects.

### 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).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.boot.pgtable_l5_enabled(prog: drgn.Program) → bool

  Return whether 5-level paging is enabled.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

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

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  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 cgroup_bpf_attach_type` (`enum bpf_attach_type` before Linux 5.15)

  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.

drgn.helpers.linux.bpf.bpf_prog_used_maps(bpf_prog: drgn.Object) → Iterator[drgn.Object]

  Yield maps used by a BPF program.

  Parameters:

    bpf_prog – `struct bpf_prog *`

  Returns:

    Iterator of `struct bpf_map *` objects.

drgn.helpers.linux.bpf.bpf_prog_by_id(prog: drgn.Program, id: drgn.IntegerLike) → drgn.Object

  Get a BPF program by ID.

  This is only supported since Linux v4.13.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - prog – Program object

    - id – BPF program ID

  Returns:

    `struct bpf_prog *` object, or a null pointer if not found

drgn.helpers.linux.bpf.bpf_map_by_id(prog: drgn.Program, id: drgn.IntegerLike) → drgn.Object

  Get a BPF map by ID.

  This is only supported since Linux v4.13.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - prog – Program object

    - id – BPF map ID

  Returns:

    `struct bpf_map *` object, or a null pointer if not found

### 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 from `struct 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, `NULL` otherwise.

  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:

    - prog – Program, which may be omitted to use the default program argument.

    - path – Path name.

drgn.helpers.linux.cgroup.css_next_child(pos: drgn.Object, parent: drgn.Object) → drgn.Object

  Get the next child (or `NULL` if there is none) of the given parent starting from the given position (`NULL` to 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 `NULL` if there is none) of the given css root starting from the given position (`NULL` to 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 (offline included) 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 (offline included) in pre-order.

  Parameters:

    css – `struct cgroup_subsys_state *`

  Returns:

    Iterator of `struct cgroup_subsys_state *` objects.

### Common

Linux kernel specializations of `common` helpers.

class drgn.helpers.linux.common.IdentifiedTaskStruct

  `IdentifiedAddress` for an address in a `struct task_struct`.

  task: drgn.Object

    `struct task_struct *` containing the address.

class drgn.helpers.linux.common.IdentifiedTaskStack

  `IdentifiedAddress` for an address in a kernel stack.

  task: drgn.Object

    `struct task_struct *` of the task whose stack contains the address.

class drgn.helpers.linux.common.IdentifiedSlabObject

  `IdentifiedAddress` for an address from the slab allocator.

  slab_object_info: drgn.helpers.linux.slab.SlabObjectInfo

    Information about slab object containing the address.

class drgn.helpers.linux.common.IdentifiedVmap

  `IdentifiedAddress` for an address in a vmap/vmalloc allocation.

  vmap_area: drgn.Object

    `struct vmap_area *` containing the address.

  vm_struct: drgn.Object

    `struct vm_struct *` containing the address.

class drgn.helpers.linux.common.IdentifiedPage

  `IdentifiedAddress` for an address in a `struct page` object.

  page: drgn.Object

    `struct page *` containing the address.

  pfn: int

    Page frame number of the page.

### Completion Variables

The `drgn.helpers.linux.completion` module provides helpers for working with completion variables (`struct completion`) from `include/linux/completion.h`.

drgn.helpers.linux.completion.completion_done(completion: drgn.Object) → bool

  Test if a completion has any waiters.

  Parameters:

    completion – `struct completion *`

drgn.helpers.linux.completion.completion_for_each_task(completion: drgn.Object) → Iterator[drgn.Object]

  Iterate over all tasks waiting on a completion variable.

  Parameters:

    completion – `struct completion *`

  Returns:

    Iterator of `struct task_struct *` 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.cpu_online_mask(prog: drgn.Program) → drgn.Object

  Return the mask of online CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `struct cpumask *`

drgn.helpers.linux.cpumask.cpu_possible_mask(prog: drgn.Program) → drgn.Object

  Return the mask of possible CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `struct cpumask *`

drgn.helpers.linux.cpumask.cpu_present_mask(prog: drgn.Program) → drgn.Object

  Return the mask of present CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `struct cpumask *`

drgn.helpers.linux.cpumask.cpumask_of(prog: drgn.Program, cpu: drgn.IntegerLike) → drgn.Object

  Return a mask containing only the given CPU.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `struct cpumask *`

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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.cpumask.for_each_possible_cpu(prog: drgn.Program) → Iterator[int]

  Iterate over all possible CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.cpumask.for_each_present_cpu(prog: drgn.Program) → Iterator[int]

  Iterate over all present CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.cpumask.cpumask_weight(mask: drgn.Object) → int

  Return the number of CPUs in the given mask

  Parameters:

    mask – `struct cpumask *`

drgn.helpers.linux.cpumask.num_online_cpus(prog: drgn.Program) → int

  Return the number of online CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.cpumask.num_possible_cpus(prog: drgn.Program) → int

  Return the number of possible CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.cpumask.num_present_cpus(prog: drgn.Program) → int

  Return the number of present CPUs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.cpumask.cpumask_to_cpulist(mask: drgn.Object) → str

  Return a CPU mask as a CPU list string.

      >>> cpumask_to_cpulist(mask)
      0-3,8-11

  Parameters:

    mask – `struct cpumask *`

  Returns:

    String in the CPU list format.

### 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_t` object or `int`.

drgn.helpers.linux.device.MINOR(dev: drgn.IntegerLike) → int

  Return the minor ID of a kernel `dev_t`.

  Parameters:

    dev – `dev_t` object or `int`.

drgn.helpers.linux.device.MKDEV(major: drgn.IntegerLike, minor: drgn.IntegerLike) → int

  Return a kernel `dev_t` from the major and minor IDs.

  Parameters:

    - major – Device major ID.

    - minor – Device minor ID.

drgn.helpers.linux.device.dev_name(dev: drgn.Object) → bytes

  Get the name of a device.

  Parameters:

    dev – `struct device *`

drgn.helpers.linux.device.bus_to_subsys(bus: drgn.Object) → drgn.Object

  Get the private data for a device bus.

  Parameters:

    bus – `struct bus_type *`

  Returns:

    `struct subsys_private *`

drgn.helpers.linux.device.bus_for_each_dev(bus: drgn.Object) → Iterable[drgn.Object]

  Iterate over all devices on a bus.

  Parameters:

    bus – `struct bus_type *`

  Returns:

    Iterator of `struct device *` objects.

drgn.helpers.linux.device.class_to_subsys(class_: drgn.Object) → drgn.Object

  Get the private data for a device class.

  Parameters:

    bus – `struct class *`

  Returns:

    `struct subsys_private *`

drgn.helpers.linux.device.class_for_each_device(class_: drgn.Object) → Iterable[drgn.Object]

  Iterate over all devices of a class.

  Parameters:

    bus – `struct class *`

  Returns:

    Iterator of `struct device *` objects.

drgn.helpers.linux.device.for_each_registered_chrdev(prog: drgn.Program) → Iterator[Tuple[int, int, bytes, drgn.Object]]

  Iterate over all registered character device number ranges.

  Character device numbers are reserved in ranges, so this returns the first `dev_t` value (which includes a major and minor ID) and the size of the range (i.e., the number of consecutive minor IDs starting from the first `dev_t`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of (first device number, number of consecutive minor IDs, name, `struct cdev *` object) tuples. The `struct cdev *` may be `NULL`.

drgn.helpers.linux.device.for_each_registered_blkdev(prog: drgn.Program) → Iterator[Tuple[int, bytes, drgn.Object]]

  Iterate over all registered block device numbers.

  Block device numbers are reserved by major ID.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of (major ID, name, `struct blk_major_name *` object) tuples.

### 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(root: Union[drgn.Object, drgn.Program], path: drgn.Path, *, allow_negative: bool = False) → drgn.Object

  Look up the given path name.

  Parameters:

    - root – `struct path *` to use as the root directory. Defaults to the initial root filesystem if given a `Program` or omitted.

    - 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('/usr/include/stdlib.h')
      ...
      Exception: could not find '/usr/include/stdlib.h' in dcache
      >>> open('/usr/include/stdlib.h').close()
      >>> path_lookup('/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 path` or `struct 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.d_path(dentry: drgn.Object) → bytes

  Return the full path of a dentry.

  Since a mount is not provided, this arbitrarily selects a mount to determine the path.

  Parameters:

    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 `None` if 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.inode_for_each_page(inode: drgn.Object) → Iterator[Tuple[int, drgn.Object]]

  Iterate over all cached pages and their indices in an inode.

      >>> for index, page in inode_for_each_page(inode):
      ...     print(index, hex(page))
      ...
      0 0xffffcfde4d0b6b00
      1 0xffffcfde4d0bda40
      3 0xffffcfde4d0b8b80

  Parameters:

    inode – `struct inode *`

  Returns:

    Iterator of (index, `struct page *` object) tuples.

drgn.helpers.linux.fs.address_space_for_each_page(mapping: drgn.Object) → Iterator[Tuple[int, drgn.Object]]

  Iterate over all cached pages and their indices in an inode address space.

  Parameters:

    mapping – `struct address_space *`

  Returns:

    Iterator of (index, `struct page *` object) tuples.

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(ns: Union[drgn.Object, drgn.Program], *, 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:

    - ns – `struct mnt_namespace *`. Defaults to the initial mount namespace if given a `Program` or omitted.

    - 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.super_block_for_each_mount(sb: drgn.Object) → Iterator[drgn.Object]

  Iterate over every mount of a super block.

  Parameters:

    sb – `struct super_block *`.

  Returns:

    Iterator of `struct mount *` objects.

drgn.helpers.linux.fs.print_mounts(ns: Union[drgn.Object, drgn.Program], *, 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/mounts` but prints the value of each `struct 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 *`

drgn.helpers.linux.fs.decode_file_type(mode: drgn.IntegerLike) → str

  Convert a file mode to a human-readable file type string.

  Parameters:

    mode – File mode (e.g., `struct inode::i_mode` or `os.stat_result.st_mode`).

  Returns:

    File type as a string (e.g., “REG”, “DIR”, “CHR”, etc.), or a raw octal value if unknown.

### HugeTLB

The `drgn.helpers.linux.hugetlb` module provides helpers for working with HugeTLB pages.

drgn.helpers.linux.hugetlb.for_each_hstate(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over all HugeTLB page size states.

      >>> [h.name.string_() for h in for_each_hstate()]
      [b'hugepages-1048576kB', b'hugepages-2048kB']

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct hstate *` objects.

drgn.helpers.linux.hugetlb.huge_page_size(hstate: drgn.Object) → drgn.Object

  Return the size of a HugeTLB state in bytes.

  Parameters:

    hstate – `struct hstate *`

  Returns:

    `unsigned long`

drgn.helpers.linux.hugetlb.hugetlb_total_pages(prog: drgn.Program) → int

  Get the total number of HugeTLB pages (in `PAGE_SIZE` units).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.hugetlb.hugetlb_total_usage(prog: drgn.Program) → drgn.helpers.linux.mm.PageUsage

  Get the total number of HugeTLB pages and the number of free HugeTLB pages (in `PAGE_SIZE` units).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

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

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, or `NULL` if not found.

drgn.helpers.linux.idr.idr_for_each(idr: drgn.Object) → Iterator[Tuple[int, drgn.Object]]

  Iterate over all of the pointers in an IDR.

  Parameters:

    idr – `struct idr *`

  Returns:

    Iterator of (index, `void *`) tuples.

drgn.helpers.linux.idr.idr_for_each_entry(idr: drgn.Object, type: Union[str, drgn.Type]) → Iterator[Tuple[int, drgn.Object]]

  Iterate over all of the entries with the given type in an IDR.

  Parameters:

    - idr – `struct idr *`

    - type – Entry type.

  Returns:

    Iterator of (index, `type *`) tuples.

### I/O Resources

The `drgn.helpers.linux.ioport` module provides helpers for working with I/O resources.

drgn.helpers.linux.ioport.for_each_resource(root: drgn.Object) → Iterator[drgn.Object]

  Iterate over all I/O resources starting from the given root resource.

  Parameters:

    root – `struct resource *`

  Returns:

    Iterator of `struct resource *` objects.

### Interprocess Communication

The `drgn.helpers.linux.ipc` module provides helpers for working with System V interprocess communication mechanisms.

drgn.helpers.linux.ipc.for_each_sysv_msg_queue(ns: drgn.Object | drgn.Program) → Iterator[drgn.Object]

  Iterate over all System V message queues in a namespace.

  Parameters:

    ns – `struct ipc_namespace *`. Defaults to the initial IPC namespace if given a `Program` or omitted.

  Returns:

    Iterator of `struct msg_queue *` objects.

drgn.helpers.linux.ipc.find_sysv_msg_queue(ns: drgn.Object | drgn.Program, id: drgn.IntegerLike) → drgn.Object

  Find a System V message queue by ID.

  Parameters:

    - ns – `struct ipc_namespace *`. Defaults to the initial IPC namespace if given a `Program` or omitted.

    - id – Message queue identifier.

  Returns:

    `struct msg_queue *` (`NULL` if not found)

drgn.helpers.linux.ipc.for_each_sysv_shm(ns: drgn.Object | drgn.Program) → Iterator[drgn.Object]

  Iterate over all System V shared memory segments in a namespace.

  Parameters:

    ns – `struct ipc_namespace *`. Defaults to the initial IPC namespace if given a `Program` or omitted.

  Returns:

    Iterator of `struct shmid_kernel *` objects.

drgn.helpers.linux.ipc.find_sysv_shm(ns: drgn.Object | drgn.Program, id: drgn.IntegerLike) → drgn.Object

  Find a System V shared memory segment by ID.

  Parameters:

    - ns – `struct ipc_namespace *`. Defaults to the initial IPC namespace if given a `Program` or omitted.

    - id – Shared memory segment identifier.

  Returns:

    `struct shmid_kernel *` (`NULL` if not found)

drgn.helpers.linux.ipc.decode_sysv_shm_flags(shm: drgn.Object) → str

  Get a human-readable representation of the flags set on a System V shared memory segment.

      >>> decode_sysv_shm_flags(shm)
      'SHM_LOCKED'

  Parameters:

    shm – `struct shmid_kernel *`

drgn.helpers.linux.ipc.decode_sysv_shm_mode_flags(prog: drgn.Program, value: drgn.IntegerLike) → str

  Get a human-readable representation of the flags in the `mode` value of a System V shared memory segment.

      >>> decode_sysv_shm_mode_flags(0o2777)
      'SHM_LOCKED'

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - mode – `umode_t`

drgn.helpers.linux.ipc.for_each_sysv_sem_array(ns: drgn.Object | drgn.Program) → Iterator[drgn.Object]

  Iterate over all System V semaphore arrays in a namespace.

  Parameters:

    ns – `struct ipc_namespace *`. Defaults to the initial IPC namespace if given a `Program` or omitted.

  Returns:

    Iterator of `struct sem_array *` objects.

drgn.helpers.linux.ipc.find_sysv_sem_array(ns: drgn.Object | drgn.Program, id: drgn.IntegerLike) → drgn.Object

  Find a System V semaphore array by ID.

  Parameters:

    - ns – `struct ipc_namespace *`. Defaults to the initial IPC namespace if given a `Program` or omitted.

    - id – Semaphore array identifier.

  Returns:

    `struct sem_array *` (`NULL` if not found)

### Interrupts

The `drgn.helpers.linux.irq` module provides helpers for working with IRQs and interrupt descriptors.

drgn.helpers.linux.irq.irq_to_desc(prog: drgn.Program, irq: drgn.IntegerLike) → drgn.Object

  Get the interrupt descriptor for an IRQ number.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - irq – IRQ number.

  Returns:

    `struct irq_desc *` (`NULL` if not found)

drgn.helpers.linux.irq.for_each_irq_desc(prog: drgn.Program) → Iterator[Tuple[int, drgn.Object]]

  Iterate over all allocated interrupt descriptors.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of (IRQ number, `struct irq_desc *` object) tuples.

drgn.helpers.linux.irq.irq_desc_affinity_mask(desc: drgn.Object) → drgn.Object

  Get the CPU affinity mask for an interrupt descriptor.

  Parameters:

    desc – `struct irq_desc *`

  Returns:

    `struct cpumask *`

drgn.helpers.linux.irq.irq_desc_action_names(desc: drgn.Object) → List[bytes]

  Get a list of the names of actions set on an interrupt descriptor.

  Actions without names (e.g., `chained_action`) are skipped.

      >>> irq_desc_action_names(irq_to_desc(27))
      [b'i2c_designware.0', b'idma64.0']

  Parameters:

    desc – `struct irq_desc *`

drgn.helpers.linux.irq.irq_desc_chip_name(desc: drgn.Object) → Optional[bytes]

  Get the name of the controller chip that manages an interrupt descriptor.

  Parameters:

    desc – `struct irq_desc *`

  Returns:

    Chip name, or `None` if the chip or name is not set.

drgn.helpers.linux.irq.irq_desc_kstat_cpu(desc: drgn.Object, cpu: drgn.IntegerLike) → int

  Get the number of times that an interrupt has fired on a given CPU.

  Parameters:

    - desc – `struct irq_desc *`

    - cpu – CPU number.

drgn.helpers.linux.irq.gate_desc_func(gate: drgn.Object) → drgn.Object

  Get the IDT entry function for a gate on x86.

      >>> gate_desc_func(prog["idt_table"][3])
      (void *)asm_exc_int3+0x0 = 0xffffffff91001240

  Parameters:

    gate – `gate_desc` or `gate_desc *`

  Returns:

    `void *`

### Kallsyms

The `drgn.helpers.linux.kallsyms` module contains helpers which allow you to use the built-in kallsyms symbol table for drgn symbol lookup. Combined with an alternative type information source, this can enable debugging Linux kernel core dumps without the corresponding DWARF debuginfo files. Even without type information, kallsyms can be used to help locate objects, and drgn’s low-level memory reading functions can be used to do basic debugging tasks.

drgn.helpers.linux.kallsyms.load_vmlinux_kallsyms(prog: drgn.Program) → drgn.SymbolIndex

  Create a kallsyms index for vmlinux

  This function loads the kallsyms for the core kernel and returns a symbol index. This function does not require that any debuginfo is loaded for the kernel: it either relies on `/proc/kallsyms` (which requires running drgn as root) or it parses internal data structures using information found from the VMCOREINFO note (which requires Linux 6.0 or later, or a backport of commit `f09bddbd86619 ("vmcoreinfo: add kallsyms_num_syms symbol")` and its dependencies).

  Returns:

    a symbol index containing kallsyms for the core kernel (vmlinux)

drgn.helpers.linux.kallsyms.load_module_kallsyms(prog: drgn.Program) → drgn.SymbolIndex

  Return a symbol index containing all module symbols from kallsyms

  For kernels built with `CONFIG_KALLSYMS`, loaded kernel modules contain an ELF symbol table in kernel memory. This function can parse those data structures and create a symbol index usable by drgn. However, it requires that you already have debuginfo for the vmlinux image.

  Returns:

    a symbol index containing all symbols from module kallsyms

drgn.helpers.linux.kallsyms.module_kallsyms(module: drgn.Object) → List[drgn.Symbol]

  Get the list of symbols from a kernel module’s kallsyms data.

  The kernel must be configured with `CONFIG_KALLSYMS`, and debugging symbols for the main kernel image must already be loaded.

  Parameters:

    module – `struct module *`

### 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()['CONFIG_SMP']
      'y'
      >>> get_kconfig()['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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

### 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_root(kn: drgn.Object) → drgn.Object

  Get the kernfs root that the given kernfs node belongs to.

  Parameters:

    kn – `struct kernfs_node *`

  Returns:

    `struct kernfs_root *`

drgn.helpers.linux.kernfs.kernfs_parent(kn: drgn.Object) → drgn.Object

  Get the parent of the given kernfs node.

  Parameters:

    kn – `struct kernfs_node *`

  Returns:

    `struct kernfs_node *`

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, follow_symlinks: bool = True) → drgn.Object

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

  Parameters:

    - parent – `struct kernfs_node *`

    - path – Path name.

    - follow_symlinks – If True (default), all symbolic links encountered in the path, including the final component, are followed and the function returns the target node. If False, all intermediate symlinks are still followed, but if the final component is a symlink, the function returns the symlink node itself rather than its target.

  Returns:

    `struct kernfs_node *` (`NULL` if not found)

drgn.helpers.linux.kernfs.kernfs_children(kn: drgn.Object) → Iterator[drgn.Object]

  Get an iterator over the children of the given kernfs node.

  Parameters:

    kn – `struct kernfs_node *`

  Returns:

    Iterator of `struct kernfs_node *` objects.

  Raises:

    ValueError – if the kernfs node is not a directory

### Kernel Threads

The `drgn.helpers.linux.kthread` module provides helpers for working with Linux kernel threads, a.k.a. kthreads.

drgn.helpers.linux.kthread.to_kthread(task: drgn.Object) → drgn.Object

  Get the kthread information for a task.

      >>> to_kthread(find_task(3))
      *(struct kthread *)0xffff8ef600191580 = {
              ...
              .threadfn = (int (*)(void *))kthread_worker_fn+0x0 = 0xffffffffba1e61b0,
              .full_name = (char *)0xffff8ef6003d4ac0 = "pool_workqueue_release",
      }

  Parameters:

    task – `struct task *`

  Returns:

    `struct kthread *`

drgn.helpers.linux.kthread.kthread_data(task: drgn.Object) → drgn.Object

  Get the data that was specified when a kthread was created.

      >>> kthread_data(find_task(3))
      (void *)0xffff8ef6001812c0

  Parameters:

    task – `struct task *`

  Returns:

    `void *`

drgn.helpers.linux.kthread.task_is_kthread(task: drgn.Object) → bool

  Return whether a task is a kernel thread.

  Parameters:

    task – `struct task_struct *`

### 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_count_nodes(head: drgn.Object) → int

  Return the number of nodes in a list.

  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 `NULL` if 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 `next` and `prev` pointers in a list are consistent and that the list does not contain any cycles.

      >>> validate_list(prog["my_list"].address_of_())
      drgn.helpers.ValidationError: (struct list_head *)0xffffffffc029e460 next 0xffffffffc029e000 has prev 0xffffffffc029e450

  Parameters:

    head – `struct list_head *`

  Raises:

    ValidationError – if the list is invalid

drgn.helpers.linux.list.validate_list_count_nodes(head: drgn.Object) → int

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

  Parameters:

    head – `struct list_head *`

drgn.helpers.linux.list.validate_list_for_each(head: drgn.Object) → Iterator[drgn.Object]

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

  Note that this may yield duplicate nodes before a cycle is detected.

  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 like `validate_list()` while iterating.

  Note that this may yield duplicate entries before a cycle is detected.

      def validate_my_list(prog):
           for entry in validate_list_for_each_entry(
               "struct my_entry",
               prog["my_list"].address_of_(),
               "list",
           ):
               if entry.value < 0:
                   raise ValidationError("list contains negative entry")

  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_node` member 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 `NULL` if the llist is empty.

  See also `llist_first_entry()`.

  Parameters:

    - head – `struct llist_head *`

    - type – Entry type.

    - member – Name of `struct llist_node` member 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_node` member 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_node` member in entry type.

  Returns:

    Iterator of `type *` objects.

### Locking

The `drgn.helpers.linux.locking` module provides helpers for inspecting locks, including mutexes and read-write semaphores.

drgn.helpers.linux.locking.mutex_owner(lock: drgn.Object) → drgn.Object

  Get the task that currently owns a mutex.

  Before Linux 4.10, this is only supported when `CONFIG_DEBUG_MUTEXES` or `CONFIG_MUTEX_SPIN_ON_OWNER` are enabled.

  Parameters:

    lock – `struct mutex *`

  Returns:

    `struct task_struct *`

drgn.helpers.linux.locking.rwsem_locked(sem: drgn.Object) → RwsemLocked

  Return whether a read-write semaphore is unlocked, read-locked, or write-locked.

  Before Linux 5.3, this is only supported when `CONFIG_RWSEM_SPIN_ON_OWNER` is enabled.

  Parameters:

    sem – `struct rw_semaphore *`

class drgn.helpers.linux.locking.RwsemLocked

  Bases: `enum.Enum`

  Locked status of a read-write semaphore.

  UNLOCKED
  READ_LOCKED
  WRITE_LOCKED

drgn.helpers.linux.locking.rwsem_owner(sem: drgn.Object) → drgn.Object

  Get the task that currently owns a read-write semaphore.

  Warning

  Due to the kernel implementation, unless the semaphore is currently write-locked, then this is not totally reliable.

  It may return `NULL` when the semaphore is read-locked (specifically, when the last task to read-lock the semaphore unlocks it and `CONFIG_DEBUG_RWSEMS` or `CONFIG_DETECT_HUNG_TASK_BLOCKER` are enabled, or before Linux 4.20).

  It may also return a previous reader that no longer owns the semaphore when it is read-locked or unlocked (although an effort is made to avoid this when `CONFIG_DEBUG_RWSEMS` or `CONFIG_DETECT_HUNG_TASK_BLOCKER` are enabled unless `up_read_non_owner()` is used).

  Before Linux 5.3, this is only supported when `CONFIG_RWSEM_SPIN_ON_OWNER` is enabled.

  Parameters:

    sem – `struct rw_semaphore *`

  Returns:

    `struct task_struct *`

### Maple Trees

The `drgn.helpers.linux.mapletree` module provides helpers for working with maple trees from `include/linux/maple_tree.h`.

Maple trees were introduced in Linux 6.1.

drgn.helpers.linux.mapletree.mtree_load(mt: drgn.Object, index: drgn.IntegerLike, *, advanced: bool = False) → drgn.Object

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

      >>> entry = mtree_load(task.mm.mm_mt.address_of_(), 0x55d65cfaa000)
      >>> cast("struct vm_area_struct *", entry)
      *(struct vm_area_struct *)0xffff97ad82bfc930 = {
          ...
      }

  Parameters:

    - mt – `struct maple_tree *`

    - index – Entry index.

    - advanced – Whether to return nodes only visible to the maple tree advanced API. If `False`, zero entries (see `xa_is_zero()`) will be returned as `NULL`.

  Returns:

    `void *` found entry, or `NULL` if not found.

drgn.helpers.linux.mapletree.mt_for_each(mt: drgn.Object, *, advanced: bool = False) → Iterator[Tuple[int, int, drgn.Object]]

  Iterate over all of the entries and their ranges in a maple tree.

      >>> for first_index, last_index, entry in mt_for_each(task.mm.mm_mt.address_of_()):
      ...     print(hex(first_index), hex(last_index), entry)
      ...
      0x55d65cfaa000 0x55d65cfaafff (void *)0xffff97ad82bfc930
      0x55d65cfab000 0x55d65cfabfff (void *)0xffff97ad82bfc0a8
      0x55d65cfac000 0x55d65cfacfff (void *)0xffff97ad82bfc000
      0x55d65cfad000 0x55d65cfadfff (void *)0xffff97ad82bfcb28
      ...

  Parameters:

    - mt – `struct maple_tree *`

    - advanced – Whether to return nodes only visible to the maple tree advanced API. If `False`, zero entries (see `xa_is_zero()`) will be skipped.

  Returns:

    Iterator of (first_index, last_index, `void *`) tuples. Both indices are inclusive.

### Memory Management

The `drgn.helpers.linux.mm` module provides helpers for working with the Linux memory management (MM) subsystem.

Helpers that translate virtual addresses or read virtual memory may fail for multiple reasons:

1. If the address is invalid.

2. If the address is swapped or paged out.

3. If the address is in high memory. High memory is only used for userspace memory by 32-bit systems with a lot of physical memory, and only if `CONFIG_HIGHMEM` is enabled.

   3a. If the page table is in high memory. This is only possible if `CONFIG_HIGHPTE` is enabled.

drgn.helpers.linux.mm.page_flags(page: drgn.Object) → drgn.Object

  Return a page’s flags.

  This handles kernel versions before and after the page flags were moved to memdesc_flags_t.

  Parameters:

    page – `struct page *`

  Returns:

    `unsigned long`

drgn.helpers.linux.mm.page_index(page: drgn.Object) → drgn.Object

  Return a page’s offset (in pages) within its mapping.

  Parameters:

    page – `struct page *`

  Returns:

    `pgoff_t`

drgn.helpers.linux.mm.PageActive(page: drgn.Object) → bool

  Return whether the `PG_active` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageChecked(page: drgn.Object) → bool

  Return whether the `PG_checked` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageDirty(page: drgn.Object) → bool

  Return whether the `PG_dirty` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageDoubleMap(page: drgn.Object) → bool

  Return whether the `PG_double_map` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageError(page: drgn.Object) → bool

  Return whether the `PG_error` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageForeign(page: drgn.Object) → bool

  Return whether the `PG_foreign` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageHWPoison(page: drgn.Object) → bool

  Return whether the `PG_hwpoison` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageHasHWPoisoned(page: drgn.Object) → bool

  Return whether the `PG_has_hwpoisoned` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageIdle(page: drgn.Object) → bool

  Return whether the `PG_idle` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageIsolated(page: drgn.Object) → bool

  Return whether the `PG_isolated` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageLRU(page: drgn.Object) → bool

  Return whether the `PG_lru` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageLocked(page: drgn.Object) → bool

  Return whether the `PG_locked` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageMappedToDisk(page: drgn.Object) → bool

  Return whether the `PG_mappedtodisk` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageMlocked(page: drgn.Object) → bool

  Return whether the `PG_mlocked` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageOwnerPriv1(page: drgn.Object) → bool

  Return whether the `PG_owner_priv_1` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PagePinned(page: drgn.Object) → bool

  Return whether the `PG_pinned` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PagePrivate(page: drgn.Object) → bool

  Return whether the `PG_private` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PagePrivate2(page: drgn.Object) → bool

  Return whether the `PG_private_2` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageReadahead(page: drgn.Object) → bool

  Return whether the `PG_readahead` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageReclaim(page: drgn.Object) → bool

  Return whether the `PG_reclaim` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageReferenced(page: drgn.Object) → bool

  Return whether the `PG_referenced` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageReported(page: drgn.Object) → bool

  Return whether the `PG_reported` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageReserved(page: drgn.Object) → bool

  Return whether the `PG_reserved` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageSavePinned(page: drgn.Object) → bool

  Return whether the `PG_savepinned` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageSkipKASanPoison(page: drgn.Object) → bool

  Return whether the `PG_skip_kasan_poison` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageSlobFree(page: drgn.Object) → bool

  Return whether the `PG_slob_free` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageSwapBacked(page: drgn.Object) → bool

  Return whether the `PG_swapbacked` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageUncached(page: drgn.Object) → bool

  Return whether the `PG_uncached` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageUnevictable(page: drgn.Object) → bool

  Return whether the `PG_unevictable` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageUptodate(page: drgn.Object) → bool

  Return whether the `PG_uptodate` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageVmemmapSelfHosted(page: drgn.Object) → bool

  Return whether the `PG_vmemmap_self_hosted` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageWaiters(page: drgn.Object) → bool

  Return whether the `PG_waiters` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageWorkingset(page: drgn.Object) → bool

  Return whether the `PG_workingset` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageWriteback(page: drgn.Object) → bool

  Return whether the `PG_writeback` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageXenRemapped(page: drgn.Object) → bool

  Return whether the `PG_xen_remapped` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageYoung(page: drgn.Object) → bool

  Return whether the `PG_young` flag is set on a page.

  Parameters:

    page – `struct page *`

drgn.helpers.linux.mm.PageSlab(page: drgn.Object) → bool

  Return whether a page belongs to the slab allocator.

  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.decode_page_flags_value(prog: drgn.Program, flags: drgn.IntegerLike) → str

  Get a human-readable representation of the flags value from a page.

      >>> flags = page_flags(page).read_()
      >>> hex(flags)
      0xfffffd0004028
      >>> decode_page_flags_value(flags)
      'PG_uptodate|PG_lru|PG_private|PG_reported'

  See also the `decode_page_flags()` shortcut, which takes a `struct page *` instead.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - flags – `unsigned long`

drgn.helpers.linux.mm.for_each_page(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over every valid `struct page *`.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct page *` objects.

drgn.helpers.linux.mm.for_each_valid_pfn_and_page(prog: drgn.Program) → Iterator[Tuple[int, drgn.Object]]

  Iterate over every valid page frame number (PFN) and `struct page *`.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of (`pfn`, `struct page *`) tuples.

drgn.helpers.linux.mm.for_each_valid_page_range(prog: drgn.Program) → Iterator[Tuple[int, int, drgn.Object]]

  Iterate over every contiguous range of valid page frame numbers and `struct page`s.

      >>> for start_pfn, end_pfn, mem_map in for_each_valid_page():
      ...     pages = mem_map[start_pfn:end_pfn]

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of (`start_pfn`, `end_pfn`, `mem_map`) tuples. `start_pfn` is the minimum page frame number (PFN) in the range (inclusive). `end_pfn` is the maximum PFN in the range (exclusive). `mem_map` is a `struct page *` object such that `mem_map[pfn]` is the `struct page` for the given PFN.

drgn.helpers.linux.mm.PFN_PHYS(prog: drgn.Program, pfn: drgn.IntegerLike) → drgn.Object

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

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - pfn – `unsigned long`

  Returns:

    `phys_addr_t`

drgn.helpers.linux.mm.PHYS_PFN(prog: drgn.Program, addr: drgn.IntegerLike) → drgn.Object

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

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - 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(prog: drgn.Program, pfn: drgn.IntegerLike) → drgn.Object

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

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - pfn – `unsigned long`

  Returns:

    `struct page *`

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

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - pfn – `unsigned long`

  Returns:

    `void *`

drgn.helpers.linux.mm.phys_to_page(prog: drgn.Program, addr: drgn.IntegerLike) → drgn.Object

  Get the page containing a physical address.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `phys_addr_t`

  Returns:

    `struct page *`

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.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `phys_addr_t`

  Returns:

    `void *`

drgn.helpers.linux.mm.virt_to_page(prog: drgn.Program, addr: drgn.IntegerLike) → drgn.Object

  Get the page containing a directly mapped virtual address.

  Note

  This only works for virtual addresses from the “direct map”. This includes address from:

  - kmalloc

  - Slab allocator

  - Page allocator

  But not:

  - vmalloc

  - vmap

  - ioremap

  - Symbols (function pointers, global variables)

  For vmalloc or vmap addresses, use `vmalloc_to_page(addr)`. For arbitrary kernel addresses, use `follow_page(prog["init_mm"].address_of_(), addr)`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

  Returns:

    `struct page *`

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.

  Note

  This only works for virtual addresses from the “direct map”. For vmalloc or vmap addresses, use `vmalloc_to_pfn(addr)`. For arbitrary kernel addresses, use `follow_pfn(prog["init_mm"].address_of_(), addr)`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

  Returns:

    `unsigned long`

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.

  Note

  This only works for virtual addresses from the “direct map”. For arbitrary kernel addresses, use `follow_phys(prog["init_mm"].address_of_(), addr)`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

  Returns:

    `phys_addr_t`

drgn.helpers.linux.mm.follow_page(mm: drgn.Object, addr: drgn.IntegerLike) → drgn.Object

  Get the page that a virtual address maps to in a virtual address space.

      >>> task = find_task(113)
      >>> follow_page(task.mm, 0x7fffbbb6d4d0)
      *(struct page *)0xffffbe4bc0337b80 = {
          ...
      }

  Parameters:

    - mm – `struct mm_struct *`

    - addr – `void *`

  Returns:

    `struct page *`

  Raises:

    - FaultError – if the virtual address cannot be translated

    - NotImplementedError – if virtual address translation is not supported for this architecture yet

drgn.helpers.linux.mm.follow_pfn(mm: drgn.Object, addr: drgn.IntegerLike) → drgn.Object

  Get the page frame number (PFN) that a virtual address maps to in a virtual address space.

      >>> task = find_task(113)
      >>> follow_pfn(task.mm, 0x7fffbbb6d4d0)
      (unsigned long)52718

  Parameters:

    - mm – `struct mm_struct *`

    - addr – `void *`

  Returns:

    `unsigned long`

  Raises:

    - FaultError – if the virtual address cannot be translated

    - NotImplementedError – if virtual address translation is not supported for this architecture yet

drgn.helpers.linux.mm.follow_phys(mm: drgn.Object, addr: drgn.IntegerLike) → drgn.Object

  Get the physical address that a virtual address maps to in a virtual address space.

      >>> task = find_task(113)
      >>> follow_phys(task.mm, 0x7fffbbb6d4d0)
      (phys_addr_t)215934160

  Parameters:

    - mm – `struct mm_struct *`

    - addr – `void *`

  Returns:

    `phys_addr_t`

  Raises:

    - FaultError – if the virtual address cannot be translated

    - NotImplementedError – if virtual address translation is not supported for this architecture yet

drgn.helpers.linux.mm.vmalloc_to_page(prog: drgn.Program, addr: drgn.IntegerLike) → drgn.Object

  Get the page containing a vmalloc or vmap address.

      >>> task = find_task(113)
      >>> vmalloc_to_page(task.stack)
      *(struct page *)0xffffbe4bc00a2200 = {
          ...
      }

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

  Returns:

    `struct page *`

drgn.helpers.linux.mm.vmalloc_to_pfn(prog: drgn.Program, addr: drgn.IntegerLike) → drgn.Object

  Get the page frame number (PFN) containing a vmalloc or vmap address.

      >>> task = find_task(113)
      >>> vmalloc_to_pfn(task.stack)
      (unsigned long)10376

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

  Returns:

    `unsigned long`

drgn.helpers.linux.mm.find_vmap_area(prog: drgn.Program, addr: drgn.IntegerLike) → drgn.Object

  Return the `struct vmap_area *` containing an address.

      >>> find_vmap_area(0xffffa2b680081000)
      *(struct vmap_area *)0xffffa16541046b40 = {
              ...
      }

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – Address to look up.

  Returns:

    `struct vmap_area *` (`NULL` if not found)

drgn.helpers.linux.mm.for_each_vmap_area(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over every `struct vmap_area *` on the system.

      >>> for va in for_each_vmap_area():
      ...     caller = ""
      ...     if va.vm:
      ...         try:
      ...             sym = prog.symbol(va.vm.caller)
      ...         except LookupError:
      ...             pass
      ...         else:
      ...             caller = f" {sym.name}"
      ...     print(f"{hex(va.va_start)}-{hex(va.va_end)}{caller}")
      ...
      0xffffa2b680000000-0xffffa2b680005000 irq_init_percpu_irqstack
      0xffffa2b680005000-0xffffa2b680007000 acpi_os_map_iomem
      0xffffa2b68000b000-0xffffa2b68000d000 hpet_enable
      0xffffa2b680080000-0xffffa2b680085000 kernel_clone
      ...

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct vmap_area *` objects.

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(1490152)
      >>> access_process_vm(task, 0x7f8a62b56da0, 12)
      b'hello, world'

  Parameters:

    - task – `struct task_struct *`

    - address – Starting address.

    - size – Number of bytes to read.

  Raises:

    - FaultError – if the virtual address cannot be translated

    - NotImplementedError – if virtual address translation is not supported for this architecture yet

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 a `struct mm_struct *` instead of a `struct task_struct *`.

      >>> task = find_task(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.

  Raises:

    - FaultError – if the virtual address cannot be translated

    - NotImplementedError – if virtual address translation is not supported for this architecture yet

drgn.helpers.linux.mm.cmdline(task: drgn.Object) → Optional[List[bytes]]

  Get the list of command line arguments of a task, or `None` for kernel tasks.

      >>> cmdline(find_task(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 *`

  Raises:

    - FaultError – if the virtual address containing the command line cannot be translated

    - NotImplementedError – if virtual address translation is not supported for this architecture yet

drgn.helpers.linux.mm.mm_cmdline(mm: drgn.Object) → List[bytes]

  Like `cmdline()`, but takes a (non-`NULL`) `struct mm_struct *` instead of a `struct task_struct *`.

  Parameters:

    mm – `struct mm_struct *`

drgn.helpers.linux.mm.environ(task: drgn.Object) → Optional[List[bytes]]

  Get the list of environment variables of a task, or `None` for kernel tasks.

      >>> environ(find_task(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 *`

  Raises:

    - FaultError – if the virtual address containing the environment cannot be translated

    - NotImplementedError – if virtual address translation is not supported for this architecture yet

drgn.helpers.linux.mm.mm_environ(mm: drgn.Object) → List[bytes]

  Like `environ()`, but takes a (non-`NULL`) `struct mm_struct *` instead of a `struct task_struct *`.

  Parameters:

    mm – `struct mm_struct *`

drgn.helpers.linux.mm.vma_find(mm: drgn.Object, addr: drgn.IntegerLike) → drgn.Object

  Return the virtual memory area (VMA) containing an address.

  Parameters:

    - mm – `struct mm_struct *`

    - addr – Address to look up.

  Returns:

    `struct vm_area_struct *` (`NULL` if not found)

drgn.helpers.linux.mm.vma_name(vma: drgn.Object) → bytes

  Get the display name or file path for a Virtual Memory Area (VMA).

  This helper returns a human-readable label for a given `struct vm_area_struct *` object, describing what type of memory region it represents. It mimics the VMA naming behavior seen in `/proc/<pid>/maps`.

  Parameters:

    vma – `struct vm_area_struct *`

  Returns:

    File path or descriptive name of the VMA region. Possible return values include:

    - File path (e.g., `b"/usr/lib/libc.so.6"`): For VMAs backed by files (`vma->vm_file` non-NULL).

    - `b"[heap]"`: Heap segment, between `mm->start_brk` and `mm->brk`.

    - `b"[stack]"`: Stack segment containing `mm->start_stack`.

    - `b"[vdso]"`: Virtual Dynamic Shared Object area (`mm->context.vdso`).

    - `b"[vvar]"`, `b"[vsyscall]"`, etc.: Architecture-specific special mappings from `vm_ops->name`.

    - `b"[anon:<name>]"`: private anonymous memory with a name set by PR_SET_VMA_ANON_NAME.

    - `b"[anon_shmem:<name>]"`: shared memory with a name set by PR_SET_VMA_ANON_NAME.

    - Empty string: anonymous memory.

drgn.helpers.linux.mm.for_each_vma(mm: drgn.Object) → Iterator[drgn.Object]

  Iterate over every virtual memory area (VMA) in a virtual address space.

      >>> for vma in for_each_vma(task.mm):
      ...     print(vma)
      ...
      *(struct vm_area_struct *)0xffff97ad82bfc930 = {
          ...
      }
      *(struct vm_area_struct *)0xffff97ad82bfc0a8 = {
          ...
      }
      ...

  Parameters:

    mm – `struct mm_struct *`

  Returns:

    Iterator of `struct vm_area_struct *` objects.

drgn.helpers.linux.mm.totalram_pages(prog: drgn.Program) → int

  Return the total number of RAM pages.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.mm.vm_commit_limit(prog: drgn.Program) → int

  Get the limit on committed virtual address space in pages.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.mm.vm_memory_committed(prog: drgn.Program) → int

  Get the number of pages of committed virtual address space.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

class drgn.helpers.linux.mm.PageUsage

  Bases: `NamedTuple`

  Memory usage statistic in page units.

  pages: int

    Total number of pages.

  free_pages: int

    Number of free pages.

  property used_pages: int

    Number of used pages.

drgn.helpers.linux.mm.in_direct_map(prog: drgn.Program, addr: drgn.IntegerLike) → bool

  Return whether an address is within the kernel’s direct memory mapping.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – address to check

class drgn.helpers.linux.mm.TaskRss

  Bases: `NamedTuple`

  Task’s resident set size returned by `task_rss()`.

  file: int

    Number of resident file pages.

  anon: int

    Number of resident anonymous pages.

  shmem: int

    Number of resident shared memory pages.

  swap: int

    Number of swapped-out anonymous private pages.

  property total: int

    Total number of resident pages (`file` + `anon` + `shmem`).

drgn.helpers.linux.mm.task_rss(prog: drgn.Program, task: drgn.Object) → TaskRss

  Return a task’s resident set size (RSS) in pages.

  The task’s RSS is the number of pages which are currently resident in memory. The RSS values can be broken down into anonymous pages (not bound to any file), file pages (those associated with memory mapped files), and shared memory pages (those which aren’t associated with on-disk files, but belonging to shared memory mappings). This function returns a named tuple containing each category, but the common behavior is to use the `total` value which sums them up.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - task – `struct task_struct *`

drgn.helpers.linux.mm.task_vsize(task: drgn.Object) → int

  Return the virtual memory size of a task in bytes.

  Parameters:

    task – `struct task_struct *`

drgn.helpers.linux.mm.for_each_memory_block(prog: drgn.Program) → Iterable[drgn.Object]

  Iterate over all memory hotplug blocks.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct memory_block *` objects.

drgn.helpers.linux.mm.decode_memory_block_state(mem: drgn.Object) → str

  Get a human-readable representation of the state of a memory hotplug block.

      >>> decode_memory_block_state(mem)
      'MEM_ONLINE'

  Parameters:

    mem – `struct memory_block *`

drgn.helpers.linux.mm.decode_memory_block_state_value(prog: drgn.Program, state: drgn.IntegerLike) → str

  Get a human-readable representation of a memory hotplug block state value.

      >>> decode_memory_block_state_value(mem.state)
      'MEM_ONLINE'

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - mem – `enum memory_block_state` or `unsigned long`

drgn.helpers.linux.mm.memory_block_size_bytes(prog: drgn.Program) → drgn.Object

  Return the size of a memory hotplug block in bytes.

  This is the unit that can be hot(un)plugged.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `unsigned long`

### Memory Zones

The `drgn.helpers.linux.mmzone` module provides helpers for working with memory zones and SPARSEMEM.

drgn.helpers.linux.mmzone.NODE_DATA(prog: drgn.Program, nid: drgn.IntegerLike) → drgn.Object

  Get the NUMA node memory layout data of a given NUMA node.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - nid – NUMA node ID.

  Returns:

    `struct pglist_data *`

drgn.helpers.linux.mmzone.for_each_online_pgdat(prog: drgn.Program) → Iterator[drgn.Object]

  Get the NUMA node memory layout data of each online NUMA node.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct pglist_data *` objects

drgn.helpers.linux.mmzone.min_wmark_pages(zone: drgn.Object) → int

  Return the given memory zone’s minimum watermark.

  This controls when direct reclaim is performed.

  Parameters:

    zone – `struct zone *`

drgn.helpers.linux.mmzone.low_wmark_pages(zone: drgn.Object) → int

  Return the given memory zone’s low watermark.

  This controls when indirect reclaim is performed.

  Parameters:

    zone – `struct zone *`

drgn.helpers.linux.mmzone.high_wmark_pages(zone: drgn.Object) → int

  Return the given memory zone’s high watermark.

  This controls when `kswapd` can go to sleep.

  Parameters:

    zone – `struct zone *`

drgn.helpers.linux.mmzone.wmark_pages(zone: drgn.Object, i: drgn.IntegerLike) → int

  Return the given watermark in a memory zone.

      >>> wmark_pages(zone, prog["WMARK_PROMO"])
      28

  Parameters:

    - zone – `struct zone *`

    - i – `enum zone_watermarks`

drgn.helpers.linux.mmzone.nr_to_section(prog: drgn.Program, nr: drgn.IntegerLike) → drgn.Object

  Get the SPARSEMEM section with the given number.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - nr – `unsigned long`

  Returns:

    `struct mem_section *` (`NULL` if not found)

drgn.helpers.linux.mmzone.pfn_to_section_nr(prog: drgn.Program, pfn: drgn.IntegerLike) → drgn.Object

  Get the SPARSEMEM section number containing the given page frame number (PFN).

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - pfn – `unsigned long`

  Returns:

    `unsigned long`

drgn.helpers.linux.mmzone.section_nr_to_pfn(prog: drgn.Program, nr: drgn.IntegerLike) → drgn.Object

  Get the first page frame number (PFN) in the given SPARSEMEM section number.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - nr – `unsigned long`

  Returns:

    `unsigned long`

drgn.helpers.linux.mmzone.pfn_to_section(prog: drgn.Program, pfn: drgn.IntegerLike) → drgn.Object

  Get the SPARSEMEM section containing the given page frame number (PFN).

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - pfn – `unsigned long`

  Returns:

    `struct mem_section *`

drgn.helpers.linux.mmzone.section_mem_map_addr(section: drgn.Object) → drgn.Object

  Get the SPARSEMEM memory map for the given section.

  This is encoded such that `mem_map[pfn]` is the `struct page` for the given page frame number (PFN).

  Parameters:

    section – `struct mem_section *`

  Returns:

    `struct page *`

drgn.helpers.linux.mmzone.section_decode_mem_map(section: drgn.Object, nr: drgn.IntegerLike) → drgn.Object

  Get the decoded address of the SPARSEMEM memory map for the given section.

  This is the address such that `mem_map[0]` is the `struct page` for the first page in the section.

  Parameters:

    - section – `struct mem_section *`

    - nr – Section number.

  Returns:

    `struct page *`

drgn.helpers.linux.mmzone.present_section(section: drgn.Object) → bool

  Return whether a SPARSEMEM section is present.

  Parameters:

    section – `struct mem_section *`

drgn.helpers.linux.mmzone.present_section_nr(prog: drgn.Program, nr: drgn.IntegerLike) → bool

  Return whether the SPARSEMEM section with the given number is present.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - nr – `unsigned long`

drgn.helpers.linux.mmzone.valid_section(section: drgn.Object) → bool

  Return whether a SPARSEMEM section is valid, i.e., has a `mem_map`.

  Parameters:

    section – `struct mem_section *`

drgn.helpers.linux.mmzone.valid_section_nr(prog: drgn.Program, nr: drgn.IntegerLike) → bool

  Return whether the SPARSEMEM section with the given number is valid, i.e., has a `mem_map`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - nr – `unsigned long`

drgn.helpers.linux.mmzone.online_section(section: drgn.Object) → bool

  Return whether a SPARSEMEM section is online.

  This is only valid since Linux kernel 4.13.

  Parameters:

    section – `struct mem_section *`

drgn.helpers.linux.mmzone.online_section_nr(prog: drgn.Program, nr: drgn.IntegerLike) → bool

  Return whether the SPARSEMEM section with the given number is online.

  This is only valid since Linux kernel 4.13.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - nr – `unsigned long`

drgn.helpers.linux.mmzone.early_section(section: drgn.Object) → bool

  Return whether a SPARSEMEM section was created during early memory initialization.

  This is only valid since Linux kernel 5.3.

  Parameters:

    section – `struct mem_section *`

drgn.helpers.linux.mmzone.early_section_nr(prog: drgn.Program, nr: drgn.IntegerLike) → bool

  Return whether the SPARSEMEM section with the given number was created during early memory initialization.

  This is only valid since Linux kernel 5.3.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - nr – `unsigned long`

drgn.helpers.linux.mmzone.decode_section_flags(section: drgn.Object) → str

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

      >>> decode_section_flags(section)
      'SECTION_MARKED_PRESENT|SECTION_HAS_MEM_MAP|SECTION_IS_ONLINE|SECTION_IS_EARLY'

  Parameters:

    section – `struct mem_section *`

drgn.helpers.linux.mmzone.for_each_present_section(prog: drgn.Program) → Iterator[Tuple[int, drgn.Object]]

  Iterate over each present SPARSEMEM section.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of (section number, `struct mem_section *` object) tuples.

### Modules

The `drgn.helpers.linux.module` module contains helpers for working with loaded kernel modules.

drgn.helpers.linux.module.for_each_module(prog: drgn.Program) → Iterable[drgn.Object]

  Returns all loaded kernel modules

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterable of `struct module *` objects

drgn.helpers.linux.module.find_module(prog: drgn.Program, name: Union[str, bytes]) → drgn.Object

  Lookup a kernel module by name, or return NULL if not found

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - name – name to search for

  Returns:

    the `struct module *` by that name, or NULL

drgn.helpers.linux.module.module_percpu_region(mod: drgn.Object) → Tuple[int, int]

  Lookup the percpu memory region of a module.

  Given a `struct module *`, return the address (as a an int) and the length of the percpu memory region. Modules may have a NULL percpu region, in which case (0, 0) is returned. Rarely, on kernels without `CONFIG_SMP`, there is no percpu region at all, and this function returns (0, 0)

  Parameters:

    mod – Object of type `struct module *`

  Returns:

    (base, size) of the module percpu region

drgn.helpers.linux.module.module_address_regions(mod: drgn.Object) → List[Tuple[int, int]]

  Returns a list of address ranges for a module

  Given a `struct module *`, return every address range associated with the module. Note that the number of address ranges and their interpretations vary across kernel versions. Some kernel versions provide additional information about some regions (e.g. text, data, R/O, init). This API doesn’t distinguish. However, this API does not provide the module’s percpu region: use `module_percpu_region()` for that.

  Parameters:

    mod – Object of type `struct module *`

  Returns:

    list of tuples: (starting memory address, length of address range)

drgn.helpers.linux.module.address_to_module(prog: drgn.Program, addr: drgn.IntegerLike) → drgn.Object

  Return the `struct module *` associated with a memory address

  If the address is a text, data, or read-only data address associated with a kernel module, then this function returns the module it is associated with. Otherwise, returns NULL. Note that dynamic memory (e.g. slab objects) generally can’t be associated with the module that allocated it. Further, static & dynamic per-cpu address cannot be associated with their associated module either.

  Normally, this lookup is efficient, thanks to `CONFIG_MODULES_TREE_LOOKUP`, which provides a red-black tree of module address ranges, and is very commonly enabled. However, on some uncommon configurations the rbtree may not be present. In those cases, we fall back to a linear search of each kernel module’s memory regions.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – memory address to lookup

  Returns:

    the `struct module *` associated with the memory, or NULL

drgn.helpers.linux.module.module_taints(module: drgn.Object) → str

  Get a kernel module’s taint flags as a string.

  If the module did not taint the kernel, then this returns an empty string:

      >>> module_taints(module)
      ''

  Otherwise, it returns the flags as letters (without spaces):

      >>> module_taints(module)
      'O'

  See the kernel documentation for an explanation of the flags.

  Parameters:

    module – `struct module *`

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

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  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/net` or `/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/net` or `/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.for_each_netdev(net: Union[drgn.Object, drgn.Program]) → Iterator[drgn.Object]

  Iterate over all network devices in a namespace.

  Parameters:

    net – `struct net *`. Defaults to the initial network namespace if given a `Program` or omitted.

  Returns:

    Iterator of `struct net_device *` objects.

drgn.helpers.linux.net.netdev_name(dev: drgn.Object) → bytes

  Get the name of a network device.

      >>> netdev_name(dev)
      b'lo'

  Parameters:

    dev – `struct net_device *`

drgn.helpers.linux.net.netdev_get_by_index(net: Union[drgn.Object, drgn.Program], ifindex: drgn.IntegerLike) → drgn.Object

  Get the network device with the given interface index number.

  Parameters:

    - net – `struct net *`. Defaults to the initial network namespace if given a `Program` or omitted.

    - ifindex – Network interface index number.

  Returns:

    `struct net_device *` (`NULL` if not found)

drgn.helpers.linux.net.netdev_get_by_name(net: Union[drgn.Object, drgn.Program], name: Union[str, bytes]) → drgn.Object

  Get the network device with the given interface name.

  Parameters:

    - net – `struct net *`. Defaults to the initial network namespace if given a `Program` or omitted.

    - name – Network interface name.

  Returns:

    `struct net_device *` (`NULL` if not found)

drgn.helpers.linux.net.netdev_priv(dev: drgn.Object, type: Union[str, drgn.Type] = 'void') → drgn.Object

  Return the private data of a network device.

      >>> dev = netdev_get_by_name("wlp0s20f3")
      >>> netdev_priv(dev)
      (void *)0xffff9419c9dec9c0
      >>> netdev_priv(dev, "struct ieee80211_sub_if_data")
      *(struct ieee80211_sub_if_data *)0xffff9419c9dec9c0 = {
          ...
      }

  Parameters:

    - dev – `struct net_device *`

    - type – Type of private data.

  Returns:

    `type *`

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_head` head.

  Parameters:

    head – `struct hlist_nulls_head *`

  Returns:

    Iterator of `struct sock *` objects.

drgn.helpers.linux.net.skb_shinfo(skb: drgn.Object) → drgn.Object

  Get the shared info for a socket buffer.

  Parameters:

    skb – `struct sk_buff *`

  Returns:

    `struct skb_shared_info *`

drgn.helpers.linux.net.is_pp_page(page: drgn.Object) → bool

  Check if given page is a page_pool page.

  Parameters:

    page – `struct page *`

  Raises:

    NotImplementedError – If page_pool pages cannot be identified on this kernel. This is the case from Linux 4.18 (when page_pool was introduced) up to and including Linux 5.13.

drgn.helpers.linux.net.netdev_ipv4_addrs(dev: drgn.Object) → List[ipaddress.IPv4Address]

  Get the list of IPV4 addresses associated with a network device.

  Parameters:

    dev – `struct net_device *`

drgn.helpers.linux.net.netdev_ipv6_addrs(dev: drgn.Object) → List[ipaddress.IPv6Address]

  Get the list of IPV6 addresses associated with a network device.

  Parameters:

    dev – `struct net_device *`

drgn.helpers.linux.net.neigh_table_for_each_neighbor(table: drgn.Object) → Iterator[drgn.Object]

  Get the neighbour object from the neighbour hash table

  Parameters:

    dev – `struct neigh_hash_table *`

### 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.nr_node_ids(prog: drgn.Program) → int

  Get the upper bound on the number of NUMA node IDs.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

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:

    - prog – Program, which may be omitted to use the default program argument.

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

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.nodemask.for_each_online_node(prog: drgn.Program) → Iterator[int]

  Iterate over all online NUMA nodes.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

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`)

### Panic

The `drgn.helpers.linux.panic` module provides helpers for getting kernel panic information.

drgn.helpers.linux.panic.panic_task(prog: drgn.Program) → drgn.Object

  Return the task that panicked.

  This is equivalent to:

      from drgn import NULL

      try:
          task = prog.crashed_thread().object
      except ValueError:
          task = NULL(prog, "struct task_struct *")

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `struct task_struct *` (`NULL` if the kernel has not panicked)

drgn.helpers.linux.panic.panic_message(prog: drgn.Program) → Optional[bytes]

  Get the kernel message logged during a panic.

      >>> panic_message()
      b'Oops: Oops: 0002 [#1] SMP NOPTI'

  Note that this returns `bytes`. The recommended way to get a `str` is with `bytes.decode(errors="replace")`:

      message = panic_message()
      if message is not None:
          message = message.decode(errors="replace")

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Message, or `None` if the kernel has not panicked or no message was found

drgn.helpers.linux.panic.tainted(prog: drgn.Program) → str

  Get the kernel’s tainted flags as a string.

  If the kernel is not tainted, then this returns an empty string:

      >>> tainted()
      ''

  Otherwise, it returns the flags as letters:

      >>> tainted()
      'G           O       '

  See the kernel documentation for an explanation of the flags.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

### PCI

The `drgn.helpers.linux.pci` module provides helpers for working with PCI devices and buses.

drgn.helpers.linux.pci.for_each_pci_dev(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over all PCI devices.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct pci_dev *` objects.

drgn.helpers.linux.pci.for_each_pci_root_bus(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over all PCI root buses.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct pci_bus *` objects.

drgn.helpers.linux.pci.pci_bus_for_each_child(bus: drgn.Object) → Iterator[drgn.Object]

  Iterate over every child bus of a given PCI bus.

  Parameters:

    bus – `struct pci_bus *`

  Returns:

    Iterator of `struct pci_bus *` objects.

drgn.helpers.linux.pci.pci_bus_for_each_dev(bus: drgn.Object) → Iterator[drgn.Object]

  Iterate over every device on a given PCI bus.

  Parameters:

    bus – `struct pci_bus *`

  Returns:

    Iterator of `struct pci_dev *` objects.

drgn.helpers.linux.pci.pci_name(dev: drgn.Object) → str

  Get the name (Domain:Bus:Device.Function) of a PCI device.

  Parameters:

    dev – `struct pci_dev *`

drgn.helpers.linux.pci.pci_bus_name(bus: drgn.Object) → str

  Get the name (Domain:Bus) of a PCI bus.

  Parameters:

    bus – `struct pci_bus *`

drgn.helpers.linux.pci.pci_is_bridge(dev: drgn.Object) → bool

  Return whether a PCI device is a bridge.

  Parameters:

    dev – `struct pci_dev *`

drgn.helpers.linux.pci.pci_pcie_type(dev: drgn.Object) → Union['PCI_EXP_TYPE', int]

  Return the PCI Express Device/Port Type of a PCI device.

  Parameters:

    dev – `struct pci_dev *`

  Returns:

    `PCI_EXP_TYPE` constant, or an `int` if the value is not recognized.

class drgn.helpers.linux.pci.PCI_EXP_TYPE

  Bases: `enum.IntEnum`

  PCI Express Device/Port Type.

  ENDPOINT

    Express Endpoint

  LEG_END

    Legacy Endpoint

  ROOT_PORT

    Root Port

  UPSTREAM

    Upstream Port

  DOWNSTREAM

    Downstream Port

  PCI_BRIDGE

    PCIe to PCI/PCI-X Bridge

  PCIE_BRIDGE

    PCI/PCI-X to PCIe Bridge

  RC_END

    Root Complex Integrated Endpoint

  RC_EC

    Root Complex Event Collector

### 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 use `per_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; use `per_cpu_ptr()` for that).

    - cpu – CPU number.

  Returns:

    `type` object.

drgn.helpers.linux.percpu.percpu_counter_sum(fbc: drgn.Object) → int

  Return the sum of a per-CPU counter.

  Parameters:

    fbc – `struct percpu_counter *`

drgn.helpers.linux.percpu.percpu_counter_sum_positive(fbc: drgn.Object) → int

  Return the sum of a per-CPU counter, or 0 if it is negative.

  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.pid_task(pid: drgn.Object, pid_type: drgn.IntegerLike) → drgn.Object

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

  Parameters:

    - pid – `struct pid *`

    - pid_type – `enum pid_type`

  Returns:

    `struct task_struct *`

drgn.helpers.linux.pid.find_pid(ns: drgn.Object | drgn.Program, pid: drgn.IntegerLike) → drgn.Object

  Return the `struct pid *` for the given PID number.

  Parameters:

    ns – `struct pid_namespace *`. Defaults to the initial PID namespace if given a `Program` or omitted.

  Returns:

    `struct pid *`

drgn.helpers.linux.pid.for_each_pid(ns: drgn.Object | drgn.Program) → Iterator[drgn.Object]

  Iterate over all PIDs in a namespace.

  Parameters:

    ns – `struct pid_namespace *`. Defaults to the initial PID namespace if given a `Program` or omitted.

  Returns:

    Iterator of `struct pid *` objects.

drgn.helpers.linux.pid.find_task(ns: drgn.Object | drgn.Program, pid: drgn.IntegerLike) → drgn.Object

  Return the task with the given PID.

  Parameters:

    ns – `struct pid_namespace *`. Defaults to the initial PID namespace if given a `Program` or omitted.

  Returns:

    `struct task_struct *`

drgn.helpers.linux.pid.for_each_task(ns: drgn.Object | drgn.Program, *, idle: bool = False) → Iterator[drgn.Object]

  Iterate over all of the tasks visible in a namespace.

  Parameters:

    - ns – `struct pid_namespace *`. Defaults to the initial PID namespace if given a `Program` or omitted.

    - idle – Whether to include the idle threads (PID 0, a.k.a swapper) for each CPU.

  Returns:

    Iterator of `struct task_struct *` objects.

drgn.helpers.linux.pid.for_each_task_in_group(task: drgn.Object, include_self: bool = False) → Iterator[drgn.Object]

  Iterate over all tasks in the thread group

  Or, in the more common userspace terms, iterate over all threads of a process.

  Parameters:

    - task – a task whose group to iterate over

    - include_self – should `task` itself be returned?

  Returns:

    an iterable of every thread in the thread group

### Priority-Sorted Lists

The `drgn.helpers.linux.plist` module provides helpers for working with descending-priority-sorted doubly-linked lists (`struct plist_head` and `struct plist_node`) from `include/linux/plist.h`.

drgn.helpers.linux.plist.plist_head_empty(head: drgn.Object) → bool

  Return whether a plist is empty.

  Parameters:

    head – `struct plist_head *`

drgn.helpers.linux.plist.plist_node_empty(node: drgn.Object) → bool

  Return whether a plist node is empty (i.e., not on a list).

  Parameters:

    node – `struct plist_node *`

drgn.helpers.linux.plist.plist_first_entry(head: drgn.Object, type: Union[str, drgn.Type], member: str) → drgn.Object

  Return the first (highest priority) entry in a plist.

  The list is assumed to be non-empty.

  Parameters:

    - head – `struct plist_head *`

    - type – Entry type.

    - member – Name of list node member in entry type.

  Returns:

    `type *`

drgn.helpers.linux.plist.plist_last_entry(head: drgn.Object, type: Union[str, drgn.Type], member: str) → drgn.Object

  Return the last (lowest priority) entry in a plist.

  The list is assumed to be non-empty.

  Parameters:

    - head – `struct plist_head *`

    - type – Entry type.

    - member – Name of list node member in entry type.

  Returns:

    `type *`

drgn.helpers.linux.plist.plist_for_each(head: drgn.Object) → Iterator[drgn.Object]

  Iterate over all of the nodes in a plist.

  Parameters:

    head – `struct plist_head *`

  Returns:

    Iterator of `struct plist_node *` objects.

drgn.helpers.linux.plist.plist_for_each_entry(type: Union[str, drgn.Type], head: drgn.Object, member: str) → Iterator[drgn.Object]

  Iterate over all of the entries in a plist.

  Parameters:

    - type – Entry type.

    - head – `struct plist_head *`

    - member – Name of plist node member in entry type.

  Returns:

    Iterator of `type *` 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: `NamedTuple`

  Kernel log record.

  text: bytes

    Message text.

  facility: int

    syslog(3) facility.

  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_tid` for 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/kmsg` documentation 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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.printk.get_dmesg(prog: drgn.Program, *, timestamps: Union[bool, Literal['human']] = True) → bytes

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

  If you just want to print the log buffer, use `print_dmesg()`.

  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.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - timestamps – How to format timestamps. If `True`, timestamps are formatted in decimal seconds. If `False`, timestamps are omitted. If `"human"`, timestamps are formatted as human-readable dates and times, which are only correct for messages printed since the last suspend/resume.

drgn.helpers.linux.printk.print_dmesg(prog: drgn.Program, *, timestamps: Union[bool, Literal['human']] = True, file: Optional[SupportsWrite[str]] = None) → None

  Print the contents of the kernel log buffer.

      >>> print_dmesg()
      [    0.000000] Linux version 6.8.0-vmtest28.1default (drgn@drgn) (x86_64-linux-gcc (GCC) 12.2.0, GNU ld (GNU Binutils) 2.39) #1 SMP PREEMPT_DYNAMIC Mon Mar 11 06:38:45 UTC 2024
      [    0.000000] Command line: rootfstype=9p rootflags=trans=virtio,cache=loose,msize=1048576 ro console=ttyS0,115200 panic=-1 crashkernel=256M init=/tmp/drgn-vmtest-rudzppeo/init
      [    0.000000] BIOS-provided physical RAM map:
      ...

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - timestamps – How to format timestamps. See `get_dmesg()`.

    - file – File to print to. Defaults to `sys.stdout`.

### 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, or `NULL` if 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 `NULL` if 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 `NULL` if 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 `NULL` if 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 `NULL` if 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_node` member in entry type.

  Returns:

    Iterator of `type *` objects.

drgn.helpers.linux.rbtree.rbtree_preorder_for_each(root: drgn.Object) → Iterator[drgn.Object]

  Iterate over all of the nodes in a red-black tree, visiting each node before its children.

  Parameters:

    root – `struct rb_root *`

  Returns:

    Iterator of `struct rb_node *` objects.

drgn.helpers.linux.rbtree.rbtree_preorder_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, visiting each node before its children.

  Parameters:

    - type – Entry type.

    - root – `struct rb_root *`

    - member – Name of `struct rb_node` member 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_node` member 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, or `NULL` if 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:

  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 – Entry type.

    - root – `struct rb_root *`

    - member – Name of `struct rb_node` member 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 like `validate_rbtree()` while iterating.

  Parameters:

    - type – Entry type.

    - root – `struct rb_root *`

    - member – Name of `struct rb_node` member 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

### Resource Limits

The `drgn.helpers.linux.resource` module provides helpers for resource limits (rlimit).

drgn.helpers.linux.resource.task_rlimits(task: drgn.Object) → Dict[str, 'Rlimit']

  Get the resource limits on a given task.

      >>> task_rlimits(find_task(os.getpid()))
      {'CPU': Rlimit(cur=None, max=None), 'FSIZE': Rlimit(cur=None, max=None), ...}
      >>> task_rlimits(find_task(os.getpid()))["STACK"].cur
      8388608

  Returns:

    Dictionary mapping resource name (“NOFILE”, “CORE”, etc.) to `Rlimit`.

class drgn.helpers.linux.resource.Rlimit

  Bases: `NamedTuple`

  Resource limit.

  cur: Optional[int]

    Soft limit, or `None` if unlimited.

  max: Optional[int]

    Hard limit, or `None` if unlimited.

### Sbitmaps

The `drgn.helpers.linux.sbitmap` module provides helpers for working with scalable bitmaps from `include/linux/sbitmap.h`.

drgn.helpers.linux.sbitmap.sbitmap_for_each_set(sb: drgn.Object) → Iterator[int]

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

  Parameters:

    sb – `struct sbitmap *`

### CPU Scheduler

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

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_on_cpu(task: drgn.Object) → bool

  Return whether the given task is currently running on a CPU.

  Parameters:

    task – `struct task_struct *`

drgn.helpers.linux.sched.task_thread_info(task: drgn.Object) → drgn.Object

  Return the thread information structure for a task.

  Parameters:

    task – `struct task_struct *`

  Returns:

    `struct thread_info *`

drgn.helpers.linux.sched.cpu_curr(prog: drgn.Program, cpu: drgn.IntegerLike) → drgn.Object

  Return the task running on the given CPU.

      >>> cpu_curr(7).comm
      (char [16])"python3"

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - cpu – CPU number.

  Returns:

    `struct task_struct *`

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(1).comm
      (char [16])"swapper/1"

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - cpu – CPU number.

  Returns:

    `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 *`

drgn.helpers.linux.sched.get_task_state(task: drgn.Object) → str

  Get the state of the task as a character plus a parenthesized name (e.g., `'R (running)'`).

  See also `task_state_to_char()`.

  Parameters:

    task – `struct task_struct *`

drgn.helpers.linux.sched.loadavg(prog: drgn.Program) → Tuple[float, float, float]

  Return system load averaged over 1, 5 and 15 minutes as tuple of three float values.

      >>> loadavg()
      (2.34, 0.442, 1.33)

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.sched.cpu_rq(prog: drgn.Program, cpu: drgn.IntegerLike) → drgn.Object

  Get the runqueue for a given cpu.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - cpu – CPU number.

  Returns:

    `struct rq *`

drgn.helpers.linux.sched.task_rq(task: drgn.Object) → drgn.Object

  Get the runqueue for a given task.

  Parameters:

    task – `struct task_struct *`

  Returns:

    `struct rq *`

drgn.helpers.linux.sched.rq_for_each_fair_task(rq: drgn.Object) → Iterator[drgn.Object]

  Iterate over tasks on a runqueue in the fair scheduling class (EEVDF or CFS).

  Parameters:

    rq – `struct rq *`

  Returns:

    Iterator of `struct task_struct *` objects

drgn.helpers.linux.sched.rq_for_each_rt_task(rq: drgn.Object) → Iterator[drgn.Object]

  Iterate over tasks on a runqueue in the realtime scheduling class.

  Parameters:

    rq – `struct rq *`

  Returns:

    Iterator of `struct task_struct *` objects

drgn.helpers.linux.sched.sched_entity_is_task(se: drgn.Object) → bool

  Return whether a scheduler entity is a task.

  Parameters:

    se – `struct sched_entity *`

drgn.helpers.linux.sched.sched_entity_to_task(se: drgn.Object) → drgn.Object

  Get the task represented by a scheduler entity.

  Note that this does not check whether the entity is actually a task; see `sched_entity_is_task()`.

  Parameters:

    se – `struct sched_entity *`

  Returns:

    `struct task_struct *`

drgn.helpers.linux.sched.task_group_name(tg: drgn.Object) → bytes

  Get the name of a task group.

  Parameters:

    tg – `struct task_group *`

  Returns:

    Cgroup name, or empty byte string if not a cgroup.

drgn.helpers.linux.sched.cfs_rq_for_each_entity(cfs_rq: drgn.Object) → Iterator[Tuple[drgn.Object, int, bool, bool]]

  Iterate over all entities on a fair scheduler runqueue (recursively).

  Task groups are visited before their children (i.e., this does a pre-order traversal).

  Parameters:

    cfs_rq – `struct cfs_rq *`

  Returns:

    Iterator of (`struct sched_entity *`, `depth`, `is_curr`, `is_task`) tuples.

    `depth` is the depth of the entity relative to the runqueue (e.g., direct children have depth 0, entities in descendant task groups have depth > 0).

    `is_curr` is whether the entity is the current entity on its runqueue.

    If `is_task` is `True`, then the entity is a task, which can be obtained with `sched_entity_to_task()`. Otherwise, it is a task group.

drgn.helpers.linux.sched.task_since_last_arrival_ns(task: drgn.Object) → int

  Get the difference between the runqueue timestamp when a task last started running and the current runqueue timestamp.

  This is approximately the time that the task has been in its current status (running, queued, or blocked). However, if a CPU is either idle or running the same task for a long time, then the timestamps will not be accurate.

  This is only supported if the kernel was compiled with `CONFIG_SCHEDSTATS` or `CONFIG_TASK_DELAY_ACCT`.

  Parameters:

    task – `struct task_struct *`

  Returns:

    Duration in nanoseconds.

drgn.helpers.linux.sched.thread_group_leader(task: drgn.Object) → bool

  Return whether a task is a thread group leader.

  Parameters:

    task – `struct task_struct *`

### Signals

The `drgn.helpers.linux.signal` module provides helpers for working with signals.

drgn.helpers.linux.signal.sigpending_for_each(pending: drgn.Object) → Iterator[drgn.Object]

  Iterate over a queue of pending signals.

  Parameters:

    pending – `struct sigpending *`

  Returns:

    Iterator of `struct sigqueue *` objects.

drgn.helpers.linux.signal.signal_names(prog: drgn.Program) → Mapping[str, int]

  Get a mapping from signal names to numbers on this kernel.

      >>> signal_names()
      {'SIGHUP': 1, 'SIGINT': 2, 'SIGQUIT': 3, ...}

  If there are multiple names for the same number (e.g., `SIGCHLD` and `SIGCLD`), then the preferred name comes first.

  Note that `SIGRTMIN` and `SIGRTMAX` are dynamic in userspace, so the values used in the kernel may differ from those in userspace.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.signal.signal_numbers(prog: drgn.Program) → Mapping[int, Sequence[str]]

  Get a mapping from signal numbers to names on this kernel.

      >>> signal_numbers()
      {1: ['SIGHUP'], 2: ['SIGINT'], 3: ['SIGQUIT'], ...}

  If there are multiple names for the same number (e.g., `SIGCHLD` and `SIGCLD`), then the preferred name comes first.

  Note that `SIGRTMIN` and `SIGRTMAX` are dynamic in userspace, so the values used in the kernel may differ from those in userspace.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.signal.sigaction_flags(prog: drgn.Program) → Mapping[str, int]

  Get a mapping of sigaction(2) `sa_flags` flag names to values on this kernel.

      >>> sigaction_flags()
      {'SA_NOCLDSTOP': 1, 'SA_NOCLDWAIT': 2, 'SA_SIGINFO': 4, ...}

  If there are multiple names for the same value (e.g., `SA_NODEFER` and `SA_NOMASK`), then the preferred name comes first.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.signal.decode_sigset(prog: drgn.Program, sigset: Union[drgn.Object, drgn.IntegerLike]) → str

  Get a human-readable representation of a signal set.

      >>> decode_sigset(task.blocked)
      '{SIGINT,SIGTERM}'
      >>> decode_sigset(0x14003)
      '{SIGHUP,SIGINT,SIGTERM,SIGCHLD}'

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - sigset – `sigset_t`, `sigset_t *`, or an integer

drgn.helpers.linux.signal.sigset_to_hex(sigset: drgn.Object) → str

  Get a hexadecimal representation of a signal set.

  This matches how signal sets are represented in proc_pid_status(5).

      >>> sigset_to_hex(task.blocked)
      '0000000000004002'

  Parameters:

    sigset – `sigset_t` or `sigset_t *`

drgn.helpers.linux.signal.decode_sigaction_flags(sigaction: drgn.Object) → str

  Get a human-readable representation of the `sa_flags` of a `struct sigaction`.

      >>> decode_sigaction_flags(task.sighand.action[1].sa)
      'SA_RESTORER|SA_RESTART'

  Parameters:

    sigaction – `struct sigaction`

drgn.helpers.linux.signal.decode_sigaction_flags_value(prog: drgn.Program, value: drgn.IntegerLike) → str

  Get a human-readable representation of a sigaction(2) `sa_flags` value.

      >>> decode_sigaction_flags_value(0x14000000)
      'SA_RESTORER|SA_RESTART'

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - value – `int`

### 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_objects_per_slab(slab_cache: drgn.Object) → int

  Get the number of objects in each slab of the given slab cache.

  This is only applicable to the SLUB and SLAB allocators; SLOB is not supported.

  Parameters:

    slab_cache – `struct kmem_cache *`

drgn.helpers.linux.slab.slab_cache_pages_per_slab(slab_cache: drgn.Object) → int

  Get the number of pages allocated for each slab of the given slab cache.

  This is only applicable to the SLUB and SLAB allocators; SLOB is not supported.

  Parameters:

    slab_cache – `struct kmem_cache *`

drgn.helpers.linux.slab.slab_cache_order(slab_cache: drgn.Object) → int

  Get the allocation order (i.e., base 2 logarithm of the number of pages) for each slab of the given slab cache.

  This is only applicable to the SLUB and SLAB allocators; SLOB is not supported.

      >>> 1 << slab_cache_order(slab_cache) == slab_cache_pages_per_slab(slab_cache)
      True

  Parameters:

    slab_cache – `struct kmem_cache *`

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_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("bar")

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

      slab_cache_for_each_allocated_object(find_slab_cache("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 with `CONFIG_SLUB` and `CONFIG_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()
      >>> cache_to_merged["dnotify_struct"]
      'avc_xperms_data'
      >>> "avc_xperms_data" in cache_to_merged
      False
      >>> find_slab_cache("dnotify_struct") is None
      True
      >>> find_slab_cache("avc_xperms_data") is None
      False

  Warning:

    This function will only work on kernels which are built with `CONFIG_SLUB` and `CONFIG_SYSFS` enabled.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  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.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  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:

    - prog – Program, which may be omitted to use the default program argument.

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

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

class drgn.helpers.linux.slab.SlabCorruptionError

  Bases: `drgn.helpers.ValidationError`

  Error raised when a corruption is encountered in a slab allocator data structure.

class drgn.helpers.linux.slab.SlabFreelistCycleError

  Bases: `SlabCorruptionError`

  Error raised when a cycle is encountered in a slab allocator freelist.

class drgn.helpers.linux.slab.SlabPartialListError

  Bases: `SlabCorruptionError`

  Error raised when a corruption is encountered in a list of partial slabs.

drgn.helpers.linux.slab.slab_cache_usage(slab_cache: drgn.Object) → SlabCacheUsage

  Get statistics for how many slabs and objects are allocated for a given slab cache.

  Only the SLUB and SLAB allocators are supported; SLOB does not track these statistics. Additionally, for SLUB, `CONFIG_SLUB_DEBUG` must be enabled in the kernel (this is the default unless `CONFIG_SLUB_TINY` is enabled).

  Parameters:

    slab_cache – `struct kmem_cache *`

class drgn.helpers.linux.slab.SlabCacheUsage

  Bases: `NamedTuple`

  Slab cache usage statistics returned by `slab_cache_usage()`.

  num_slabs: int

    Number of slabs allocated for this slab cache.

  num_objs: int

    Total number of objects in this slab cache (free and active).

  free_objs: int

    Number of free objects in this slab cache.

  property active_objs: int

    Number of active (allocated) objects in this slab cache.

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("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(prog: drgn.Program, addr: drgn.IntegerLike) → Optional[SlabObjectInfo]

  Get information about an address if it is in a slab object.

      >>> ptr = find_task(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.address` is 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

  Note that SLOB does not store enough information to identify slab objects, so if the kernel is configured to use SLOB, then `SlabObjectInfo.slab_cache` will always be `NULL` and `SlabObjectInfo.address` will always be 0. Additionally, for allocations of at least one page, SLOB allocates pages directly, so this will return `None`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

  Returns:

    `SlabObjectInfo` if addr is in a slab object, or `None` if 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.

    SLOB does not store enough information to find this, so if the kernel is configured to use SLOB, then this will always be `NULL`.

  slab: drgn.Object

    Slab containing the slab object.

    Since Linux v5.17, this is a `struct slab *`. Before that, it is a `struct page *`.

  address: int

    Address of the slab object.

    SLOB does not store enough information to find this, so if the kernel is configured to use SLOB, then this will always be 0.

  allocated: Optional[bool]

    `True` if the object is allocated, `False` if it is free, or `None` if not known because the slab cache is corrupted or the kernel is configured to use SLOB.

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.

  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:

    - prog – Program, which may be omitted to use the default program argument.

    - addr – `void *`

  Returns:

    `struct kmem_cache *` containing addr, or `NULL` if addr is not from a slab cache.

drgn.helpers.linux.slab.slab_total_usage(prog: drgn.Program) → SlabTotalUsage

  Get the total number of reclaimable and unreclaimable slab pages.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

class drgn.helpers.linux.slab.SlabTotalUsage

  Bases: `NamedTuple`

  Slab memory usage returned by `slab_total_usage()`.

  reclaimable_pages: int

    Number of reclaimable slab pages.

  unreclaimable_pages: int

    Number of unreclaimable slab pages.

  property total_pages: int

    Total number of slab pages.

### Stack

The `drgn.helpers.linux.stack` module contains helpers for working with Linux kernel stacks. These helpers can provide additional information specific to the kernel.

class drgn.helpers.linux.stack.StackKind

  Bases: `enum.Enum`

  A `StackKind` represents a kind of context associated with a stack.

  USER

    Stack frames associated with userspace

  TASK

    Stack frames associated with the kernel’s thread stack

  IRQ

    Stack frames associated with IRQ handlers

  SOFTIRQ

    Stack frames associated with softirqs

  NMI

    Stack frames associated with NMI handlers (arch-specific)

  EXCEPTION

    Stack frames associated with other exceptions (arch-specific)

  UNKNOWN

    Stack frames which could not be categorized

class drgn.helpers.linux.stack.StackSegment

  A subset of a stack trace associated with a context.

  kind: StackKind

    The kind of stack associated with this segment

  frames: Sequence[drgn.StackFrame]

    Stack frames that are part of the segment

class drgn.helpers.linux.stack.LinuxKernelStack

  A stack trace broken into segments associated with execution contexts.

  Stack traces for kernel programs may span many execution contexts, each one interrupting the previous one. For instance, a user task may be interrupted by the kernel handling its system call, which could in turn be interrupted by a hardware interrupt. A `LinuxKernelStack` groups the frames of a stack trace into `StackSegments`, each of which is associated with a `StackKind`. It may also be iterated and indexed like a normal `StackTrace`.

  prog: drgn.Program

    The program associated with the stack trace

  segments: Sequence[StackSegment]

    Segments of the stack trace

drgn.helpers.linux.stack.kernel_stack_trace(prog: drgn.Program, task_arg: Union[drgn.Object, drgn.IntegerLike]) → LinuxKernelStack

  Create a stack trace and return a categorized `LinuxKernelStack`.

  This function creates a stack trace, breaks it into segments, and categorizes each segment. The process is best-effort. Not all stack kinds can be segmented or recognized, as the process is architecture and version specific.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - task – a PID or `struct task_struct *` to unwind

  Returns:

    a separated, annotated stack

### Stack Depot

The `drgn.helpers.linux.stackdepot` module provides helpers for working with the stack trace storage from `include/linux/stackdepot.h` used by KASAN and other kernel debugging tools.

drgn.helpers.linux.stackdepot.stack_depot_fetch(handle: drgn.Object) → Optional[drgn.StackTrace]

  Returns a stack trace for the given stack handle.

  Parameters:

    handle – `depot_stack_handle_t`

  Returns:

    The stack trace, or `None` if not available.

### Simple Wait Queues

The `drgn.helpers.linux.swait` module provides helpers for working with simple wait queues (`swait_queue_head` and `swait_queue`) from `include/linux/swait.h`.

drgn.helpers.linux.swait.swait_active(wq: drgn.Object) → bool

  Return whether a simple wait queue has any waiters.

  Parameters:

    wq – `struct swait_queue_head *`

drgn.helpers.linux.swait.swait_for_each_task(wq: drgn.Object) → Iterator[drgn.Object]

  Iterate over all tasks waiting on a simple wait queue.

  Parameters:

    wq – `struct swait_queue_head *`

  Returns:

    Iterator of `struct task_struct *` objects.

### Swap Space

The `drgn.helpers.linux.swap` module provides helpers for inspecting swap partitions and swap files.

drgn.helpers.linux.swap.for_each_swap_info(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over all swap devices.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct swap_info_struct *` objects.

drgn.helpers.linux.swap.swap_file_path(si: drgn.Object) → bytes

  Get the path of the swap partition or file.

      >>> swap_file_path(si)
      b'/dev/sda3'

  Parameters:

    si – `struct swap_info_struct *`

drgn.helpers.linux.swap.swap_is_file(si: drgn.Object) → bool

  Return whether a swap device is a regular file.

  Parameters:

    si – `struct swap_info_struct *`

drgn.helpers.linux.swap.swap_usage_in_pages(si: drgn.Object) → int

  Get the number of pages currently in use on a swap device.

      >>> swap_usage_in_pages(si)
      394319

  Parameters:

    si – `struct swap_info_struct *`

drgn.helpers.linux.swap.swap_total_usage(prog: drgn.Program) → drgn.helpers.linux.mm.PageUsage

  Get the total number of swap pages and the number of free swap pages on all swap devices.

      >>> usage = swap_total_usage()
      >>> usage
      PageUsage(pages=2097151, free_pages=1704798)
      >>> usage.used_pages
      392353

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.swap.total_swapcache_pages(prog: drgn.Program) → int

  Get the number of swap cached pages (pages that are swapped in but still present on a swap device).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

### Sysfs

The `drgn.helpers.linux.sysfs` module provides helpers for working with the sysfs interface built on top of kernfs.

drgn.helpers.linux.sysfs.sysfs_lookup_node(prog: drgn.Program, path: str) → drgn.Object

  Look up a `struct kernfs_node *` for a given sysfs path.

  The path may be provided either relative to `/sys` (e.g., `devices/system/cpu`) or as an absolute path beginning with `/sys`.

  If the path is empty or refers to `/sys` itself, this returns the sysfs root node.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - path – Sysfs path (absolute or relative to `/sys`)

  Returns:

    `struct kernfs_node *` or `NULL`

drgn.helpers.linux.sysfs.sysfs_lookup_kobject(prog: drgn.Program, path: str) → Optional[drgn.Object]

  Look up the `struct kobject *` corresponding to a sysfs path.

  If the path refers to a directory, this returns `kn->priv`. If the path refers to a file (attribute), this returns the parent kobject (i.e., the parent node’s `priv`)

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - path – Sysfs path (absolute or relative to `/sys`)

  Returns:

    `struct kobject *` or `NULL`

drgn.helpers.linux.sysfs.sysfs_lookup(prog: drgn.Program, path: str) → Optional[drgn.Object]

  Look up the object represented by a sysfs path.

  Resolve the `struct kobject` corresponding to a sysfs entry and, when possible, return the kernel structure which contains that kobject.

  Note: This may return more specific types for other cases in the future.

  Depending on the kobject type, this helper may return:

  - `struct device *`

  - `struct class *`

  - `struct bus_type *`

  - `struct device_driver *`

  - `struct module_kobject *`

  If the kobject type does not correspond to a known container structure, the function returns the `struct kobject *`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - path – Sysfs path (absolute or relative to `/sys`)

  Returns:

    Corresponding container structure pointer or `struct kobject *` or `NULL`

drgn.helpers.linux.sysfs.sysfs_listdir(prog: drgn.Program, path: str) → List[bytes]

  List the children of a sysfs directory.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - path – Sysfs directory path (absolute or relative to `/sys`)

  Returns:

    List of child entry names

  Raises:

    ValueError – If path is not found or not a directory

drgn.helpers.linux.sysfs.kobject_path(kobj: drgn.Object) → bytes

  Return the sysfs path corresponding to a `struct kobject *`.

  Parameters:

    kobj – `struct kobject *`

  Returns:

    Absolute path in sysfs

### 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 a `tc` command means major handle 0x10.

  Parameters:

    - dev – `struct net_device *`

    - major – Qdisc major handle number.

  Returns:

    `struct Qdisc *` (`NULL` if 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.

### Timekeeping

The `drgn.helpers.linux.timekeeping` module provides helpers for timestamps.

Note

In core dumps, it is only possible to recover coarse timestamps, which are only updated once per tick (~1-10 ms). Therefore, only the `ktime_get_seconds()` and `ktime_get_coarse_ns()` families of functions are provided. These functions can also race with timekeeping updates and return a value with an error of up to 1 second.

drgn.helpers.linux.timekeeping.ktime_to_ns(kt: drgn.Object) → drgn.Object

  Convert a `ktime_t` to nanoseconds.

  Parameters:

    kt – `ktime_t`

  Returns:

    `s64`

drgn.helpers.linux.timekeeping.ktime_get_seconds(prog: drgn.Program) → drgn.Object

  Get the seconds component of the monotonic time (`CLOCK_MONOTONIC_COARSE`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `time64_t`

drgn.helpers.linux.timekeeping.ktime_get_coarse_ns(prog: drgn.Program) → drgn.Object

  Get the coarse monotonic time in nanoseconds (`CLOCK_MONOTONIC_COARSE`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `u64`

drgn.helpers.linux.timekeeping.ktime_get_real_seconds(prog: drgn.Program) → drgn.Object

  Get the seconds component of the real (wall) time (`CLOCK_REALTIME_COARSE`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `time64_t`

drgn.helpers.linux.timekeeping.ktime_get_coarse_real_ns(prog: drgn.Program) → drgn.Object

  Get the coarse real (wall) time in nanoseconds (`CLOCK_REALTIME_COARSE`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `u64`

drgn.helpers.linux.timekeeping.ktime_get_boottime_seconds(prog: drgn.Program) → drgn.Object

  Get the seconds component of the monotonic time since boot (coarse version of `CLOCK_BOOTTIME`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `time64_t`

drgn.helpers.linux.timekeeping.ktime_get_coarse_boottime_ns(prog: drgn.Program) → drgn.Object

  Get the the coarse monotonic time since boot in nanoseconds (coarse version of `CLOCK_BOOTTIME`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `u64`

drgn.helpers.linux.timekeeping.ktime_get_clocktai_seconds(prog: drgn.Program) → drgn.Object

  Get the seconds component of the International Atomic Time (coarse version of `CLOCK_TAI`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `time64_t`

drgn.helpers.linux.timekeeping.ktime_get_coarse_clocktai_ns(prog: drgn.Program) → drgn.Object

  Get the coarse International Atomic Time in nanoseconds (coarse version of `CLOCK_TAI`).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    `u64`

drgn.helpers.linux.timekeeping.uptime(prog: drgn.Program) → float

  Get the system uptime (as of the last tick) in fractional seconds.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.timekeeping.uptime_pretty(prog: drgn.Program) → str

  Get the system uptime as a human-readable string.

      >>> uptime_pretty()
      '1 day, 6 hours, 56 minutes, 40 seconds'

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

### Timers

The `drgn.helpers.linux.timer` module provides helpers for kernel timers, including the timer wheel and high-resolution timers (“hrtimers”).

drgn.helpers.linux.timer.timer_base_names(prog: drgn.Program) → Sequence[str]

  Get the names of the timer wheel bases used on this kernel.

  This depends on the kernel version and configuration. For example:

      >>> timer_base_names()
      ('BASE_LOCAL', 'BASE_GLOBAL', 'BASE_DEF')

  means that each CPU has 3 timer bases: `BASE_LOCAL` (0), `BASE_GLOBAL` (1), and `BASE_DEF` (2).

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.timer.timer_base_for_each(base: drgn.Object) → Iterator[drgn.Object]

  Iterate over every timer on a timer base.

      for cpu in for_each_online_cpu():
          for base in per_cpu(prog["timer_bases"], cpu):
              for timer in timer_base_for_each(base.address_of_()):
                  ...

  Parameters:

    base – `struct timer_base *`

  Returns:

    Iterator of `struct timer_list *` objects.

drgn.helpers.linux.timer.hrtimer_clock_base_for_each(clock_base: drgn.Object) → Iterator[drgn.Object]

  Iterate over every high-resolution timer on an hrtimer clock base.

      for cpu in for_each_online_cpu():
          for cpu_base in per_cpu(prog["hrtimer_bases"], cpu):
              for clock_base in cpu_base.clock_base:
                  for hrtimer in hrtimer_clock_base_for_each(clock_base.address_of_()):
                      ...

  Parameters:

    clock_base – `struct hrtimer_clock_base *`

  Returns:

    Iterator of `struct hrtimer *` objects.

### Users

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

drgn.helpers.linux.user.kuid_val(uid: Union[drgn.Object, drgn.IntegerLike]) → int

  Return the UID value of a `kuid_t`.

  Parameters:

    uid – `kuid_t` object. May also be an integer, in which case its value is returned.

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:

    - prog – Program, which may be omitted to use the default program argument.

    - uid – `kuid_t` object or integer.

  Returns:

    `struct user_struct *` (`NULL` if not found)

drgn.helpers.linux.user.for_each_user(prog: drgn.Program) → Iterator[drgn.Object]

  Iterate over all users in the system.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

  Returns:

    Iterator of `struct user_struct *` objects.

### Virtual Memory Statistics

The `drgn.helpers.linux.vmstat` module provides helpers for reading virtual memory statistics.

drgn.helpers.linux.vmstat.global_node_page_state(prog: drgn.Program, item: drgn.IntegerLike) → int

  Get the global value of a node VM statistic.

      >>> global_node_page_state(prog["NR_FILE_PAGES"])
      2257904

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - item – `enum node_stat_item`

drgn.helpers.linux.vmstat.zone_page_state(zone: drgn.Object, item: drgn.IntegerLike) → int

  Get the value of a zone VM statistic in a single zone.

  Parameters:

    - zone – `struct zone *`

    - item – `enum zone_stat_item`

drgn.helpers.linux.vmstat.global_zone_page_state(prog: drgn.Program, item: drgn.IntegerLike) → int

  Get the global value of a zone VM statistic.

      >>> global_zone_page_state(prog["NR_MLOCK"])
      1562

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - item – `enum zone_stat_item`

drgn.helpers.linux.vmstat.nr_free_pages(prog: drgn.Program) → int

  Get the number of free memory pages.

  Parameters:

    prog – Program, which may be omitted to use the default program argument.

drgn.helpers.linux.vmstat.global_numa_event_state(prog: drgn.Program, item: drgn.IntegerLike) → int

  Get the global value of a NUMA statistic.

  Note

  This is only valid if the kernel was compiled with `CONFIG_NUMA`. Before Linux 4.14, these items (e.g., `NUMA_HIT`) were zone statistics, so on kernel versions before 4.14, this is an alias of `global_zone_page_state()`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - item – `enum numa_stat_item` (or `enum zone_stat_item` on Linux < 4.14)

drgn.helpers.linux.vmstat.global_vm_event_state(prog: drgn.Program, item: drgn.IntegerLike) → int

  Get the global value of a virtual memory event statistic.

  Note

  This is only valid if the kernel was compiled with `CONFIG_VM_EVENT_COUNTERS`.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - item – `enum vm_event_item`

### Wait Queues

The `drgn.helpers.linux.wait` module provides helpers for working with wait queues (`wait_queue_head_t` and `wait_queue_entry_t`) from `include/linux/wait.h`.

Note

Since Linux 4.13, entries in a wait queue have type `wait_queue_entry_t`. Before that, the type was named `wait_queue_t`.

drgn.helpers.linux.wait.waitqueue_active(wq: drgn.Object) → bool

  Return whether a wait queue has any waiters.

  Parameters:

    wq – `wait_queue_head_t *`

drgn.helpers.linux.wait.waitqueue_for_each_entry(wq: drgn.Object) → Iterator[drgn.Object]

  Iterate over all entries in a wait queue.

  Parameters:

    wq – `wait_queue_head_t *`

  Returns:

    Iterator of `wait_queue_entry_t *` or `wait_queue_t *` objects depending on the kernel version.

drgn.helpers.linux.wait.waitqueue_for_each_task(wq: drgn.Object) → Iterator[drgn.Object]

  Iterate over all tasks waiting on a wait queue.

  Warning

  This comes from `wait_queue_entry_t::private`, which usually stores a task. However, some wait queue entries store a different pointer type, in which case this will return garbage.

  Parameters:

    wq – `wait_queue_head_t *`

  Returns:

    Iterator of `struct task_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 (see `xa_is_zero()`) will be returned as `NULL`.

  Returns:

    `void *` found entry, or `NULL` if 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 (see `xa_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`. If `xa_is_value()` returns `True`, 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()` and `xa_for_each()` when `advanced = 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 *`

## Experimental

The `drgn.helpers.experimental` package contains experimental helpers with no stability guarantees. They may change, move to another package, or be removed. They are not automatically imported by the CLI.

### Kmodify

The `drgn.helpers.experimental.kmodify` module provides experimental helpers for modifying the state of the running kernel. This works by loading a temporary kernel module, so the kernel must support loadable kernel modules (`CONFIG_MODULES=y`) and allow loading unsigned modules (`CONFIG_MODULE_SIG_FORCE=n`). It is currently only implemented for x86-64.

Warning

These helpers are powerful but extremely dangerous. Use them with care.

drgn.helpers.experimental.kmodify.write_memory(prog: drgn.Program, address: drgn.IntegerLike, value: bytes) → None

  Write a byte string to kernel memory.

      >>> os.uname().sysname
      'Linux'
      >>> write_memory(prog["init_uts_ns"].name.sysname.address_, b"Lol\0")
      >>> os.uname().sysname
      'Lol'

  Warning

  This attempts to detect writes to bad addresses and raise a `FaultError`, but this is best-effort and may still crash the kernel. Writing bad data can of course also cause a crash when the data is used. Additionally, this is not atomic, so the data may be accessed while it is partially written.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - address – Address to write to.

    - value – Byte string to write.

  Raises:

    FaultError – if the address cannot be written to

drgn.helpers.experimental.kmodify.set_bit(nr: drgn.IntegerLike, bitmap: drgn.Object) → None

  Atomically set a bit in kernel memory.

  Warning

  This attempts to detect bad addresses and raise a `FaultError`, but this is best-effort and may still crash the kernel. In particular, this function will crash the kernel if the target address is read-only. Writing an invalid bit can of course also cause a crash when the data is used.

  Parameters:

    - nr – Bit number.

    - bitmap – `unsigned long *`

drgn.helpers.experimental.kmodify.clear_bit(nr: drgn.IntegerLike, bitmap: drgn.Object) → None

  Atomically clear a bit in kernel memory.

  Warning

  The warnings about `set_bit()` also apply to `clear_bit()`.

  Parameters:

    - nr – Bit number.

    - bitmap – `unsigned long *`

drgn.helpers.experimental.kmodify.write_object(object: drgn.Object, value: Any, *, dereference: Optional[bool] = None) → None

  Write to an object in kernel memory.

      >>> os.system("uptime -p")
      up 12 minutes
      >>> write_object(prog["init_time_ns"].offsets.boottime.tv_sec, 1000000000)
      >>> os.system("uptime -p")
      up 3 decades, 1 year, 37 weeks, 1 hour, 59 minutes

  Bit fields are currently only supported if they are either byte-aligned or a single bit. Writes to a bit field are atomic with respect to other bit fields.

  Warning

  The warnings about `write_memory()` and `set_bit()` also apply to `write_object()`.

  Parameters:

    - object – Object to write to.

    - value – Value to write. This may be an `Object` or a Python value. Either way, it will be converted to the type of object.

    - dereference – If object is a pointer, whether to dereference it. If `True`, then write to the object pointed to by object (`*ptr = value`). If `False`, then write to the pointer itself (`ptr = value`). This is a common source of confusion, so it is required if object is a pointer.

  Raises:

    - ValueError – if object is not a reference object (i.e., its address is not known)

    - TypeError – if object is a pointer and dereference is not given

    - TypeError – if object is not a pointer and dereference is `True`

    - NotImplementedError – if object is a bit field that is not byte-aligned or a single bit

drgn.helpers.experimental.kmodify.call_function(prog: drgn.Program, func: Union[str, drgn.Object], *args: Any) → drgn.Object

  Call a function in the kernel.

      >>> task = find_task(99)
      >>> if task:
      ...     call_function("wake_up_process", task)
      ...
      (int)1

  Arguments can be either `Object`s or Python values. The function return value is returned as an `Object`:

      >>> # GFP_KERNEL isn't in the kernel debug info
      >>> # We have to use this trick to get it.
      >>> for flag in prog["gfpflag_names"]:
      ...     if flag.name.string_() == b"GFP_KERNEL":
      ...             GFP_KERNEL = flag.mask
      ...             break
      ...
      >>> # kmalloc() is actually a macro.
      >>> # We have to call the underlying function.
      >>> p = call_function("__kmalloc_noprof", 13, GFP_KERNEL)
      >>> p
      (void *)0xffff991701ef43c0
      >>> identify_address(p)
      'slab object: kmalloc-16+0x0'
      >>> call_function("kfree", p)
      (void)<absent>
      >>> identify_address(p)
      'free slab object: kmalloc-16+0x0'

  Variadic functions are also supported:

      >>> call_function("_printk", "Hello, world! %d\n", Object(prog, "int", 1234))
      (int)18
      >>> os.system("dmesg | tail -1")
      [ 1138.223004] Hello, world! 1234

  Constructed values can be passed by pointer using `pass_pointer()`:

      >>> sb = prog["init_fs"].root.mnt.mnt_sb
      >>> sb.s_shrink.scan_objects
      (unsigned long (*)(struct shrinker *, struct shrink_control *))super_cache_scan+0x0 = 0xffffffffbda4c487
      >>> sc = pass_pointer(Object(prog, "struct shrink_control",
      ...                   {"gfp_mask": GFP_KERNEL, "nr_to_scan": 100, "nr_scanned": 100}))
      >>> call_function(sb.s_shrink.scan_objects, sb.s_shrink, sc)
      (unsigned long)31

  If the function modifies the passed value, the `pass_pointer` object is updated:

      >>> sc.object
      (struct shrink_control){
              .gfp_mask = (gfp_t)3264,
              .nid = (int)0,
              .nr_to_scan = (unsigned long)1,
              .nr_scanned = (unsigned long)100,
              .memcg = (struct mem_cgroup *)0x0,
      }

  Note

  It is not possible to call some functions, including inlined functions and function-like macros. If the unavailable function is a wrapper around another function, sometimes the wrapped function can be called instead.

  Warning

  Calling a function incorrectly may cause the kernel to crash or misbehave in various ways.

  The function is called from process context. Note that the function may have context, locking, or reference counting requirements.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - func – Function to call. May be a function name, function object, or function pointer object.

    - args – Function arguments. `int`, `float`, and `bool` arguments are converted as “literals” with `Object(prog, value=...)`. `str` and `bytes` arguments are converted to `char` array objects. `pass_pointer` arguments are copied to the kernel, passed by pointer, and copied back.

  Returns:

    Function return value.

  Raises:

    - TypeError – if the passed arguments have incorrect types for the function

    - ObjectAbsentError – if the function cannot be called because it is inlined

    - LookupError – if a function with the given name is not found (possibly because it is actually a function-like macro)

drgn.helpers.experimental.kmodify.call_functions(prog: drgn.Program, calls: Sequence[Sequence[Any]]) → None

  Call multiple functions in the kernel.

  This is more efficient than calling `call_function()` multiple times because it only inserts one kernel module.

      >>> leaked_namespaces
      [Object(prog, 'struct net *', value=0xffff8f568869af80), ...]
      >>> call_functions([("netns_put", ns) for ns in leaked_namespaces])

  Function return values are ignored. Use `call_function()` if you need the return value.

  Warning

  See `call_function()` for warnings about calling kernel functions.

  Parameters:

    - prog – Program, which may be omitted to use the default program argument.

    - calls – List of calls, where each call is a tuple of `(func, *args)`. See `call_function()` for details on func and args.

class drgn.helpers.experimental.kmodify.pass_pointer(object: Any)

  Wrapper used to pass values to `call_function()` or `call_functions()` by pointer.

  Parameters:

    object – `Object` or Python value to wrap.

  object: Any

    Wrapped object. Updated to an `Object` containing the final value after the function call.