summaryrefslogtreecommitdiffstats
path: root/tools/valgrind/test_suppressions.py
diff options
context:
space:
mode:
authorgroby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-07 22:14:50 +0000
committergroby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-07 22:14:50 +0000
commitc13196354937f967842695372115ed8e6835ccd6 (patch)
tree262c4068486d1c9c48e1ef1692d467733a7341de /tools/valgrind/test_suppressions.py
parent670d7710d74e3f15e35d970f750d9296aa1a9410 (diff)
downloadchromium_src-c13196354937f967842695372115ed8e6835ccd6.zip
chromium_src-c13196354937f967842695372115ed8e6835ccd6.tar.gz
chromium_src-c13196354937f967842695372115ed8e6835ccd6.tar.bz2
[Memory Sheriff] --top-symbols for waterfall match
Allow "--top-symbols <n>" as an argument for "waterfall match". Will list the top <n> symbol occurrences in all unsuppressed reports. NOTRY=true R=thestig@chromium.org BUG=none Review URL: https://chromiumcodereview.appspot.com/15039007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198813 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/valgrind/test_suppressions.py')
-rwxr-xr-xtools/valgrind/test_suppressions.py61
1 files changed, 60 insertions, 1 deletions
diff --git a/tools/valgrind/test_suppressions.py b/tools/valgrind/test_suppressions.py
index 75bc6b9..5eeab99 100755
--- a/tools/valgrind/test_suppressions.py
+++ b/tools/valgrind/test_suppressions.py
@@ -3,9 +3,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import argparse
from collections import defaultdict
import os
import re
+import subprocess
import sys
import suppressions
@@ -45,6 +47,46 @@ def ReadReportsFromFile(filename):
# The line at the end of the file is assumed to store the URL of the report.
return reports,line
+def Demangle(names):
+ """ Demangle a list of C++ symbols, return a list of human-readable symbols.
+ """
+ args = ['c++filt', '-n']
+ args.extend(names)
+ pipe = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ stdout, _ = pipe.communicate()
+ demangled = stdout.split("\n")
+
+ # Each line ends with a newline, so the final entry of the split output
+ # will always be ''.
+ assert len(demangled) == len(names) + 1
+ return demangled[:-1]
+
+def GetSymbolsFromReport(report):
+ """Extract all symbols from a suppression report."""
+ symbols = []
+ prefix = "fun:"
+ prefix_len = len(prefix)
+ for line in report.splitlines():
+ index = line.find(prefix)
+ if index != -1:
+ symbols.append(line[index + prefix_len:])
+ return symbols
+
+def PrintTopSymbols(symbol_reports, top_count):
+ """Print the |top_count| symbols with the most occurrences."""
+ boring_symbols=['malloc', '_Znw*', 'TestBody']
+ sorted_reports = sorted(filter(lambda x:x[0] not in boring_symbols,
+ symbol_reports.iteritems()),
+ key=lambda x:len(x[1]), reverse=True)
+ symbols = symbol_reports.keys()
+ demangled = Demangle(symbols)
+ assert len(demangled) == len(symbols)
+ symboltable = dict(zip(symbols, demangled))
+
+ print "\n"
+ print "Top %d symbols" % top_count
+ for (symbol, suppressions) in sorted_reports[:top_count]:
+ print "%4d occurrences : %s" % (len(suppressions), symboltable[symbol])
def main(argv):
supp = suppressions.GetSuppressions()
@@ -52,8 +94,17 @@ def main(argv):
# all_reports is a map {report: list of urls containing this report}
all_reports = defaultdict(list)
report_hashes = {}
+ symbol_reports = defaultdict(list)
+
+ # Create argument parser.
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--top-symbols', type=int, default=0,
+ help='Print a list of the top <n> symbols')
+ parser.add_argument('reports', metavar='report file', nargs='+',
+ help='List of report files')
+ args = parser.parse_args(argv)
- for f in argv:
+ for f in args.reports:
f_reports, url = ReadReportsFromFile(f)
for (hash, report) in f_reports:
all_reports[report] += [url]
@@ -95,9 +146,17 @@ def main(argv):
print r
print "==================================="
+ if args.top_symbols > 0:
+ symbols = GetSymbolsFromReport(r)
+ for symbol in symbols:
+ symbol_reports[symbol].append(report_hashes[r])
+
if reports_count > 0:
print ("%d unique reports don't match any of the suppressions" %
reports_count)
+ if args.top_symbols > 0:
+ PrintTopSymbols(symbol_reports, args.top_symbols)
+
else:
print "Congratulations! All reports are suppressed!"
# TODO(timurrrr): also make sure none of the old suppressions