Chromium Code Reviews| Index: tools/valgrind/test_suppressions.py |
| diff --git a/tools/valgrind/test_suppressions.py b/tools/valgrind/test_suppressions.py |
| index 75bc6b9227448fc633a8b3d0776fcba075715541..4fb30d15d597f7881a2bda4a77afdf8dee135db2 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 |
|
Lei Zhang
2013/05/07 20:39:56
Is everyone running an OS on their desktop with Py
groby-ooo-7-16
2013/05/07 20:57:59
Seems to be the case.
On 2013/05/07 20:39:56, Lei
|
| from collections import defaultdict |
| import os |
| import re |
| +import subprocess |
| import sys |
| import suppressions |
| @@ -45,6 +47,44 @@ 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 |
|
Lei Zhang
2013/05/07 20:39:56
style nit: spaces around +
groby-ooo-7-16
2013/05/07 20:57:59
Done.
|
| + return demangled[:-1] |
| + |
| +def GetSymbolsFromReport(report): |
| + """Extract all symbols from a suppression report.""" |
| + symbols = [] |
| + for line in report.splitlines(): |
| + index = line.find('fun:') |
| + if index != -1: |
| + symbols.append(line[index+4:]) |
|
Lei Zhang
2013/05/07 20:39:56
index + len('fun:'), or have some constant that in
groby-ooo-7-16
2013/05/07 20:57:59
Done.
|
| + return symbols |
| + |
| +def PrintTopSymbols(symbol_reports, top_count): |
| + """Print the |top_count| symbols with the most occurrences.""" |
| + boring_symbols=['malloc', '_Znw*', 'TestBody'] |
|
Lei Zhang
2013/05/07 20:39:56
Use BoringCallers() in common.py?
groby-ooo-7-16
2013/05/07 20:57:59
BoringCallers ignores different boringness. Per of
|
| + 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)) |
|
Lei Zhang
2013/05/07 20:39:56
style nit: space after comma.
groby-ooo-7-16
2013/05/07 20:57:59
Done.
|
| + |
| + 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 +92,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 +144,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 |