summaryrefslogtreecommitdiff
path: root/bird-gdb.py
diff options
context:
space:
mode:
Diffstat (limited to 'bird-gdb.py')
-rw-r--r--bird-gdb.py124
1 files changed, 61 insertions, 63 deletions
diff --git a/bird-gdb.py b/bird-gdb.py
index e11f9757..c53a3b55 100644
--- a/bird-gdb.py
+++ b/bird-gdb.py
@@ -1,6 +1,3 @@
-import itertools
-import functools
-
class BIRDPrinter:
def __init__(self, val):
self.val = val
@@ -29,7 +26,6 @@ class BIRDFValPrinter(BIRDPrinter):
"T_ENUM_RTS": "i",
"T_ENUM_BGP_ORIGIN": "i",
"T_ENUM_SCOPE": "i",
- "T_ENUM_RTC": "i",
"T_ENUM_RTD": "i",
"T_ENUM_ROA": "i",
"T_ENUM_NETTYPE": "i",
@@ -201,20 +197,12 @@ class BIRDList:
if str(self.tail_node["prev"].address) == '0x0':
raise Exception("List tail is NULL")
- def __iter__(self):
+ def walk(self, do):
cur = self.head
while cur.dereference() != self.tail_node:
- yield cur
+ do(cur)
cur = cur.dereference()["next"]
- def __len__(self):
- return sum([1 for _ in self])
-
- def __getitem__(self, key):
- for item in itertools.islice(self, key):
- return item
-
- raise KeyError("Not enough elements in list")
class BIRDListLength(gdb.Function):
"""Returns length of the list, as in
@@ -222,8 +210,13 @@ class BIRDListLength(gdb.Function):
def __init__(self):
super(BIRDListLength, self).__init__("list_length")
+ def count(self, _):
+ self.cnt += 1
+
def invoke(self, l):
- return len(BIRDList(l))
+ self.cnt = 0
+ BIRDList(l).walk(self.count)
+ return self.cnt
BIRDListLength()
@@ -232,11 +225,30 @@ class BIRDListItem(gdb.Function):
def __init__(self):
super(BIRDListItem, self).__init__("list_item")
+ class BLException(Exception):
+ def __init__(self, node, msg):
+ Exception.__init__(self, msg)
+ self.node = node
+
+ def count(self, node):
+ if self.cnt == self.pos:
+ raise self.BLException(node, "Node found")
+
+ self.cnt += 1
+
def invoke(self, l, n, t=None, item="n"):
- if t is None:
- return BIRDList(l)[n]
- else:
- return BIRD.skip_back(t, item, BIRDList(l)[n])
+ self.cnt = 0
+ self.pos = n
+ bl = BIRDList(l)
+ try:
+ bl.walk(self.count)
+ except self.BLException as e:
+ if t is None:
+ return e.node
+ else:
+ return BIRD.skip_back(t, item, e.node)
+
+ raise Exception("List too short")
BIRDListItem()
@@ -290,26 +302,19 @@ class BIRDLinPoolResource(BIRDResource):
self.lptype = gdb.lookup_type("struct linpool")
self.val = val.cast(self.lptype)
self.info = None
- self.std = self.ChunkList(self.val["first"])
- self.large = self.ChunkList(self.val["first_large"])
-
- class ChunkList:
- def __init__(self, val):
- self.val = val
-
- def __iter__(self):
- chunk = self.val
- while str(chunk) != 0x0:
- yield chunk
- chunk = chunk.dereference()["next"]
- def __len__(self):
- return sum([1 for _ in self])
+ def count_chunk(self, which):
+ cnt = 0
+ chunk = self.val[which]
+ while str(chunk) != '0x0':
+ cnt += 1
+ chunk = chunk.dereference()["next"]
+ return cnt
def parse(self):
self.info = {
- "std_chunks": len(self.std),
- "large_chunks": len(self.large),
+ "std_chunks": self.count_chunk("first"),
+ "large_chunks": self.count_chunk("first_large"),
}
def memsize(self):
@@ -334,13 +339,14 @@ class BIRDSlabResource(BIRDResource):
self.val = val.cast(self.slabtype)
self.info = None
+ def count_heads_item(self, item):
+ self.hcnt += 1
+ self.used += item.dereference().cast(self.slheadtype)["num_full"]
+
def count_heads(self, which):
self.hcnt = 0
self.used = 0
- for item in BIRDList(self.val[which + "_heads"]):
- self.hcnt += 1
- self.used += item.dereference().cast(self.slheadtype)["num_full"]
-
+ BIRDList(self.val[which + "_heads"]).walk(self.count_heads_item)
self.info[which + "_heads"] = self.hcnt
self.info[which + "_used"] = self.used
return (self.hcnt, self.used)
@@ -375,36 +381,25 @@ class BIRDSlabResource(BIRDResource):
f", {self.val['objs_per_slab']} objects of size {self.val['obj_size']} per head"
-class BIRDIOLoopResource(BIRDResource):
- def __init__(self, val):
- self.iolooptype = gdb.lookup_type("struct birdloop")
- self.val = val.cast(self.iolooptype)
- self.pages = self.val["pages"]
- self.page_size = gdb.lookup_symbol("page_size")[0].value()
-
- def memsize(self):
- return BIRDResourceSize(0, self.iolooptype.sizeof, self.pages['cnt'] * self.page_size)
-
- def __str__(self):
- return f"IO Loop {self.val.address} containing {self.pages['cnt']} free pages (min {self.pages['min']} max {self.pages['max']}), cleanup event {self.pages['cleanup'].dereference().address}: " + \
- ", ".join([ str(p) for p in BIRDList(self.pages["list"])])
-
-
class BIRDPoolResource(BIRDResource):
def __init__(self, val):
self.pooltype = gdb.lookup_type("struct pool")
self.resptrtype = gdb.lookup_type("struct resource").pointer()
+ self.page_size = gdb.lookup_symbol("page_size")[0].value()
self.val = val.cast(self.pooltype)
- self.inside = BIRDList(self.val["inside"])
+ self.items = None
- def __iter__(self):
- for val in self.inside:
- yield BIRDNewResource(val.cast(self.resptrtype).dereference())
+ def parse_inside(self, val):
+ self.items.append(BIRDNewResource(val.cast(self.resptrtype).dereference()))
- def __len__(self):
- return len(self.inside)
+ def parse(self):
+ self.items = []
+ BIRDList(self.val["inside"]).walk(self.parse_inside)
def memsize(self):
+ if self.items is None:
+ self.parse()
+
sum = BIRDResourceSize(0, self.pooltype.sizeof, 0)
# for i in self.items:
# sum += i.memsize()
@@ -412,17 +407,19 @@ class BIRDPoolResource(BIRDResource):
return sum
def __str__(self):
+ if self.items is None:
+ self.parse()
+
# for i in self.items:
# print(i)
- return f"Resource pool {self.val.address} \"{self.val['name'].string()}\" containing {len(self)} items"
+ return f"Resource pool {self.val.address} \"{self.val['name'].string()}\" containing {len(self.items)} items"
BIRDResourceMap = {
"mbl_memsize": BIRDMBResource,
"pool_memsize": BIRDPoolResource,
"lp_memsize": BIRDLinPoolResource,
"slab_memsize": BIRDSlabResource,
- "birdloop_memsize": BIRDIOLoopResource,
}
def BIRDNewResource(res):
@@ -442,13 +439,14 @@ class BIRDResourcePrinter(BIRDPrinter):
def __init__(self, val):
super(BIRDResourcePrinter, self).__init__(val)
self.resource = BIRDNewResource(val)
+ self.resource.parse()
self.resourcetype = gdb.lookup_type("struct resource")
if type(self.resource) == BIRDPoolResource:
self.children = self.pool_children
def pool_children(self):
- return iter([ ("\n", i.val.cast(self.resourcetype)) for i in self.resource ])
+ return iter([ ("\n", i.val.cast(self.resourcetype)) for i in self.resource.items ])
def to_string(self):
return f"[ {str(self.resource.memsize())} ] {str(self.resource)}"