diff options
author | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
---|---|---|
committer | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
commit | c63f340d90800895f007de64b7d2d14624263331 (patch) | |
tree | 2c0849fa597dd6da831c8707b6f2603403778d7b /python/weenix/kmem.py |
Created student weenix repository
Diffstat (limited to 'python/weenix/kmem.py')
-rw-r--r-- | python/weenix/kmem.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/python/weenix/kmem.py b/python/weenix/kmem.py new file mode 100644 index 0000000..8f8a6f2 --- /dev/null +++ b/python/weenix/kmem.py @@ -0,0 +1,109 @@ +import gdb +import weenix + +import weenix.list + +PAGE_SIZE = 4096 + +_uint32_type = gdb.lookup_type("uint32_t") +_uintptr_type = gdb.lookup_type("uintptr_t") +_slab_type = gdb.lookup_type("struct slab") +_allocator_type = gdb.lookup_type("struct slab_allocator") +_bufctl_type = gdb.lookup_type("struct slab_bufctl") +_void_type = gdb.lookup_type("void") + +# for Python 3 compatibility, where xrange is done away with +try: + xrange +except NameError: + xrange = range + +class Slab: + + def __init__(self, alloc, val): + self._alloc = alloc + if (val.type.code == gdb.TYPE_CODE_PTR): + self._value = val.cast(_slab_type.pointer()).dereference() + else: + self._value = val.cast(_slab_type) + + def objs(self, typ=None): + next = self._value["s_addr"] + for i in xrange(int(self._alloc["sa_slab_nobjs"])): + bufctl = (next.cast(_uintptr_type) + + self._alloc["sa_objsize"]).cast(_bufctl_type.pointer()) + if (bufctl.dereference()["u"]["sb_slab"] == self._value.address): + # if redzones are in effect we need to skip them + if (int(next.cast(_uint32_type.pointer()).dereference()) == 0xdeadbeef): + value = (next.cast(_uint32_type.pointer()) + 1).cast(_void_type.pointer()) + else: + value = next + + if (typ != None): + yield value.cast(typ.pointer()) + else: + yield value + + next = (next.cast(_uintptr_type) + + self._alloc["sa_objsize"] + + _bufctl_type.sizeof).cast(_void_type.pointer()) + +class SlabAllocator: + + def __init__(self, val): + if (val.type.code == gdb.TYPE_CODE_PTR): + self._value = val.cast(_allocator_type.pointer()).dereference() + else: + self._value = val.cast(_allocator_type) + + def name(self): + return self._value["sa_name"].string() + + def size(self): + return int(self._value["sa_objsize"]) + + def slabs(self): + next = self._value["sa_slabs"] + while (next != 0): + yield Slab(self._value, next.dereference()) + next = next.dereference()["s_next"] + + def objs(self, typ=None): + for slab in self.slabs(): + for obj in slab.objs(typ): + yield obj + + def __str__(self): + res = "name: {0}\n".format(self.name()) + res += "slabcount: {0}\n".format(len(list(self.slabs()))) + res += "objsize: {0}\n".format(self.size()) + res += "objcount: {0}".format(len(list(self.objs()))) + return res + +def allocators(): + next = gdb.parse_and_eval("slab_allocators") + while (next != 0): + yield SlabAllocator(next.dereference()) + next = next.dereference()["sa_next"] + +def allocator(name): + for alloc in allocators(): + if name == alloc.name(): + return alloc + raise KeyError(name) + +def pagesize(): + return PAGE_SIZE + +def freepages(): + freepages = dict() + for pagegroup in weenix.list.load("pagegroup_list", "struct pagegroup", "pg_link"): + freelist = pagegroup.item()["pg_freelist"] + for order in xrange(freelist.type.sizeof // freelist.type.target().sizeof): + psize = (1 << order) * PAGE_SIZE + count = len(weenix.list.load(freelist[order])) + if (order in freepages): + freepages[order] += count + else: + freepages[order] = count + return freepages |