171 lines
3.1 KiB
Text
171 lines
3.1 KiB
Text
// trace user malloc pool - trace malloc, realloc, and free calls
|
|
// if trumpsbrk is set, we trace sbrkalloc and sbrkmerge too.
|
|
|
|
_stoprunning = 0;
|
|
trumphexaddrs = 0;
|
|
trumpsbrk = 0;
|
|
|
|
defn stopped(pid) {
|
|
local l;
|
|
local pc;
|
|
pc = *PC;
|
|
if notes then {
|
|
if (notes[0]!="sys: breakpoint") then
|
|
{
|
|
print(pid,": ",reason(*TRAP),"\t");
|
|
print(fmt(pc,97),"\t",fmt(pc,105),"\n");
|
|
print("Notes pending:\n");
|
|
l = notes;
|
|
while l do
|
|
{
|
|
print("\t",head l,"\n");
|
|
l = tail l;
|
|
}
|
|
_stoprunning = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
defn printstack() {
|
|
local frame, stk, pcs, lst, x;
|
|
|
|
pcs = {*PC};
|
|
stk = strace(*PC,*SP,0);
|
|
while stk do {
|
|
pcs = append pcs, stk[0][1];
|
|
stk = tail stk;
|
|
}
|
|
|
|
print(" #");
|
|
lst = pcs;
|
|
while lst do {
|
|
if trumphexaddrs != 0 then
|
|
x = lst[0]\X;
|
|
else
|
|
x = lst[0]\a;
|
|
print(" src(", x, ");");
|
|
lst = tail lst;
|
|
}
|
|
print("\n");
|
|
}
|
|
|
|
defn setuptrump() {
|
|
mallocPC = malloc;
|
|
malloczPC = mallocz;
|
|
freePC = free;
|
|
reallocPC = realloc;
|
|
sbrkallocPC = sbrkalloc;
|
|
sbrkmergePC = sbrkmerge;
|
|
|
|
// linker might fill delay slot with first instruction
|
|
if objtype == "mips" then {
|
|
mallocPC = mallocPC+4;
|
|
malloczPC = malloczPC+4;
|
|
freePC = freePC+4;
|
|
reallocPC = reallocPC+4;
|
|
sbrkallocPC = sbrkallocPC+4;
|
|
sbrkmergePC = sbrkmergePC+4;
|
|
}
|
|
|
|
bpset(mallocPC);
|
|
bpset(malloczPC);
|
|
bpset(freePC);
|
|
bpset(reallocPC);
|
|
if trumpsbrk then {
|
|
bpset(sbrkallocPC);
|
|
bpset(sbrkmergePC);
|
|
}
|
|
}
|
|
|
|
defn cleantrump() {
|
|
stop(pid);
|
|
|
|
bpdel(mallocPC);
|
|
bpdel(malloczPC);
|
|
bpdel(freePC);
|
|
bpdel(reallocPC);
|
|
bpdel(sbrkallocPC);
|
|
bpdel(sbrkmergePC);
|
|
}
|
|
|
|
defn trumpflush() {
|
|
stop(pid); // already stopped, but flushes output
|
|
}
|
|
|
|
defn new() {
|
|
bplist = {};
|
|
newproc(progargs);
|
|
bpset(follow(main)[0]);
|
|
cont();
|
|
bpdel(*PC);
|
|
// clear the hang bit, which is left set by newproc, so programs we fork/exec don't hang
|
|
printto("/proc/"+itoa(pid)+"/ctl", "nohang");
|
|
}
|
|
|
|
defn trumpfninfo() {
|
|
local arg0, arg1, stk, retpc, params;
|
|
|
|
stk = strace(*PC, *SP, 0);
|
|
retpc = stk[0][1];
|
|
params = stk[0][2];
|
|
arg0 = params[0][1];
|
|
arg1 = 0;
|
|
if tail params != {} then
|
|
arg1 = params[1][1];
|
|
return {arg0, arg1, retpc};
|
|
}
|
|
|
|
defn trumpretval() {
|
|
if objtype=="386" || objtype=="amd64" then
|
|
return *AX;
|
|
if objtype=="mips" then
|
|
return *R1;
|
|
if objtype=="power" || objtype=="arm" then
|
|
return *R0;
|
|
}
|
|
|
|
defn trump() {
|
|
local arg0, arg1, pc, ret, x;
|
|
|
|
stop(pid);
|
|
_stoprunning = 0;
|
|
setuptrump();
|
|
while !_stoprunning do {
|
|
cont();
|
|
if notes[0]!="sys: breakpoint" then {
|
|
cleantrump();
|
|
return {};
|
|
}
|
|
|
|
pc = *PC;
|
|
x = trumpfninfo();
|
|
arg0 = x[0];
|
|
if pc == reallocPC || pc == sbrkmergePC then
|
|
arg1 = x[1];
|
|
bpset(x[2]);
|
|
cont();
|
|
bpdel(x[2]);
|
|
ret = trumpretval();
|
|
if pc == mallocPC then
|
|
print(ret\X, " malloc ", arg0\D);
|
|
if pc == malloczPC then
|
|
print(ret\X, " mallocz ", arg0\D);
|
|
if pc == freePC then
|
|
print(arg0\X, " free");
|
|
if pc == reallocPC then
|
|
print(ret\X, " realloc ", arg0\X, " ", arg1\D);
|
|
if pc == sbrkallocPC then
|
|
print(ret\X, " sbrkalloc ", arg0\D);
|
|
if pc == sbrkmergePC then
|
|
print("sbrkmerge ", arg0\X, " ", arg1\X, " = ", ret\D);
|
|
printstack();
|
|
trumpflush();
|
|
}
|
|
}
|
|
|
|
defn untrump() {
|
|
cleantrump();
|
|
start(pid);
|
|
}
|
|
|
|
print("/sys/lib/acid/trump");
|