1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
#!perl
# Useage: $0 error_report_file >check_list
# Check the error report file for malloc() leaks.
# libber.c: 221: 1: cmdToken: arg: token = +
# libber.c: 221: 1: cmdToken: arg: token = .\*
# libber.c: 120: 1: cmdToken: mem: malloc = 1ab2655a (0002)
# libber.c: 120: 1: cmdToken: mem: malloc = 1ab26572 (0008)
# libber.c: 111: 1: cmdToken: mem: free = 1ab26572
# libber.c: 120: 1: cmdToken: mem: malloc = 1ab26572 (000f)
# libber.c: 120: 1: cmdToken: mem: calloc = 1ab26572 (000f*000f)
# list.c: 602: 2: appList: arg: flags = 1; name = .\MSG_0000.OBJ
# list.c: 521: 3: inList: arg: flags = 7; name = .\MSG_0000.OBJ
# list.c: 111: 3: inList: mem: free = 1ab20000
# list.c: 120: 2: appList: mem: malloc = 1ab26586 (0013)
# libber.c: 461: 1: >main
# list.c: 194: 2: | >Falloc
# list.c: 195: 2: | | arg: paras = 65535
# list.c: 218: 2: | | inf: allocated 32062 @22c1
# list.c: 219: 2: | <Falloc
# list.c: 194: 2: | >Falloc
# list.c: 195: 2: | | arg: paras = 65535
# list.c: 211: 2: | <Falloc
# list.c: 534: 2: | >clrList
# types.c: 143: 3: | | >U_free
$[ = 0;
%mem = ();
sub deIndent { # deIndent current line
local($line, $h, $fnfo);
return unless /^([^:]*:[^:]*):[^:]*:\s*/;
$line = $&;
$h = $';
return unless $h =~ /^[<>\|]/;
while($h =~ /^\|\s*/) {
$h = $';
}
if($h =~ /^>/) {
$h = $';
$h =~ s/\s*$//;
push(@fct, $h);
$h = $_;
$h .= "\n" unless /\n$/;
push(@nfo, $h);
$_ = '';
} elsif($h =~ /^</) {
pop(@fct);
pop(@nfo);
$_ = '';
} else {
$_ = $line . $fct[$#fct] . ': ' . $h;
}
}
sub pr {
local($h, $cnt) = "@_";
local(@q) = split(/\s+/,$_);
print "$q[1] $q[2] $h: @q[3..$#q]\n";
foreach $cnt (1..$#nfo) {
print $nfo[$#nfo - $cnt];
}
}
sub Xmalloc {
local($addr, $cnt) = @_;
if(defined $mem{$addr}) {
&pr("double malloc");
} else {
$mem{$addr} = $line;
foreach $cnt (0..$#nfo) {
$mem{$addr} .= $nfo[$cnt];
}
}
}
sub Xfree {
local($addr) = @_;
return if $addr eq "00000000"; # free(NULL) is a NOP
if(!defined $mem{$addr}) {
&pr("free non-allocated");
} else {
delete $mem{$addr};
}
}
while(<>) {
&deIndent;
print STDERR "$.\r";
@h = split(/\s+/, $_);
next unless $h[5] eq "mem:";
$line = $_;
if($h[6] eq "malloc" || $h[6] eq "strdup" || $h[6] eq "calloc") {
&Xmalloc($h[8], $h[9]);
} elsif($h[6] eq "free") {
&Xfree($h[8]);
} elsif($h[6] eq "realloc") {
$h[10] =~ s/^\[//;
$h[10] =~ s/\]$//;
&Xfree($h[10]);
&Xmalloc($h[8], $h[9]);
} else {
&pr("unknown cmd $h[6]");
}
}
print STDERR " \r";
while(($addr, $line) = each(%mem)) {
@nfo = split(/\n/, $line);
$_ = shift(@nfo);
foreach $cnt (0..$#nfo) {
$nfo[$cnt] .= "\n";
}
&pr("Unfreed");
}
|