xref: /plan9/rc/bin/leak (revision 7c70c028d2d46a27a61ae88e6df0eb0935d9da7a)
159cc4ca5SDavid du Colombier#!/bin/rc
259cc4ca5SDavid du Colombier
359cc4ca5SDavid du Colombierrfork e
459cc4ca5SDavid du Colombier
5*7c70c028SDavid du Colombierflagfmt='a,b,c,d,s,f binary,r res,x width'
684cb9422SDavid du Colombierargs='name | pid list'
784cb9422SDavid du Colombierif(! ifs=() eval `{aux/getflags $*} || ~ $#* 0){
884cb9422SDavid du Colombier	aux/usage
959cc4ca5SDavid du Colombier	exit usage
1059cc4ca5SDavid du Colombier}
1159cc4ca5SDavid du Colombier
12*7c70c028SDavid du Colombierconflicting=($flagb $flagc $flags)
13*7c70c028SDavid du Colombierif(~ $#conflicting 2 || ~ $#conflicting 3){
14*7c70c028SDavid du Colombier	echo 'can only use one of -b, -c or -s' >[1=2]
1580ee5cbfSDavid du Colombier	exit usage
1680ee5cbfSDavid du Colombier}
1780ee5cbfSDavid du Colombier
1884cb9422SDavid du Colombierleakflags=()
1984cb9422SDavid du Colombierif(~ $#flags 1)
2084cb9422SDavid du Colombier	leakflags=($leakflags -s)
21*7c70c028SDavid du Colombierif(~ $#flaga 1)
22*7c70c028SDavid du Colombier	leakflags=($leakflags -a)
23*7c70c028SDavid du Colombierif(~ $#flagc 1)
24*7c70c028SDavid du Colombier	leakflags=($leakflags -c)
25*7c70c028SDavid du Colombierif(~ $#flagd 1)
26*7c70c028SDavid du Colombier	leakflags=($leakflags -d)
2784cb9422SDavid du Colombierif(~ $#flagf 1)
2884cb9422SDavid du Colombier	leakflags=($leakflags -f $flagf)
2984cb9422SDavid du Colombier
3084cb9422SDavid du Colombieracidleakflags=()
3184cb9422SDavid du Colombierif(~ $#flagb 1)
3284cb9422SDavid du Colombier	acidleakflags=($acidleakflags -b)
3384cb9422SDavid du Colombierif(~ $#flagr 1)
3484cb9422SDavid du Colombier	acidleakflags=($acidleakflags -r $flagr)
3584cb9422SDavid du Colombierif(~ $#flagx 1)
3684cb9422SDavid du Colombier	acidleakflags=($acidleakflags -x $flagx)
3780ee5cbfSDavid du Colombier
3859cc4ca5SDavid du Colombierif(! test -d /proc/$1) {
3980ee5cbfSDavid du Colombier	# x=`{psu | awk '$NF=="'$1'" {print $2}'}
4080ee5cbfSDavid du Colombier	x=`{psu | grep ' '$1'$' | sed 's/^[^ ]+ +([0-9]+).*/\1/'}
4159cc4ca5SDavid du Colombier	if(~ $#x 0) {
4259cc4ca5SDavid du Colombier		echo 'no processes named '$1 >[1=2]
4359cc4ca5SDavid du Colombier		exit usage
4459cc4ca5SDavid du Colombier	}
4584cb9422SDavid du Colombier	echo leak $leakflags $acidleakflags $x
4659cc4ca5SDavid du Colombier	exit
4759cc4ca5SDavid du Colombier}
4859cc4ca5SDavid du Colombier
4984cb9422SDavid du Colombierpidlist=`{echo $"* | tr ' ' ,}
5059cc4ca5SDavid du Colombier
51*7c70c028SDavid du Colombierecho 'leakdump({'$pidlist'})' | acid -lpool -lleak $1 $flagf |
52*7c70c028SDavid du Colombier{
53*7c70c028SDavid du Colombier	if(~ $#flaga 1 && ~ $#flagd 1)
54*7c70c028SDavid du Colombier		grep 'block|free'
55*7c70c028SDavid du Colombier	if not
56*7c70c028SDavid du Colombier	if(~ $#flaga 1)
57*7c70c028SDavid du Colombier		grep block
58*7c70c028SDavid du Colombier	if not
59*7c70c028SDavid du Colombier	if(~ $#flagd 1)
60*7c70c028SDavid du Colombier		grep free
61*7c70c028SDavid du Colombier	if not
62*7c70c028SDavid du Colombier		aux/acidleak $acidleakflags $flagf
63*7c70c028SDavid du Colombier} |
6459cc4ca5SDavid du Colombier{
6584cb9422SDavid du Colombier	if(~ $#flags 1)
663ff48bf5SDavid du Colombier		awk '{print $4}' |
6780ee5cbfSDavid du Colombier			sort | uniq -c | sort -nr |
6859cc4ca5SDavid du Colombier			sed 's! *(.*) (0x.*)!src(\2); // \1!'
6959cc4ca5SDavid du Colombier	if not
70*7c70c028SDavid du Colombier	if(~ $#flagc 1)
71*7c70c028SDavid du Colombier		awk 'BEGIN {
72*7c70c028SDavid du Colombier				for(i=0; i<16; i++)
73*7c70c028SDavid du Colombier					_unhex[sprintf("%x", i)] = _unhex[sprintf("%X", i)] = i
74*7c70c028SDavid du Colombier			}
75*7c70c028SDavid du Colombier			function unhex(s, i, v) {
76*7c70c028SDavid du Colombier				sub("^0[xX]0*","",s)
77*7c70c028SDavid du Colombier				for (i=1; i<=length(s); i++)
78*7c70c028SDavid du Colombier					v = v*16 + _unhex[substr(s,i,1)]
79*7c70c028SDavid du Colombier				return v
80*7c70c028SDavid du Colombier			}
81*7c70c028SDavid du Colombier			{	sum[$4] += unhex($3);
82*7c70c028SDavid du Colombier				count[$4]++;
83*7c70c028SDavid du Colombier				alloc[$4] = $6;
84*7c70c028SDavid du Colombier			}
85*7c70c028SDavid du Colombier			END {
86*7c70c028SDavid du Colombier				for (v in sum) {
87*7c70c028SDavid du Colombier					printf("src(%s);\t// %d\t%d\t%d\t%s\n", v, sum[v], count[v], sum[v] / count[v], alloc[v])
88*7c70c028SDavid du Colombier					total += sum[v]
89*7c70c028SDavid du Colombier				}
90*7c70c028SDavid du Colombier				printf("// %d\n", total);
91*7c70c028SDavid du Colombier			}
92*7c70c028SDavid du Colombier		'  | sort -nr +2
93*7c70c028SDavid du Colombier	if not
9459cc4ca5SDavid du Colombier		cat
9559cc4ca5SDavid du Colombier}
96