[tools] Commit memory debug (et al) tooling
These are some changes I made to debug tooling while tracking down the bugfix in the previous commit. Each `scripts/debug_*_alloc.gdb` script has gdb output a `*_allocs.txt` file, which in turn can be parsed by the `scripts/parse_*_allocs.py` script to find errors.
This commit is contained in:
62
scripts/parse_heap_allocs.py
Executable file
62
scripts/parse_heap_allocs.py
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from bisect import bisect_left, insort
|
||||
from operator import attrgetter
|
||||
|
||||
by_start = attrgetter('start')
|
||||
|
||||
class alloc:
|
||||
def __init__(self, start, size):
|
||||
self.start = start
|
||||
self.size = size
|
||||
|
||||
@property
|
||||
def end(self):
|
||||
return self.start + self.size
|
||||
|
||||
def overlaps(self, other):
|
||||
return other.start < self.end and other.end > self.start
|
||||
|
||||
def __str__(self):
|
||||
return f"[{self.start:012x} - {self.end:012x}]"
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.start > other.start
|
||||
|
||||
def add_alloc(allocs, addr, length):
|
||||
a = alloc(addr, length)
|
||||
for existing in allocs:
|
||||
if a.overlaps(existing):
|
||||
print(f"ERROR: allocation {a} overlaps existing {existing}")
|
||||
insort(allocs, a)
|
||||
|
||||
def remove_alloc(allocs, addr):
|
||||
a = alloc(addr, 0)
|
||||
i = bisect_left(allocs, a)
|
||||
if len(allocs) > i and allocs[i].start == addr:
|
||||
del allocs[i]
|
||||
else:
|
||||
print(f"ERROR: freeing unallocated {a}")
|
||||
|
||||
def parse_line(allocs, line):
|
||||
args = line.strip().split()
|
||||
match args:
|
||||
case ['+', addr, length]:
|
||||
add_alloc(allocs, int(addr, base=16), int(length))
|
||||
case ['-', addr]:
|
||||
remove_alloc(allocs, int(addr, base=16))
|
||||
case _:
|
||||
pass
|
||||
|
||||
def parse_file(f):
|
||||
allocs = []
|
||||
for line in f.readlines():
|
||||
parse_line(allocs, line)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) > 1:
|
||||
with open(sys.argv[1]) as f:
|
||||
parse_file(f)
|
||||
else:
|
||||
parse_file(sys.stdin)
|
||||
Reference in New Issue
Block a user