raddr = *R31;
bpset(raddr);
stk = strace(*PC, *SP); // Save a copy of the stack up to the malloc
cont(); // Continue until malloc returns
bpdel(raddr);
defn pentry(s)
{
local sno;
local blst;
local gotone;
local size;
gotone = 0;
blst = blocklist;
flst = framelist;
while blst do {
sno = head flst;
if sno == s then {
addr = fmt(head blst, 'X');
size = 1<<*(addr-12);
// print(addr, "of ", fmt(size, 'D'), "bytes\n");
gotone = gotone + size;
}
blst = tail blst;
flst = tail flst;
}
return gotone;
}
defn leak()
{
local n;
local sz;
n = 0;
while n < nstack do {
sz = pentry(n);
if sz then {
print("Lost a total of ", fmt(sz, 'D'), "bytes from:\n");
mstack(stacks[n]);
}
n = n+1;
}
}
defn scanmem(start, end)
{
local n;
start = fmt(start, 'X');
while start < end do {
n = match(*start, blocklist);
if n >= 0 then {
blocklist = delete blocklist, n;
framelist = delete framelist, n;
}
start++;
}
}
defn mstack(stk)
{
while stk do {
frame = head stk;
print("\t", fmt(frame[0], 'a'), "() ");
print(pcfile(frame[0]), ":", pcline(frame[0]));
print("called from ", fmt(frame[1], 'a'), " ");
pfl(frame[1]);
stk = tail stk;
}
}
defn gotfree()
{
local n;
local addr;
addr = *R1; // We know the first parameter is register R1
if addr == 0 then
return {};
n = match(addr, blocklist);
if n < 0 then {
print("free(", addr, ") called with bad pointer:\n");
stk();
return {};
}
blocklist = delete blocklist, n;
framelist = delete framelist, n;
}