X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Ftests%2Fleak_finder.pl;h=c230e590d4b716f3977be7a6c5643dec44c38a54;hp=99a0f67685fe3c9fbd7318289f401c96369d21bf;hb=1de3c3455868670c289ed1d69f57244816ea39b5;hpb=042d62050b799f563e5a1f1a7c535dacc6b02e0f diff --git a/lustre/tests/leak_finder.pl b/lustre/tests/leak_finder.pl index 99a0f67..c230e59 100644 --- a/lustre/tests/leak_finder.pl +++ b/lustre/tests/leak_finder.pl @@ -1,53 +1,123 @@ #!/usr/bin/perl -w +use IO::Handle; + +STDOUT->autoflush(1); +STDERR->autoflush(1); + my ($line, $memory); my $debug_line = 0; -while ($line = <>) { +my $total = 0; +my $max = 0; + +my @parsed; +my %cpu; +my $start_time = 0; + +if (!defined($ARGV[0])) { + print "No log file specified\n"; + exit +} + +open(INFILE, $ARGV[0]); +while ($line = ) { + if ($line =~ m/^(.*)\((.*):(\d+):(.*)\(\)\)/) { + @parsed = split(":", $1); + if (substr ($parsed[2], -1, 1) eq "F") { + chop $parsed[2]; + $cpu{$parsed[2]} = 0; + } else { + if (!defined($cpu{$parsed[2]})) { + $cpu{$parsed[2]} = $parsed[3]; + } + } + } +} + +foreach $time (values %cpu) { + if ($start_time < $time) { + $start_time = $time; + } +} + +print "Starting analysis since $start_time\n"; + +seek(INFILE, 0, 0); +while ($line = ) { $debug_line++; my ($file, $func, $lno, $name, $size, $addr, $type); - if ($line =~ m/^.*\(@\d+ (.*):(.*)\,l\. (\d+) .* k(.*) '(.*)': (\d+) at (.*) \(tot .*$/) { - $file = $1; - $func = $2; - $lno = $3; - $type = $4; - $name = $5; - $size = $6; - $addr = $7; + if ($line =~ m/^(.*)\((.*):(\d+):(.*)\(\)\) (k|v|slab-)(.*) '(.*)': (\d+) at ([\da-f]+)/){ + @parsed = split(":", $1); + if ($parsed[3] <= $start_time) { + next; + } + + $file = $2; + $lno = $3; + $func = $4; + $type = $6; + $name = $7; + $size = $8; + $addr = $9; + + # we can't dump the log after portals has exited, so skip "leaks" + # from memory freed in the portals module unloading. + if ($func eq 'portals_handle_init') { + next; + } printf("%8s %6d bytes at %s called %s (%s:%s:%d)\n", $type, $size, $addr, $name, $file, $func, $lno); } else { next; } - if ($type eq 'malloced') { + if (index($type, 'alloced') >= 0) { + if (defined($memory->{$addr})) { + print STDOUT "*** Two allocs with the same address ($size bytes at $addr, $file:$func:$lno)\n"; + print STDOUT " first malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, second at $file:$func:$lno\n"; + next; + } + $memory->{$addr}->{name} = $name; $memory->{$addr}->{size} = $size; $memory->{$addr}->{file} = $file; $memory->{$addr}->{func} = $func; $memory->{$addr}->{lno} = $lno; $memory->{$addr}->{debug_line} = $debug_line; + + $total += $size; + if ($total > $max) { + $max = $total; + } } else { if (!defined($memory->{$addr})) { - print "*** Free without malloc ($size bytes at $addr, $file:$func:$lno)\n"; + print STDOUT "*** Free without malloc ($size bytes at $addr, $file:$func:$lno)\n"; next; } my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$addr}; if ($memory->{$addr}->{size} != $size) { - print "*** Free different size ($memory->{$addr}->{size} alloced, $size freed).\n"; - print " malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, free at $file:$func:$lno\n"; + print STDOUT "*** Free different size ($memory->{$addr}->{size} alloced, $size freed).\n"; + print STDOUT " malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, free at $file:$func:$lno\n"; next; } delete $memory->{$addr}; + $total -= $size; } } +close(INFILE); + +# Sort leak output by allocation time +my @sorted = sort { + return $memory->{$a}->{debug_line} <=> $memory->{$b}->{debug_line}; +} keys(%{$memory}); my $key; -foreach $key (keys(%{$memory})) { +foreach $key (@sorted) { my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$key}; - print "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n"; + print STDOUT "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n"; } -print "Done.\n"; +print STDOUT "maximum used: $max, amount leaked: $total\n";