pykdump.API
Main Package¶
This module provides everything necessary to write PyKdump programs. It imports other modules as needed.
Conversion of Integers¶
Python integers are always signed and have arbitrary precision. As a result, they do not behave in the same way as in C, e.g. they do not overflow. So to emulate C behavior, we need to use special functions.
- pykdump.API.cpu_to_le32(uint)¶
Similar to
le32_to_cpu()
but invokes C macro__cpu_to_le32
- pykdump.API.le32_to_cpu(ulong)¶
Interface to
__le32_to_cpu
C macro- Parameters:
ulong -- unsigned integer
- Returns:
converts Python integer to C
ulong
val, applies__le32_to_cpu(val)
and returns a Python integer
- pykdump.API.le16_to_cpu(uint)¶
Similar to
le32_to_cpu()
but invokes C macro__le16_to_cpu
- pykdump.API.sLong(i)¶
In C, the same bit sequence can represent either signed or unsigned integer. In Python, there is no native unsigned integer. This subroutine lets you convert a Python integer to signed assuming that integer size is that for long type of this architecture.
- Parameters:
i -- Python integer of any size/value
- Returns:
process
sizeof(long)
lower bits of provided integer as Cunsigned long
and return this value assigned long
An example:
l = 0xffffffffffffffff print(l, sLong(l)) # Prints 18446744073709551615 -1
- pykdump.API.unsigned16(i)¶
- Parameters:
i -- a Python integer
- Returns:
i & 0xffff
- pykdump.API.unsigned32(i)¶
- Parameters:
i -- a Python integer
- Returns:
i & 0xffffffff
- pykdump.API.unsigned64(i)¶
- Parameters:
i -- a Python integer
- Returns:
i & 0xffffffffffffffff
Reading Memory¶
There are different types of memory. See Reading Memory for details about
possible memory types. If you need to use these types, you should import them from
the crash
module explicitly.
Several low-level subroutines are automatically imported from
the crash
module (implemented in C); you do not
need to import them yourself. They are documented in the description
of the crash
module.
- pykdump.API.mem2long(bytestr, signed, array)¶
see
crash.mem2long()
- pykdump.API.readmem(addr, size[, mtype])¶
see
crash.readmem()
Reading Integers¶
- pykdump.API.readInt(addr, size[, signedvar[, mtype]])¶
Given an address, read an integer of given size
See
crash.readInt()
- pykdump.API.readPtr(addr[, mtype])¶
Assuming that addr contains a pointer, read the pointer value.
See
crash.readPtr()
- pykdump.API.readS32(addr)¶
- Parameters:
addr -- address to read from
- Returns:
read 4 bytes, intepret it as signed
- pykdump.API.readS64(addr)¶
- Parameters:
addr -- address to read from
- Returns:
read 8 bytes, intepret it as signed
- pykdump.API.readU8(addr)¶
- Parameters:
addr -- address to read from
- Returns:
read 1 byte, intepret it as unsigned
- pykdump.API.readU16(addr)¶
- Parameters:
addr -- address to read from
- Returns:
read 2 byte, intepret it as unsigned
- pykdump.API.readU32(addr)¶
- Parameters:
addr -- address to read from
- Returns:
read 4 bytes, intepret it as unsigned
- pykdump.API.readU64(addr)¶
- Parameters:
addr -- address to read from
- Returns:
read 8 bytes, intepret it as unsigned
Working with Lists¶
There are several standard ways in the Linux kernel to define lists:
using 'struct list_head' and embedding it into another structure
using
next
and/orprev
pointers embedded directly in a structure, without anylist_head
- pykdump.API.LH_isempty(lh)¶
- Parameters:
lh --
list head
address orStructResult
object forlist_head
- Returns:
in boolean context, evaluates to True (when list head is empty) or False
- pykdump.API.list_for_each_entry(start, offset=0, maxel=None, warn=True)¶
Another name for
readListByHead()
- class pykdump.API.ListHead(lh, sname=None, maxel=None, warn=True)¶
To read a list of structures with
list_head
embedded, we can create an instance of this class and then use it for iterations:lh is the address of a
list_head
.If sname is specified, this is a string with structure name embedding our
list_head
.maxel is the maximum number of elements to traverse.
warn specifies whether we would like to see warnings if we reach the maxel limit while iterating.
An object created can be used in two ways:
if sname was not specified, we should use as an iterator the object itself, and iterations return a list of
list_head
results.if sname is specified, we should use as an iterator not the object itself, but rather
obj.fieldname
where fieldname is the name of the structure field containinglist_head
. In this case, we return a list of structures of sname type.
For example, in C we have
static LIST_HEAD(cache_list); struct cache_detail { struct module * owner; int hash_size; struct cache_head ** hash_table; ... struct list_head others;
Traversing this list in Python:
cache_list = ListHead(sym2addr("cache_list"), "struct cache_detail") for c in cache_list.others: if (c.name == cname): details = c break
- pykdump.API.readBadList(start, offset=0, maxel=_MAXEL, inchead=True)¶
Similar to
readList()
but in case we are interested in partial lists even when there are low-level errors.- Returns:
a tuple (partiallist, error/None)
- pykdump.API.readList((start, offset=0, maxel = None, inchead = True, warn = True)¶
- Parameters:
start -- address of first structure
offset -- offset of the pointer to the next structure in the list
maxel -- maximum number of elements to follow (to limit the number of found elements). If not defined, uses the default value (which can be changed).
inchead -- whether to include the list head itself in the output or not
warn -- if True, print a warning when the maximum number of elements is reached
- pykdump.API.readListByHead(start, offset=0, maxel=None, warn=True)¶
- Parameters:
start -- address of first structure
offset -- offset of the pointer to the next structure in the list
maxel -- maximum number of elements to follow (to limit the number of found elements). If not defined, continues indefinitely.
warn -- if True, print a warning when the maximum number of elements is reached
Working with Hash-Lists¶
- pykdump.API.hlist_for_each_entry(emtype, head, member)¶
Traverse hlist_node hash-lists, e.g.
hlist_for_each_entry("struct xfrm_policy", table, "bydst")
forstruct xfrm_policy { possible_net_t xp_net; struct hlist_node bydst; struct hlist_node byidx; ...
- Parameters:
emtype -- a string with struct name
head -- a
StructResult
object forstruct hlist_node
member -- a string with the field name embedded in our main struct
- pykdump.API.getFullBuckets(start, bsize, items, chain_off=0)¶
Struct Lists and Arrays¶
- pykdump.API.readSUArray(suname, startaddr, dim=0)¶
Read an array of structs/unions given the structname, start, and dimension.
Normally a list with dim elements is returned, but if the dimension specified is zero, return a generator instead.
- Parameters:
suname -- a string with struct/union name
startaddr -- address of the first element
dim -- an integer, either the number of elements to read or zero
- pykdump.API.readSUListFromHead(headaddr, listfieldname, mystruct, maxel=None, inchead=False, warn=True)¶
- pykdump.API.readStructNext(shead, nextname, maxel=None, inchead=True)¶
Suppressing Internal Crash/GDB Messages¶
When you execute crash/GDB commands, they might display errors, e.g. if you try to execute an invalid command, or a page is missing in the vmcore. Sometimes you may want to suppress such error messages. This can be done using the following context manager:
- class pykdump.API.SuppressCrashErrors(outfile='/dev/null')¶
A context manager to redirect or suppress internal crash/GDB error messages
An example:
with SuppressCrashErrors(): try: print("test", exec_crash_command("set scope st_create")) except: print("Exception caught")