diff options
author | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-09 02:21:46 +0000 |
---|---|---|
committer | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-09 02:21:46 +0000 |
commit | 8687244a01e4333ed0edb429bdefbf88f83e965b (patch) | |
tree | 86d85e42a9ac9ead118607d843dc6fab8b55c1ca /tools/memory_watcher | |
parent | e724cb43e666972363380de0f6eba349160ac28c (diff) | |
download | chromium_src-8687244a01e4333ed0edb429bdefbf88f83e965b.zip chromium_src-8687244a01e4333ed0edb429bdefbf88f83e965b.tar.gz chromium_src-8687244a01e4333ed0edb429bdefbf88f83e965b.tar.bz2 |
Add mbelshe's memwatcehr scripts to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@615 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/memory_watcher')
-rw-r--r-- | tools/memory_watcher/scripts/finditem.pl | 53 | ||||
-rw-r--r-- | tools/memory_watcher/scripts/memprof.pl | 78 | ||||
-rw-r--r-- | tools/memory_watcher/scripts/memtrace.pl | 112 | ||||
-rw-r--r-- | tools/memory_watcher/scripts/summary.pl | 109 |
4 files changed, 352 insertions, 0 deletions
diff --git a/tools/memory_watcher/scripts/finditem.pl b/tools/memory_watcher/scripts/finditem.pl new file mode 100644 index 0000000..e1171ef --- /dev/null +++ b/tools/memory_watcher/scripts/finditem.pl @@ -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); diff --git a/tools/memory_watcher/scripts/memprof.pl b/tools/memory_watcher/scripts/memprof.pl new file mode 100644 index 0000000..67c1997 --- /dev/null +++ b/tools/memory_watcher/scripts/memprof.pl @@ -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); diff --git a/tools/memory_watcher/scripts/memtrace.pl b/tools/memory_watcher/scripts/memtrace.pl new file mode 100644 index 0000000..f699a67 --- /dev/null +++ b/tools/memory_watcher/scripts/memtrace.pl @@ -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); diff --git a/tools/memory_watcher/scripts/summary.pl b/tools/memory_watcher/scripts/summary.pl new file mode 100644 index 0000000..35c0716 --- /dev/null +++ b/tools/memory_watcher/scripts/summary.pl @@ -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(); |