--- mt-helper 2010-09-20 14:03:12.677163269 +0530 +++ mtrace 2010-09-20 14:03:17.621163064 +0530 @@ -49,7 +49,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") { @@ -63,352 +63,175 @@ } } -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; - } - 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; - } - - - + 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; } - 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. + 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; } $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; - $temp = $where; - } - else - { - $where=""; - $n=0; + if ($cols[0] eq "@") { + # We have address and/or function name. + $where=$cols[1]; + $n=2; + } 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}) - { - 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; - } + 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; + } } } close (DATA); -$anything=0; -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})); - } - } +# 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})); + } + } } print "No memory leaks.\n" if ($anything == 0); exit $anything != 0; -#eof