xref: /plan9-contrib/rc/bin/leak (revision 7c70c028d2d46a27a61ae88e6df0eb0935d9da7a)
1#!/bin/rc
2
3rfork e
4
5flagfmt='a,b,c,d,s,f binary,r res,x width'
6args='name | pid list'
7if(! ifs=() eval `{aux/getflags $*} || ~ $#* 0){
8	aux/usage
9	exit usage
10}
11
12conflicting=($flagb $flagc $flags)
13if(~ $#conflicting 2 || ~ $#conflicting 3){
14	echo 'can only use one of -b, -c or -s' >[1=2]
15	exit usage
16}
17
18leakflags=()
19if(~ $#flags 1)
20	leakflags=($leakflags -s)
21if(~ $#flaga 1)
22	leakflags=($leakflags -a)
23if(~ $#flagc 1)
24	leakflags=($leakflags -c)
25if(~ $#flagd 1)
26	leakflags=($leakflags -d)
27if(~ $#flagf 1)
28	leakflags=($leakflags -f $flagf)
29
30acidleakflags=()
31if(~ $#flagb 1)
32	acidleakflags=($acidleakflags -b)
33if(~ $#flagr 1)
34	acidleakflags=($acidleakflags -r $flagr)
35if(~ $#flagx 1)
36	acidleakflags=($acidleakflags -x $flagx)
37
38if(! test -d /proc/$1) {
39	# x=`{psu | awk '$NF=="'$1'" {print $2}'}
40	x=`{psu | grep ' '$1'$' | sed 's/^[^ ]+ +([0-9]+).*/\1/'}
41	if(~ $#x 0) {
42		echo 'no processes named '$1 >[1=2]
43		exit usage
44	}
45	echo leak $leakflags $acidleakflags $x
46	exit
47}
48
49pidlist=`{echo $"* | tr ' ' ,}
50
51echo 'leakdump({'$pidlist'})' | acid -lpool -lleak $1 $flagf |
52{
53	if(~ $#flaga 1 && ~ $#flagd 1)
54		grep 'block|free'
55	if not
56	if(~ $#flaga 1)
57		grep block
58	if not
59	if(~ $#flagd 1)
60		grep free
61	if not
62		aux/acidleak $acidleakflags $flagf
63} |
64{
65	if(~ $#flags 1)
66		awk '{print $4}' |
67			sort | uniq -c | sort -nr |
68			sed 's! *(.*) (0x.*)!src(\2); // \1!'
69	if not
70	if(~ $#flagc 1)
71		awk 'BEGIN {
72				for(i=0; i<16; i++)
73					_unhex[sprintf("%x", i)] = _unhex[sprintf("%X", i)] = i
74			}
75			function unhex(s, i, v) {
76				sub("^0[xX]0*","",s)
77				for (i=1; i<=length(s); i++)
78					v = v*16 + _unhex[substr(s,i,1)]
79				return v
80			}
81			{	sum[$4] += unhex($3);
82				count[$4]++;
83				alloc[$4] = $6;
84			}
85			END {
86				for (v in sum) {
87					printf("src(%s);\t// %d\t%d\t%d\t%s\n", v, sum[v], count[v], sum[v] / count[v], alloc[v])
88					total += sum[v]
89				}
90				printf("// %d\n", total);
91			}
92		'  | sort -nr +2
93	if not
94		cat
95}
96