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 |