Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 # tsan_analyze.py | 6 # tsan_analyze.py |
| 7 | 7 |
| 8 ''' Given a ThreadSanitizer output file, parses errors and uniques them.''' | 8 ''' Given a ThreadSanitizer output file, parses errors and uniques them.''' |
| 9 | 9 |
| 10 import gdb_helper | 10 import gdb_helper |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 self.ReadLine() | 114 self.ReadLine() |
| 115 if re.match('-+ suppression -+', self.line_): | 115 if re.match('-+ suppression -+', self.line_): |
| 116 # We need to calculate the suppression hash and prepend a line like | 116 # We need to calculate the suppression hash and prepend a line like |
| 117 # "Suppression (error hash=#0123456789ABCDEF#):" so the buildbot can | 117 # "Suppression (error hash=#0123456789ABCDEF#):" so the buildbot can |
| 118 # extract the suppression snippet. | 118 # extract the suppression snippet. |
| 119 supp = "" | 119 supp = "" |
| 120 while not re.match('-+ end suppression -+', self.line_): | 120 while not re.match('-+ end suppression -+', self.line_): |
| 121 self.ReadLine() | 121 self.ReadLine() |
| 122 supp += self.line_ | 122 supp += self.line_ |
| 123 self.ReadLine() | 123 self.ReadLine() |
| 124 if self._cur_testcase: | |
| 125 result.append("The report came from the `%s` test.\n" % \ | |
| 126 self._cur_testcase) | |
| 124 result.append("Suppression (error hash=#%016X#):\n" % \ | 127 result.append("Suppression (error hash=#%016X#):\n" % \ |
| 125 (int(hashlib.md5(supp).hexdigest()[:16], 16))) | 128 (int(hashlib.md5(supp).hexdigest()[:16], 16))) |
| 126 result.append(" For more info on using suppressions see " | 129 result.append(" For more info on using suppressions see " |
| 127 "http://dev.chromium.org/developers/how-tos/using-valgrind/threadsan itizer#TOC-Suppressing-data-races\n") | 130 "http://dev.chromium.org/developers/how-tos/using-valgrind/threadsan itizer#TOC-Suppressing-data-races\n") |
| 128 result.append(supp) | 131 result.append(supp) |
| 129 else: | 132 else: |
| 130 self.ReadLine() | 133 self.ReadLine() |
| 131 | 134 |
| 132 return result | 135 return result |
| 133 | 136 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 reports = [] | 209 reports = [] |
| 207 self.used_suppressions = {} | 210 self.used_suppressions = {} |
| 208 for file in files: | 211 for file in files: |
| 209 reports.extend(self.ParseReportFile(file)) | 212 reports.extend(self.ParseReportFile(file)) |
| 210 if self._use_gdb: | 213 if self._use_gdb: |
| 211 TheAddressTable.ResolveAll() | 214 TheAddressTable.ResolveAll() |
| 212 # Make each line of each report a string. | 215 # Make each line of each report a string. |
| 213 reports = map(lambda(x): map(str, x), reports) | 216 reports = map(lambda(x): map(str, x), reports) |
| 214 return [''.join(report_lines) for report_lines in reports] | 217 return [''.join(report_lines) for report_lines in reports] |
| 215 | 218 |
| 216 def Report(self, files, check_sanity=False): | 219 def Report(self, files, testcase, check_sanity=False): |
| 217 '''Reads in a set of files and prints ThreadSanitizer report. | 220 '''Reads in a set of files and prints ThreadSanitizer report. |
| 218 | 221 |
| 219 Args: | 222 Args: |
| 220 files: A list of filenames. | 223 files: A list of filenames. |
| 221 check_sanity: if true, search for SANITY_TEST_SUPPRESSIONS | 224 check_sanity: if true, search for SANITY_TEST_SUPPRESSIONS |
| 222 ''' | 225 ''' |
| 223 | 226 |
| 227 self._cur_testcase = testcase | |
| 224 reports = self.GetReports(files) | 228 reports = self.GetReports(files) |
| 229 self._cur_testcase = None | |
|
Alexander Potapenko
2011/11/11 09:41:31
Please add a comment describing why you need to re
| |
| 225 | 230 |
| 226 is_sane = False | 231 is_sane = False |
| 227 print "-----------------------------------------------------" | 232 print "-----------------------------------------------------" |
| 228 print "Suppressions used:" | 233 print "Suppressions used:" |
| 229 print " count name" | 234 print " count name" |
| 230 for item in sorted(self.used_suppressions.items(), key=lambda (k,v): (v,k)): | 235 for item in sorted(self.used_suppressions.items(), key=lambda (k,v): (v,k)): |
| 231 print "%7s %s" % (item[1], item[0]) | 236 print "%7s %s" % (item[1], item[0]) |
| 232 if item[0].startswith(TsanAnalyzer.SANITY_TEST_SUPPRESSION): | 237 if item[0].startswith(TsanAnalyzer.SANITY_TEST_SUPPRESSION): |
| 233 is_sane = True | 238 is_sane = True |
| 234 print "-----------------------------------------------------" | 239 print "-----------------------------------------------------" |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 258 parser.add_option("", "--source_dir", | 263 parser.add_option("", "--source_dir", |
| 259 help="path to top of source tree for this build" | 264 help="path to top of source tree for this build" |
| 260 "(used to normalize source paths in baseline)") | 265 "(used to normalize source paths in baseline)") |
| 261 | 266 |
| 262 (options, args) = parser.parse_args() | 267 (options, args) = parser.parse_args() |
| 263 if not args: | 268 if not args: |
| 264 parser.error("no filename specified") | 269 parser.error("no filename specified") |
| 265 filenames = args | 270 filenames = args |
| 266 | 271 |
| 267 analyzer = TsanAnalyzer(options.source_dir, use_gdb=True) | 272 analyzer = TsanAnalyzer(options.source_dir, use_gdb=True) |
| 268 retcode = analyzer.Report(filenames) | 273 retcode = analyzer.Report(filenames, None) |
| 269 | 274 |
| 270 sys.exit(retcode) | 275 sys.exit(retcode) |
| OLD | NEW |