9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] trump
@ 2001-10-17 18:44 Russ Cox
  0 siblings, 0 replies; only message in thread
From: Russ Cox @ 2001-10-17 18:44 UTC (permalink / raw)
  To: 9fans

Here's trump, inspired by truss.  It's much nicer than
using debugmalloc (see debugmalloc(2)) for the
same reason that leak is better than showleaks:
you don't have to relink the affected programs, and
you don't have to arrange for magic environment variables
to be set.  I wrote trump to debug a memory leak in upas/fs
that only happened when I ran upas/fs under imap4d via the
imap4 module in upas/fs:

upas/fs -imap-> imap4d -exec-> upas/fs -9P-> /mail/box/rsc/mbox

The second upas/fs had the leak, and because imap4d
has various authentication in it, actually controlling
the startup environment of the second upas/fs is trickier
than I managed to figure out.

It was much easier to start the whole thing and then 
attach with acid.  Another nice thing about doing it in
acid is that you get better stack traces for less work:
libdebugmalloc only gets you numeric stack traces 
and only on a 386, while this works anywhere.

Ironically, running this on programs that allocate a LOT
tickles a memory leak in acid that I haven't tracked down yet.

Stealing an example from the acid paper, here's trump
running on /bin/sort.

	g% acid -l trump /bin/sort
	/bin/sort:386 plan 9 executable
	
	/sys/lib/acid/port
	/sys/lib/acid/trump
	/sys/lib/acid/386
	acid: new()
	acid: trump()
	0x0000f3d0 malloc 400000 # src(main+0x9e); src(_main+0x31);
	now
	0x00070eb8 malloc 15 # src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	0x00070ef8 realloc 0x0000000e 0 # src(newline+0x126); src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	is
	0x00070f38 malloc 14 # src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	0x00070f78 realloc 0x0000000d 0 # src(newline+0x126); src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	the
	0x00070fb8 malloc 15 # src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	0x00070ff8 realloc 0x0000000e 0 # src(newline+0x126); src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	time
	0x00071038 malloc 16 # src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	0x00071078 realloc 0x0000000f 0 # src(newline+0x126); src(dofile+0xed); src(main+0x9e); src(_main+0x31);
	<ctl-d>is
	now
	the
	time
	<stdin>:4: (error) msg: pid=432 startstop: process exited
	acid: 

Same minimanual as truss except s/truss/trump/.
Unlike truss, this doesn't work on APE programs.
Wouldn't be hard, just haven't done it.

Russ

# To unbundle, run this file
echo /sys/lib/acid/trump
sed 's/.//' >/sys/lib/acid/trump <<'//GO.SYSIN DD /sys/lib/acid/trump'
-// 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 = {};
-	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" then
-		return *AX;
-	if objtype=="mips" then
-		return *R1;
-	if objtype=="power" || objtype=="alpha" 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");
//GO.SYSIN DD /sys/lib/acid/trump



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-10-17 18:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-17 18:44 [9fans] trump Russ Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).