0

Add mbelshe's memwatcehr scripts to the repository.

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@615 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
ericroman@google.com
2008-08-09 02:21:46 +00:00
parent e724cb43e6
commit 8687244a01
4 changed files with 352 additions and 0 deletions
tools/memory_watcher/scripts

@ -0,0 +1,53 @@
#!/usr/bin/perl
sub process_raw($$) {
my $file = shift;
my $search = shift;
my %leaks = ();
my $save = 0;
my $print = 0;
my $bytes = 0;
my $calls = 0;
my $sum_bytes = 0;
my $sum_calls = 0;
open (LOGFILE, "$file") or die("could not open $file");
while(<LOGFILE>) {
my $line = $_;
if ($line =~ m/([0-9]*) bytes, ([0-9]*) items/) {
$save = "";
$print = 0;
$bytes = $1;
$calls = $2;
}
elsif ($line =~ m/$search/) {
$print = 1;
}
elsif ($line =~ m/=============/) {
$save .= $line;
if ($print) {
print "$bytes bytes ($calls calls)\n";
print $save;
$sum_bytes += $bytes;
$sum_calls += $calls;
$save = "";
$print = 0;
$calls = 0;
}
}
$save .= $line;
}
print("TOTAL: $sum_bytes bytes ($sum_calls calls)\n");
}
# ----- Main ------------------------------------------------
# Get the command line argument
my $filename = shift;
my $search = shift;
# Process the file.
process_raw($filename, $search);

@ -0,0 +1,78 @@
#!/usr/bin/perl
sub process_raw($$) {
my $file = shift;
my $filter = shift;
my %leaks = ();
my %stackframes = ();
my $blamed = 0;
my $bytes = 0;
my $hits = 0;
open (LOGFILE, "$file") or die("could not open $file");
while(<LOGFILE>) {
my $line = $_;
#print "$line";
chomp($line);
if ($line =~ m/([0-9]*) bytes, ([0-9]*) items/) {
# If we didn't find any frames to account this to, log that.
if ($blamed == 0) {
$leaks{"UNACCOUNTED"} += $bytes;
}
#print "START\n";
#print("stackframe " . $1 . ", " . $2 . "\n");
$hits = $2;
$bytes = $1;
%stackframes = (); # we have a new frame, clear the list.
$blamed = 0; # we haven't blamed anyone yet
}
elsif ($line =~ m/Total Bytes:[ ]*([0-9]*)/) {
$total_bytes += $1;
}
elsif ($line =~ m/=============/) {
next;
}
elsif ($line =~ m/[ ]*([\-a-zA-Z_\\0-9\.]*) \(([0-9]*)\):[ ]*([<>_a-zA-Z_0-9:]*)/) {
# print("junk: " . $line . "\n");
# print("file: $1\n");
# print("line: $2\n");
# print("function: $3\n");
#
# blame the function
my $pig = $3;
# my $pig = $1;
# only add the memory if this function is not yet on our callstack
if (!exists $stackframes{$pig}) {
$leaks{$pig} += $bytes;
}
$stackframes{$pig}++;
$blamed++;
}
}
# now dump our hash table
my $sum = 0;
my @keys = keys(%leaks);
for ($i=0; $i<@keys; $i++) {
my $key = @keys[$i];
printf "%8d\t%3.2f%%\t%s\n", $leaks{$key}, (100* $leaks{$key} / $total_bytes), $key;
$sum += $leaks{$key};
}
print("TOTAL: $sum\n");
}
# ----- Main ------------------------------------------------
# Get the command line argument
my $filename = shift;
my $filter = shift;
# Process the file.
process_raw($filename, $filter);

@ -0,0 +1,112 @@
#!/usr/bin/perl
sub process_raw($) {
my $file = shift;
my %leaks = ();
my $location_bytes = 0;
my $location_hits = 0;
my $location_blame = "";
my $location_last = "";
my $contains_load_lib = 0;
my $total_bytes = 0;
open (LOGFILE, "$file") or die("could not open $file");
while(<LOGFILE>) {
my $line = $_;
#print "$line";
chomp($line);
if ($line =~ m/([0-9]*) bytes, ([0-9]*) items/) {
#print "START\n";
# Dump "prior" frame here
if ($location_bytes > 0) {
#print("GOTLEAK: $location_bytes ($location_hits) $location_blame\n");
if ($location_blame eq "") {
$location_blame = $location_last;
}
if (!$contains_load_lib) {
$leaks{$location_blame} += $location_bytes;
}
$location_bytes = 0;
$location_blame = "";
$contains_load_lib = 0;
}
#print("stackframe " . $1 . ", " . $2 . "\n");
$location_hits = $2;
$location_bytes = $1;
}
elsif ($line =~ m/Total Bytes:[ ]*([0-9]*)/) {
$total_bytes += $1;
}
elsif ($line =~ m/LoadLibrary/) {
# skip these, they contain false positives.
$contains_load_lib = 1;
next;
}
elsif ($line =~ m/=============/) {
next;
}
elsif ($line =~ m/Untracking untracked/) {
next;
}
elsif ($line =~ m/[ ]*(c:\\trunk\\[a-zA-Z_\\0-9\.]*) /) {
my $filename = $1;
if ($filename =~ m/memory_watcher/) {
next;
}
if ($filename =~ m/skmemory_stdlib.cpp/) {
next;
}
if ($filename =~ m/stringimpl.cpp/) {
next;
}
if ($filename =~ m/stringbuffer.h/) {
next;
}
if ($filename =~ m/fastmalloc.h/) {
next;
}
if ($filename =~ m/microsoft visual studio 8/) {
next;
}
if ($filename =~ m/platformsdk_vista_6_0/) {
next;
}
if ($location_blame eq "") {
# use this to blame the line
$location_blame = $line;
# use this to blame the file.
# $location_blame = $filename;
#print("blaming $location_blame\n");
}
} else {
# print("junk: " . $line . "\n");
if (! ($line =~ m/GetModuleFileNameA/) ) {
$location_last = $line;
}
}
}
# now dump our hash table
my $sum = 0;
my @keys = keys(%leaks);
for ($i=0; $i<@keys; $i++) {
my $key = @keys[$i];
printf "%8d\t%3.2f%%\t%s\n", $leaks{$key}, (100* $leaks{$key} / $total_bytes), $key;
$sum += $leaks{$key};
}
print("TOTAL: $sum\n");
}
# ----- Main ------------------------------------------------
# Get the command line argument
my $filename = shift;
# Process the file.
process_raw($filename);

@ -0,0 +1,109 @@
#!/usr/bin/perl
#
# Summarizes output from memtrace using a set of heuristics
#
sub process_stdin() {
my %leaks = ();
my $total_bytes = 0;
while(<STDIN>) {
my $line = $_;
chomp($line);
my $bytes, $loc;
($bytes, $loc) = ($line =~ m/[ \t]*([0-9]*)[ \t]*[0-9\.%]*[ \t]*(.*)/);
my $location_blame = "";
# print "Found: $bytes, $loc\n";
$total_bytes += $bytes;
if ($loc =~ m/v8/) {
$location_blame = "v8";
} elsif ($loc =~ m/sqlite/) {
$location_blame = "sqlite";
} elsif ($loc =~ m/SkBitmap/) {
$location_blame = "skia";
} elsif ($loc =~ m/disk_cache/) {
$location_blame = "disk cache";
} elsif ($loc =~ m/skia/) {
$location_blame = "skia";
} elsif ($loc =~ m/:WSA/) {
$location_blame = "net";
} elsif ($loc =~ m/dns/) {
$location_blame = "net";
} elsif ($loc =~ m/trunk\\net/) {
$location_blame = "net";
} elsif ($loc =~ m/WinHttp/) {
$location_blame = "WinHttp";
} elsif ($loc =~ m/:I_Crypt/) {
$location_blame = "WinHttpSSL";
} elsif ($loc =~ m/CryptGetTls/) {
$location_blame = "WinHttpSSL";
} elsif ($loc =~ m/WinVerifyTrust/) {
$location_blame = "WinHttpSSL";
} elsif ($loc =~ m/Cert/) {
$location_blame = "WinHttpSSL";
} elsif ($loc =~ m/plugin/) {
$location_blame = "plugin";
} elsif ($loc =~ m/NP_/) {
$location_blame = "plugin";
} elsif ($loc =~ m/hunspell/) {
$location_blame = "hunspell";
} elsif ($loc =~ m/decoder/) {
$location_blame = "img decoder";
} elsif ($loc =~ m/TextCodec/) {
$location_blame = "fonts";
} elsif ($loc =~ m/glyph/) {
$location_blame = "fonts";
} elsif ($loc =~ m/cssparser/) {
$location_blame = "webkit css";
} elsif ($loc =~ m/::CSS/) {
$location_blame = "webkit css";
} elsif ($loc =~ m/Arena/) {
$location_blame = "webkit arenas";
} elsif ($loc =~ m/IPC/) {
$location_blame = "ipc";
} elsif ($loc =~ m/trunk\\chrome\\browser/) {
$location_blame = "browser";
} elsif ($loc =~ m/trunk\\chrome\\renderer/) {
$location_blame = "renderer";
} elsif ($loc =~ m/webcore\\html/) {
$location_blame = "webkit webcore html";
} elsif ($loc =~ m/webkit.*string/) {
$location_blame = "webkit strings";
} elsif ($loc =~ m/htmltokenizer/) {
$location_blame = "webkit HTMLTokenizer";
} elsif ($loc =~ m/javascriptcore/) {
$location_blame = "webkit javascriptcore";
} elsif ($loc =~ m/webkit/) {
$location_blame = "webkit other";
# print "$location_blame: ($bytes) $loc\n";
} else {
$location_blame = "unknown";
# print "$location_blame: ($bytes) $loc\n";
}
# surface large outliers
if ($bytes > 1000000 && $location_blame eq "unknown") {
$location_blame = $loc;
}
$leaks{$location_blame} += $bytes;
}
# now dump our hash table
my $sum = 0;
my @keys = keys(%leaks);
for ($i=0; $i<@keys; $i++) {
my $key = @keys[$i];
printf "%8d\t%3.2f%%\t%s\n", $leaks{$key}, (100* $leaks{$key} / $total_bytes), $key;
$sum += $leaks{$key};
}
print("TOTAL: $sum\n");
}
# ----- Main ------------------------------------------------
process_stdin();