5 # MEM mprintf.c:1094 malloc(32) = e5718
6 # MEM mprintf.c:1103 realloc(e5718, 64) = e6118
7 # MEM sendf.c:232 free(f6520)
10 if($ARGV[0] eq "-v") {
13 elsif($ARGV[0] eq "-t") {
16 } while (shift @ARGV);
24 if($newtot > $maxmem) {
33 if($line =~ /^MEM ([^:]*):(\d*) (.*)/) {
34 # generic match for the filename+linenumber
39 if($function =~ /free\(0x([0-9a-f]*)/) {
41 if($sizeataddr{$addr} == 0) {
42 print "FREE ERROR: No memory allocated: $line\n";
44 elsif(-1 == $sizeataddr{$addr}) {
45 print "FREE ERROR: Memory freed twice: $line\n";
46 print "FREE ERROR: Previously freed at: ".$getmem{$addr}."\n";
49 $totalmem -= $sizeataddr{$addr};
51 print "FREE: malloc at ".$getmem{$addr}." is freed again at $source:$linenum\n";
52 printf("FREE: %d bytes freed, left allocated: $totalmem bytes\n", $sizeataddr{$addr});
58 $sizeataddr{$addr}=-1; # set -1 to mark as freed
59 $getmem{$addr}="$source:$linenum";
63 elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) {
67 if($sizeataddr{$addr}>0) {
68 # this means weeeeeirdo
69 print "Fucked up debug compile, rebuild curl now\n";
72 $sizeataddr{$addr}=$size;
76 print "MALLOC: malloc($size) at $source:$linenum",
77 " makes totally $totalmem bytes\n";
83 $getmem{$addr}="$source:$linenum";
85 elsif($function =~ /realloc\(0x([0-9a-f]*), (\d*)\) = 0x([0-9a-f]*)/) {
90 $totalmem -= $sizeataddr{$oldaddr};
92 printf("REALLOC: %d less bytes and ", $sizeataddr{$oldaddr});
94 $sizeataddr{$oldaddr}=0;
96 $totalmem += $newsize;
97 $sizeataddr{$newaddr}=$newsize;
100 printf("%d more bytes ($source:$linenum)\n", $newsize);
106 $getmem{$oldaddr}="";
107 $getmem{$newaddr}="$source:$linenum";
109 elsif($function =~ /strdup\(0x([0-9a-f]*)\) \((\d*)\) = 0x([0-9a-f]*)/) {
110 # strdup(a5b50) (8) = df7c0
115 $getmem{$addr}="$source:$linenum";
116 $sizeataddr{$addr}=$size;
121 printf("STRDUP: $size bytes at %s, makes totally: %d bytes\n",
122 $getmem{$addr}, $totalmem);
129 print "Not recognized input line: $function\n";
132 # FD url.c:1282 socket() = 5
133 elsif($_ =~ /^FD ([^:]*):(\d*) (.*)/) {
134 # generic match for the filename+linenumber
139 if($function =~ /socket\(\) = (\d*)/) {
141 $getfile{$1}="$source:$linenum";
144 elsif($function =~ /accept\(\) = (\d*)/) {
146 $getfile{$1}="$source:$linenum";
149 elsif($function =~ /sclose\((\d*)\)/) {
150 if($filedes{$1} != 1) {
151 print "Close without open: $line\n";
154 $filedes{$1}=0; # closed now
159 # FILE url.c:1282 fopen("blabla") = 0x5ddd
160 elsif($_ =~ /^FILE ([^:]*):(\d*) (.*)/) {
161 # generic match for the filename+linenumber
166 if($function =~ /fopen\(\"([^\"]*)\"\) = (\(nil\)|0x([0-9a-f]*))/) {
172 $fopenfile{$3}="$source:$linenum";
177 elsif($function =~ /fclose\(0x([0-9a-f]*)\)/) {
179 print "fclose() without fopen(): $line\n";
187 # ADDR url.c:1282 getaddrinfo() = 0x5ddd
188 elsif($_ =~ /^ADDR ([^:]*):(\d*) (.*)/) {
189 # generic match for the filename+linenumber
194 if($function =~ /getaddrinfo\(\) = (\(nil\)|0x([0-9a-f]*))/) {
196 if($add eq "(nil)") {
201 $addrinfofile{$add}="$source:$linenum";
206 elsif($function =~ /freeaddrinfo\(0x([0-9a-f]*)\)/) {
208 print "freeaddrinfo() without getaddrinfo(): $line\n";
219 print "Not recognized prefix line: $line\n";
224 print "Leak detected: memory still allocated: $totalmem bytes\n";
226 for(keys %sizeataddr) {
228 $size = $sizeataddr{$addr};
230 print "At $addr, there's $size bytes.\n";
231 print " allocated by ".$getmem{$addr}."\n";
238 if($filedes{$_} == 1) {
239 print "Open file descriptor created at ".$getfile{$_}."\n";
245 print "Open FILE handles left at:\n";
247 if($fopen{$_} == 1) {
248 print "fopen() called at ".$fopenfile{$_}."\n";
254 print "IPv6-style name resolve data left at:\n";
255 for(keys %addrinfofile) {
256 if($addrinfo{$_} == 1) {
257 print "getaddrinfo() called at ".$addrinfofile{$_}."\n";
263 print "Mallocs: $mallocs\n",
264 "Reallocs: $reallocs\n",
265 "Strdups: $strdups\n",
268 print "Maximum allocated: $maxmem\n";