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 invoked C macro__cpu_to_le32
-
pykdump.API.le32_to_cpu(ulong)¶ Interface to
__le32_to_cpuC macro- Parameters
ulong – unsigned integer
- Returns
converts Python integer to C
ulongval, applies__le32_to_cpu(val)and returns a Python integer
-
pykdump.API.le16_to_cpu(uint)¶ Similar to
le32_to_cpu()but invoked C macro__le16_to_cpu
-
pykdump.API.sLong(i)¶ In C, the same bits sequnce 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 longand 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 documentation
Reading Memory for details about possible memory types. In
case you need to use these types, you should import them from
crash module explicitly.
Several low-level subroutines are automatically imported from
crash module (implemented in C), you do not
need to import them yourself. They are documented in the description
of 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 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 Linux kernel to define lists:
using ‘struct list_head’ and embedding it into another structure
using
nextand/orprevpointers embedded directly in structure, without anylist_head
-
pykdump.API.LH_isempty(lh)¶ - Parameters
lh –
list headaddress orStructResultobject 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_headembedded, we can create an instance of this class and then use it for iterationslh is address of
list_headIf sname is specified, this is a string with structure name embedding our
list_headmaxel is the maximal 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 return a list of
list_headresultsif sname is specified, we should use as an iterator not the object itself, but rather
obj.fieldnamewhere fieldname is the name of structure field containinglist_head. In this case, we retirn the 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 (can be changed)
inchead – whether to include list head itself in the output or not
warn – if True, print a warning when 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 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
StructResultobject forstruct hlist_nodemember – a string with the field name embedded in out 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 iIf dimension specified is zero, return a generator instead
- Parameters
suname – a string with struct/union name
startaddr – address of the forst element
dim – an integer, either number of elements to read or 0
-
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 migh display errors. For example, you try to execute an invalid command, or page is missing in vmcore. Sometimes you want to suppress displaying this errors. This can be dome using the following context manager:
-
class
pykdump.API.SuppressCrashErrors(outfile='/dev/null')¶ A context manager to redirect or suppress internal crash/GDB errors display
An example:
with SuppressCrashErrors(): try: print("test", exec_crash_command("set scope st_create")) except: print("Exception caught")