--- mtrace 2010-08-26 14:51:00.148982905 +0530
+++ mt-helper 2010-08-26 14:50:29.668982236 +0530
@@ -21,6 +21,7 @@
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA.
+
$VERSION = "2.10.1";
$PKGVERSION = "(EGLIBC) ";
$REPORT_BUGS_TO = '';
@@ -50,7 +51,7 @@
print "This is free software; see the source for copying conditions. There is NO\n";
print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
print "Written by Ulrich Drepper \n";
-
+
exit 0;
} elsif ($ARGV[0] eq "--h" || $ARGV[0] eq "--he" || $ARGV[0] eq "--hel" ||
$ARGV[0] eq "--help") {
@@ -64,175 +65,352 @@
}
}
-if ($#ARGV == 0) {
+if ($#ARGV == 0)
+{
$binary="";
$data=$ARGV[0];
-} elsif ($#ARGV == 1) {
+}
+elsif ($#ARGV == 1)
+{
$binary=$ARGV[0];
$data=$ARGV[1];
- if ($binary =~ /^.*[\/].*$/) {
- $prog = $binary;
- } else {
- $prog = "./$binary";
- }
- if (open (LOCS, "env LD_TRACE_LOADED_OBJECTS=1 $prog |")) {
- while () {
- chop;
- if (/^.*=> (.*) .(0x[0123456789abcdef]*).$/) {
- $locs{$1} = $2;
- }
- }
- close (LOCS);
- }
-} else {
+ if ($binary =~ /^.*[\/].*$/)
+ {
+ $prog = $binary;
+ }
+ else
+ {
+ $prog = "./$binary";
+ }
+ if (open (LOCS, "env LD_TRACE_LOADED_OBJECTS=1 $prog |"))
+ {
+ while ()
+ {
+ chop;
+ if (/^.*=> (.*) .(0x[0123456789abcdef]*).$/)
+ {
+ $locs{$1} = $2;
+ }
+ }
+ close (LOCS);
+ }
+}
+else
+{
die "Wrong number of arguments, run $progname --help for help.";
}
-sub location {
+sub location
+{
my $str = pop(@_);
return $str if ($str eq "");
- if ($str =~ /.*[[](0x[^]]*)]:(.)*/) {
- my $addr = $1;
- my $fct = $2;
- return $cache{$addr} if (exists $cache{$addr});
- if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
- my $line = ;
- chomp $line;
- close (ADDR);
- if ($line ne '??:0') {
- $cache{$addr} = $line;
- return $cache{$addr};
- }
- }
- $cache{$addr} = $str = "$fct @ $addr";
- } elsif ($str =~ /^(.*):.*[[](0x[^]]*)]$/) {
- my $prog = $1;
- my $addr = $2;
- my $searchaddr;
- return $cache{$addr} if (exists $cache{$addr});
- if ($locs{$prog} ne "") {
- $searchaddr = sprintf "%#x", $addr - $locs{$prog};
- } else {
- $searchaddr = $addr;
- $prog = $binary;
- }
- if ($binary ne "" && open (ADDR, "addr2line -e $prog $searchaddr|")) {
- my $line = ;
- chomp $line;
- close (ADDR);
- if ($line ne '??:0') {
- $cache{$addr} = $line;
- return $cache{$addr};
- }
- }
- $cache{$addr} = $str = $addr;
- } elsif ($str =~ /^.*[[](0x[^]]*)]$/) {
- my $addr = $1;
- return $cache{$addr} if (exists $cache{$addr});
- if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
- my $line = ;
- chomp $line;
- close (ADDR);
- if ($line ne '??:0') {
- $cache{$addr} = $line;
- return $cache{$addr};
- }
- }
- $cache{$addr} = $str = $addr;
+ if ($str =~ /.*[[](0x[^]]*)]:(.)*/)
+ {
+ my $addr = $1;
+ my $fct = $2;
+ return $cache{$addr} if (exists $cache{$addr});
+ if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|"))
+ {
+ my $line = ;
+ chomp $line;
+ close (ADDR);
+ if ($line ne '??:0')
+ {
+ $cache{$addr} = $line;
+ return $cache{$addr};
+ }
+ }
+ $cache{$addr} = $str = "$fct @ $addr";
+ }
+ elsif ($str =~ /^(.*):.*[[](0x[^]]*)]$/)
+ {
+ my $prog = $1;
+ my $addr = $2;
+ my $searchaddr;
+ return $cache{$addr} if (exists $cache{$addr});
+ if ($locs{$prog} ne "")
+ {
+ $searchaddr = sprintf "%#x", $addr - $locs{$prog};
+ }
+ else
+ {
+ $searchaddr = $addr;
+ $prog = $binary;
+ }
+ if ($binary ne "" && open (ADDR, "addr2line -e $prog $searchaddr|"))
+ {
+ my $line = ;
+ chomp $line;
+ close (ADDR);
+ if ($line ne '??:0')
+ {
+ $cache{$addr} = $line;
+ return $cache{$addr};
+ }
+ }
+ $cache{$addr} = $str = $addr;
+ }
+ elsif ($str =~ /^.*[[](0x[^]]*)]$/)
+ {
+ my $addr = $1;
+ return $cache{$addr} if (exists $cache{$addr});
+ if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|"))
+ {
+ my $line = ;
+ chomp $line;
+ close (ADDR);
+ if ($line ne '??:0')
+ {
+ $cache{$addr} = $line;
+ return $cache{$addr};
+ }
+ }
+ $cache{$addr} = $str = $addr;
}
return $str;
}
+sub mmapparser
+{
+ my $name = $_[1];
+ my $addr_hex = $_[0];
+ return $name if ($name eq "");
+ my $l=$name;
+ $addr_hex =~ /^(.*):.*[[](0x[^]]*)]$/;
+ $addr_hex=$2;
+ my $addr_dec = hex($addr_hex);
+ my $file="./mmapinfo.log";
+ my $offset_addr=0;
+ my $tmp;
+
+ if (-e "$file")
+ {
+ open (MMAPFILE,"$file");
+
+ while($tmp = )
+ {
+ @words = split / /,$tmp;
+ @addresses = split /-/,$words[0];
+
+ $a0_hex=$addresses[0];
+ $a0_dec=hex($a0_hex);
+
+ $a1_hex=$addresses[1];
+ $a1_dec=hex($a1_hex);
+
+ if ($addr_dec>=$a0_dec and $addr_dec<=$a1_dec)
+ {
+ $offset_addr=$addr_dec-$a0_dec;
+ $offset_addr=sprintf("%x", $offset_addr);
+ last;
+ }
+ }
+
+ close (MMAPFILE);
+ open (ADDR1, "addr2line -e $name $offset_addr|");
+ $line = ;
+ chomp $line;
+ close (ADDR1);
+ if ( $line ne '??:0')
+ {
+ return $line;
+ }
+ else
+ {
+ return $l;
+ }
+
+
+
+ }
+ else
+ {
+ #die "**mtrace** ERROR: $file not found. Aborting. \n";
+ #Currently script does nothing. The output will contain the leaks occurring in
+ #DSOs but without the location info.
+ }
+}
+
$nr=0;
open(DATA, "<$data") || die "Cannot open mtrace data file";
-while () {
+while ()
+{
my @cols = split (' ');
my $n, $where;
- if ($cols[0] eq "@") {
- # We have address and/or function name.
- $where=$cols[1];
- $n=2;
- } else {
- $where="";
- $n=0;
+ if ($cols[0] eq "@")
+ {
+ # We have address and/or function name.
+ $where=$cols[1];
+ $n=2;
+ $temp = $where;
+ }
+ else
+ {
+ $where="";
+ $n=0;
}
+ undef $libname;
+ if ($temp =~ m/^(.*so.*):.*/)
+ {
+ $lib = $1;
+ if ($lib =~ m/^.*lib.*so.*/)
+ {
+ $libname=$lib;
+ }
+
+ }
$allocaddr=$cols[$n + 1];
$howmuch=hex($cols[$n + 2]);
-
++$nr;
- SWITCH: {
- if ($cols[$n] eq "+") {
- if (defined $allocated{$allocaddr}) {
- printf ("+ %#010x Alloc %d duplicate: %s %s\n",
- hex($allocaddr), $nr, &location($addrwas{$allocaddr}),
- $where);
- } else {
- $allocated{$allocaddr}=$howmuch;
- $addrwas{$allocaddr}=$where;
- }
- last SWITCH;
- }
- if ($cols[$n] eq "-") {
- if (defined $allocated{$allocaddr}) {
- undef $allocated{$allocaddr};
- undef $addrwas{$allocaddr};
- } else {
- printf ("- %#010x Free %d was never alloc'd %s\n",
- hex($allocaddr), $nr, &location($where));
- }
- last SWITCH;
- }
- if ($cols[$n] eq "<") {
- if (defined $allocated{$allocaddr}) {
- undef $allocated{$allocaddr};
- undef $addrwas{$allocaddr};
- } else {
- printf ("- %#010x Realloc %d was never alloc'd %s\n",
- hex($allocaddr), $nr, &location($where));
- }
- last SWITCH;
- }
- if ($cols[$n] eq ">") {
- if (defined $allocated{$allocaddr}) {
- printf ("+ %#010x Realloc %d duplicate: %#010x %s %s\n",
- hex($allocaddr), $nr, $allocated{$allocaddr},
- &location($addrwas{$allocaddr}), &location($where));
- } else {
- $allocated{$allocaddr}=$howmuch;
- $addrwas{$allocaddr}=$where;
- }
- last SWITCH;
- }
- if ($cols[$n] eq "=") {
- # Ignore "= Start".
- last SWITCH;
- }
- if ($cols[$n] eq "!") {
- # Ignore failed realloc for now.
- last SWITCH;
- }
+ SWITCH:
+ {
+ if ($cols[$n] eq "+")
+ {
+ if (defined $allocated{$allocaddr})
+ {
+ if (defined $libs{$allocaddr})
+ {
+ printf ("+ %#010x Alloc %d duplicate: %s %s\n", hex($allocaddr), $nr, &mmapparser($addrwas{$allocaddr}, $libs{$allocaddr}), $where);
+ }
+ else
+ {
+ printf ("+ %#010x Alloc %d duplicate: %s %s\n", hex($allocaddr), $nr, &location($addrwas{$allocaddr}), $where);
+ }
+ }
+ else
+ {
+ $allocated{$allocaddr}=$howmuch;
+ $addrwas{$allocaddr}=$where;
+ if (defined $libname)
+ {
+ $libs{$allocaddr}=$libname;
+ }
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq "-")
+ {
+ if (defined $allocated{$allocaddr})
+ {
+ undef $allocated{$allocaddr};
+ undef $addrwas{$allocaddr};
+ if (defined $libs{$allocaddr})
+ {
+ undef $libs{$allocaddr};
+ }
+ }
+ else
+ {
+ if (defined $libs{$allocaddr})
+ {
+ printf ("- %#010x Free %d was never alloc'd %s\n",
+ hex($allocaddr), $nr, &mmapparser($addrwas{$allocaddr}, $libs{$allocaddr}));
+ }
+ else
+ {
+ printf ("- %#010x Free %d was never alloc'd %s\n",
+ hex($allocaddr), $nr, &location($where));
+ }
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq "<")
+ {
+ if (defined $allocated{$allocaddr})
+ {
+ undef $allocated{$allocaddr};
+ undef $addrwas{$allocaddr};
+ undef $libs{$allocaddr};
+ }
+ else
+ {
+ if (defined $libs{$allocaddr})
+ {
+ printf ("- %#010x Realloc %d was never alloc'd %s\n",
+ hex($allocaddr), $nr, &mmapparser($addrwas{$allocaddr}, $libs{$allocaddr}));
+ }
+ else
+ {
+ printf ("- %#010x Realloc %d was never alloc'd %s\n",
+ hex($allocaddr), $nr, &location($where));
+ }
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq ">")
+ {
+ if (defined $allocated{$allocaddr})
+ {
+ if (defined $libs{$allocaddr})
+ {
+ printf ("+ %#010x Realloc %d duplicate: %#010x %s %s\n",
+ hex($allocaddr), $nr, $allocated{$allocaddr},
+ &mmapparser($addrwas{$allocaddr}, $libs{$allocaddr}), &location($where));
+ }
+ else
+ {
+ printf ("+ %#010x Realloc %d duplicate: %#010x %s %s\n",
+ hex($allocaddr), $nr, $allocated{$allocaddr},
+ &location($addrwas{$allocaddr}), &location($where));
+ }
+ }
+ else
+ {
+ $allocated{$allocaddr}=$howmuch;
+ $addrwas{$allocaddr}=$where;
+ if (defined $libname)
+ {
+ $libs{$allocaddr}=$libname;
+ }
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq "=")
+ {
+ # Ignore "= Start".
+ last SWITCH;
+ }
+ if ($cols[$n] eq "!")
+ {
+ # Ignore failed realloc for now.
+ last SWITCH;
+ }
}
}
close (DATA);
-
-# Now print all remaining entries.
-@addrs= keys %allocated;
$anything=0;
-if ($#addrs >= 0) {
- foreach $addr (sort @addrs) {
- if (defined $allocated{$addr}) {
- if ($anything == 0) {
- print "\nMemory not freed:\n-----------------\n";
- print ' ' x (10 - 7), "Address Size Caller\n";
- $anything=1;
- }
- printf ("%#010x %#8x at %s\n", hex($addr), $allocated{$addr},
- &location($addrwas{$addr}));
- }
- }
+sub hashValueDescendingNum
+{
+ $allocated{$b} <=> $allocated{$a};
+}
+
+
+# Now print all remaining entries
+foreach $addr (sort hashValueDescendingNum (keys(%allocated)))
+{
+ if (defined $allocated{$addr})
+ {
+ if ($anything == 0)
+ {
+ print "\nMemory not freed:\n-----------------\n";
+ print ' ' x (10 - 7), "Address Size Caller\n";
+ $anything=1;
+ }
+ if (defined $libs{$addr})
+ {
+ printf ("%#010x %#8x at %s\n", hex($addr), $allocated{$addr},
+ &mmapparser($addrwas{$addr}, $libs{$addr}));
+ }
+ else
+ {
+ printf ("%#010x %#8x at %s\n", hex($addr), $allocated{$addr},
+ &location($addrwas{$addr}));
+ }
+ }
}
print "No memory leaks.\n" if ($anything == 0);
exit $anything != 0;
+#eof