added flag -c to print -s like output, but extended with byte counts and averages, and the allocating function. probably having both -s and -c is overkill. added flags -a and -d to print same information but then about all allocated blocks resp. about all free(d?) blocks. updated man page for these flags, and for already present format change (5 fields -> 7 fields) Reference: /n/sources/patch/applied/leak-extension Date: Tue Oct 31 22:34:16 CET 2006 Signed-off-by: Axel.Belinfante@cs.utwente.nl --- /rc/bin/leak Tue Oct 31 16:46:49 2006 +++ /rc/bin/leak Tue Oct 31 16:46:47 2006 @@ -2,21 +2,28 @@ rfork e -flagfmt='b,s,f binary,r res,x width' +flagfmt='a,b,c,d,s,f binary,r res,x width' args='name | pid list' if(! ifs=() eval `{aux/getflags $*} || ~ $#* 0){ aux/usage exit usage } -if(~ $#flags 1 && ~ $#flagb 1){ - echo 'cannot use both -b and -s' >[1=2] +conflicting=($flagb $flagc $flags) +if(~ $#conflicting 2 || ~ $#conflicting 3){ + echo 'can only use one of -b, -c or -s' >[1=2] exit usage } leakflags=() if(~ $#flags 1) leakflags=($leakflags -s) +if(~ $#flaga 1) + leakflags=($leakflags -a) +if(~ $#flagc 1) + leakflags=($leakflags -c) +if(~ $#flagd 1) + leakflags=($leakflags -d) if(~ $#flagf 1) leakflags=($leakflags -f $flagf) @@ -41,14 +48,48 @@ pidlist=`{echo $"* | tr ' ' ,} -echo 'leakdump({'$pidlist'})' | - acid -lpool -lleak $1 $flagf | - aux/acidleak $acidleakflags $flagf | - { - if(~ $#flags 1) - awk '{print $4}' | - sort | uniq -c | sort -nr | - sed 's! *(.*) (0x.*)!src(\2); // \1!' - if not - cat - } +echo 'leakdump({'$pidlist'})' | acid -lpool -lleak $1 $flagf | +{ + if(~ $#flaga 1 && ~ $#flagd 1) + grep 'block|free' + if not + if(~ $#flaga 1) + grep block + if not + if(~ $#flagd 1) + grep free + if not + aux/acidleak $acidleakflags $flagf +} | +{ + if(~ $#flags 1) + awk '{print $4}' | + sort | uniq -c | sort -nr | + sed 's! *(.*) (0x.*)!src(\2); // \1!' + if not + if(~ $#flagc 1) + awk 'BEGIN { + for(i=0; i<16; i++) + _unhex[sprintf("%x", i)] = _unhex[sprintf("%X", i)] = i + } + function unhex(s, i, v) { + sub("^0[xX]0*","",s) + for (i=1; i<=length(s); i++) + v = v*16 + _unhex[substr(s,i,1)] + return v + } + { sum[$4] += unhex($3); + count[$4]++; + alloc[$4] = $6; + } + END { + for (v in sum) { + printf("src(%s);\t// %d\t%d\t%d\t%s\n", v, sum[v], count[v], sum[v] / count[v], alloc[v]) + total += sum[v] + } + printf("// %d\n", total); + } + ' | sort -nr +2 + if not + cat +} --- /sys/man/1/leak Tue Oct 31 16:47:00 2006 +++ /sys/man/1/leak Tue Oct 31 16:46:58 2006 @@ -4,7 +4,7 @@ .SH SYNOPSIS .B leak [ -.B -bs +.B -abcds ] [ .B -f @@ -37,12 +37,13 @@ .PP Unless directed otherwise, .I leak -prints, for each block, a line with five space-separated fields: +prints, for each block, a line with seven space-separated fields: the string .BR block , the address of the block, the size of the block, -and the first two words of the block. +the first two words of the block, +and the function names represented by the first two words of the block. Usually, the first two words of the block contain the malloc and realloc tags (see @@ -51,14 +52,43 @@ .PP If the .B -s +or the +.B -c option is given, .I leak will instead present a sequence of .IR acid (1) commands that show each leaky allocation site. -A comment appears next to each command to +With +.B -s +a comment appears next to each command to indicate how many lost blocks were allocated at that point in the program. +With +.B -c +the comments are extended to indicate also the total +number of bytes lost at that point in the program, +and an additional comment line gives the +overall total number of bytes. +.PP +If the +.B -a +option is given, +.I leak +will print the same kind of information as decribed above, +but for all allocated blocks, not only about the leaked ones. +If the +.B -d +option is given, +.I leak +will print the same kind of information as decribed above, +but for all free blocks, i.e. those freed, or those that are not yet +in use (fragmentation?). +The +.B -a +and +.B -d +options can be combined. .PP If the .B -b