diff options
author | groby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-07 22:14:50 +0000 |
---|---|---|
committer | groby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-07 22:14:50 +0000 |
commit | c13196354937f967842695372115ed8e6835ccd6 (patch) | |
tree | 262c4068486d1c9c48e1ef1692d467733a7341de /tools/valgrind/test_suppressions.py | |
parent | 670d7710d74e3f15e35d970f750d9296aa1a9410 (diff) | |
download | chromium_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-x | tools/valgrind/test_suppressions.py | 61 |
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 |