Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: tools/valgrind/memcheck_analyze.py

Issue 8539007: Print out the ui_test test case in the reports (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/valgrind/tsan_analyze.py » ('j') | tools/valgrind/tsan_analyze.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 # memcheck_analyze.py 6 # memcheck_analyze.py
7 7
8 ''' Given a valgrind XML file, parses errors and uniques them.''' 8 ''' Given a valgrind XML file, parses errors and uniques them.'''
9 9
10 import gdb_helper 10 import gdb_helper
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 # Try using gdb 108 # Try using gdb
109 TheAddressTable.Add(frame_dict[OBJECT_FILE], 109 TheAddressTable.Add(frame_dict[OBJECT_FILE],
110 frame_dict[INSTRUCTION_POINTER]) 110 frame_dict[INSTRUCTION_POINTER])
111 return frames 111 return frames
112 112
113 class ValgrindError: 113 class ValgrindError:
114 ''' Takes a <DOM Element: error> node and reads all the data from it. A 114 ''' Takes a <DOM Element: error> node and reads all the data from it. A
115 ValgrindError is immutable and is hashed on its pretty printed output. 115 ValgrindError is immutable and is hashed on its pretty printed output.
116 ''' 116 '''
117 117
118 def __init__(self, source_dir, error_node, commandline): 118 def __init__(self, source_dir, error_node, commandline, testcase):
119 ''' Copies all the relevant information out of the DOM and into object 119 ''' Copies all the relevant information out of the DOM and into object
120 properties. 120 properties.
121 121
122 Args: 122 Args:
123 error_node: The <error></error> DOM node we're extracting from. 123 error_node: The <error></error> DOM node we're extracting from.
124 source_dir: Prefix that should be stripped from the <dir> node. 124 source_dir: Prefix that should be stripped from the <dir> node.
125 commandline: The command that was run under valgrind 125 commandline: The command that was run under valgrind
126 testcase: The test case name, if known.
126 ''' 127 '''
127 128
128 # Valgrind errors contain one <what><stack> pair, plus an optional 129 # Valgrind errors contain one <what><stack> pair, plus an optional
129 # <auxwhat><stack> pair, plus an optional <origin><what><stack></origin>, 130 # <auxwhat><stack> pair, plus an optional <origin><what><stack></origin>,
130 # plus (since 3.5.0) a <suppression></suppression> pair. 131 # plus (since 3.5.0) a <suppression></suppression> pair.
131 # (Origin is nicely enclosed; too bad the other two aren't.) 132 # (Origin is nicely enclosed; too bad the other two aren't.)
132 # The most common way to see all three in one report is 133 # The most common way to see all three in one report is
133 # a syscall with a parameter that points to uninitialized memory, e.g. 134 # a syscall with a parameter that points to uninitialized memory, e.g.
134 # Format: 135 # Format:
135 # <error> 136 # <error>
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 # <file>gtest-internal-inl.h</file> 188 # <file>gtest-internal-inl.h</file>
188 # <line>655</line> 189 # <line>655</line>
189 # </frame> 190 # </frame>
190 # although the dir, file, and line elements are missing if there is 191 # although the dir, file, and line elements are missing if there is
191 # no debug info. 192 # no debug info.
192 193
193 self._kind = getTextOf(error_node, "kind") 194 self._kind = getTextOf(error_node, "kind")
194 self._backtraces = [] 195 self._backtraces = []
195 self._suppression = None 196 self._suppression = None
196 self._commandline = commandline 197 self._commandline = commandline
198 self._testcase = testcase
197 199
198 # Iterate through the nodes, parsing <what|auxwhat><stack> pairs. 200 # Iterate through the nodes, parsing <what|auxwhat><stack> pairs.
199 description = None 201 description = None
200 for node in error_node.childNodes: 202 for node in error_node.childNodes:
201 if node.localName == "what" or node.localName == "auxwhat": 203 if node.localName == "what" or node.localName == "auxwhat":
202 description = "".join([n.data for n in node.childNodes 204 description = "".join([n.data for n in node.childNodes
203 if n.nodeType == n.TEXT_NODE]) 205 if n.nodeType == n.TEXT_NODE])
204 elif node.localName == "xwhat": 206 elif node.localName == "xwhat":
205 description = getTextOf(node, "text") 207 description = getTextOf(node, "text")
206 elif node.localName == "stack": 208 elif node.localName == "stack":
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 elif frame[SRC_FILE_DIR] != "": 255 elif frame[SRC_FILE_DIR] != "":
254 output += (" (" + frame[SRC_FILE_DIR] + "/" + frame[SRC_FILE_NAME] + 256 output += (" (" + frame[SRC_FILE_DIR] + "/" + frame[SRC_FILE_NAME] +
255 ":" + frame[SRC_LINE] + ")") 257 ":" + frame[SRC_LINE] + ")")
256 else: 258 else:
257 output += " (" + frame[OBJECT_FILE] + ")" 259 output += " (" + frame[OBJECT_FILE] + ")"
258 output += "\n" 260 output += "\n"
259 261
260 assert self._suppression != None, "Your Valgrind doesn't generate " \ 262 assert self._suppression != None, "Your Valgrind doesn't generate " \
261 "suppressions - is it too old?" 263 "suppressions - is it too old?"
262 264
265 if self._testcase:
266 output += "The report came from the `%s` test.\n" % self._testcase
263 output += "Suppression (error hash=#%016X#):\n" % self.ErrorHash() 267 output += "Suppression (error hash=#%016X#):\n" % self.ErrorHash()
264 output += (" For more info on using suppressions see " 268 output += (" For more info on using suppressions see "
265 "http://dev.chromium.org/developers/how-tos/using-valgrind#TOC-Su ppressing-Errors") 269 "http://dev.chromium.org/developers/how-tos/using-valgrind#TOC-Su ppressing-Errors")
266 270
267 # Widen suppression slightly to make portable between mac and linux 271 # Widen suppression slightly to make portable between mac and linux
268 supp = self._suppression; 272 supp = self._suppression;
269 supp = supp.replace("fun:_Znwj", "fun:_Znw*") 273 supp = supp.replace("fun:_Znwj", "fun:_Znw*")
270 supp = supp.replace("fun:_Znwm", "fun:_Znw*") 274 supp = supp.replace("fun:_Znwm", "fun:_Znw*")
271 supp = supp.replace("fun:_Znaj", "fun:_Zna*") 275 supp = supp.replace("fun:_Znaj", "fun:_Zna*")
272 supp = supp.replace("fun:_Znam", "fun:_Zna*") 276 supp = supp.replace("fun:_Znam", "fun:_Zna*")
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 self._use_gdb = use_gdb 395 self._use_gdb = use_gdb
392 396
393 # Contains the set of unique errors 397 # Contains the set of unique errors
394 self._errors = set() 398 self._errors = set()
395 399
396 # Contains the time when the we started analyzing the first log file. 400 # Contains the time when the we started analyzing the first log file.
397 # This variable is used to skip incomplete logs after some timeout. 401 # This variable is used to skip incomplete logs after some timeout.
398 self._analyze_start_time = None 402 self._analyze_start_time = None
399 403
400 404
401 def Report(self, files, check_sanity=False): 405 def Report(self, files, testcase, check_sanity=False):
402 '''Reads in a set of files and prints Memcheck report. 406 '''Reads in a set of files and prints Memcheck report.
403 407
404 Args: 408 Args:
405 files: A list of filenames. 409 files: A list of filenames.
406 check_sanity: if true, search for SANITY_TEST_SUPPRESSIONS 410 check_sanity: if true, search for SANITY_TEST_SUPPRESSIONS
407 ''' 411 '''
408 # Beyond the detailed errors parsed by ValgrindError above, 412 # Beyond the detailed errors parsed by ValgrindError above,
409 # the xml file contain records describing suppressions that were used: 413 # the xml file contain records describing suppressions that were used:
410 # <suppcounts> 414 # <suppcounts>
411 # <pair> 415 # <pair>
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 for x in node.childNodes: 521 for x in node.childNodes:
518 if x.nodeType == node.TEXT_NODE and "Command" in x.data: 522 if x.nodeType == node.TEXT_NODE and "Command" in x.data:
519 commandline = x.data 523 commandline = x.data
520 break 524 break
521 525
522 raw_errors = parsed_file.getElementsByTagName("error") 526 raw_errors = parsed_file.getElementsByTagName("error")
523 for raw_error in raw_errors: 527 for raw_error in raw_errors:
524 # Ignore "possible" leaks for now by default. 528 # Ignore "possible" leaks for now by default.
525 if (self._show_all_leaks or 529 if (self._show_all_leaks or
526 getTextOf(raw_error, "kind") != "Leak_PossiblyLost"): 530 getTextOf(raw_error, "kind") != "Leak_PossiblyLost"):
527 error = ValgrindError(self._source_dir, raw_error, commandline) 531 error = ValgrindError(self._source_dir,
532 raw_error, commandline, testcase)
528 if error not in cur_report_errors: 533 if error not in cur_report_errors:
529 # We haven't seen such errors doing this report yet... 534 # We haven't seen such errors doing this report yet...
530 if error in self._errors: 535 if error in self._errors:
531 # ... but we saw it in earlier reports, e.g. previous UI test 536 # ... but we saw it in earlier reports, e.g. previous UI test
532 cur_report_errors.add("This error was already printed in " 537 cur_report_errors.add("This error was already printed in "
533 "some other test, see 'hash=#%016X#'" % \ 538 "some other test, see 'hash=#%016X#'" % \
534 error.ErrorHash()) 539 error.ErrorHash())
535 else: 540 else:
536 # ... and we haven't seen it in other tests as well 541 # ... and we haven't seen it in other tests as well
537 self._errors.add(error) 542 self._errors.add(error)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 parser.add_option("", "--source_dir", 613 parser.add_option("", "--source_dir",
609 help="path to top of source tree for this build" 614 help="path to top of source tree for this build"
610 "(used to normalize source paths in baseline)") 615 "(used to normalize source paths in baseline)")
611 616
612 (options, args) = parser.parse_args() 617 (options, args) = parser.parse_args()
613 if len(args) == 0: 618 if len(args) == 0:
614 parser.error("no filename specified") 619 parser.error("no filename specified")
615 filenames = args 620 filenames = args
616 621
617 analyzer = MemcheckAnalyzer(options.source_dir, use_gdb=True) 622 analyzer = MemcheckAnalyzer(options.source_dir, use_gdb=True)
618 retcode = analyzer.Report(filenames) 623 retcode = analyzer.Report(filenames, None)
619 624
620 sys.exit(retcode) 625 sys.exit(retcode)
621 626
622 if __name__ == "__main__": 627 if __name__ == "__main__":
623 _main() 628 _main()
OLDNEW
« no previous file with comments | « no previous file | tools/valgrind/tsan_analyze.py » ('j') | tools/valgrind/tsan_analyze.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698