summaryrefslogtreecommitdiffstats
path: root/tools/memory_watcher
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-09 02:21:46 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-09 02:21:46 +0000
commit8687244a01e4333ed0edb429bdefbf88f83e965b (patch)
tree86d85e42a9ac9ead118607d843dc6fab8b55c1ca /tools/memory_watcher
parente724cb43e666972363380de0f6eba349160ac28c (diff)
downloadchromium_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.pl53
-rw-r--r--tools/memory_watcher/scripts/memprof.pl78
-rw-r--r--tools/memory_watcher/scripts/memtrace.pl112
-rw-r--r--tools/memory_watcher/scripts/summary.pl109
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();