| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 return False | 307 return False |
| 308 if '</valgrindoutput>' in line: | 308 if '</valgrindoutput>' in line: |
| 309 # valgrind often has garbage after </valgrindoutput> upon crash | 309 # valgrind often has garbage after </valgrindoutput> upon crash |
| 310 f.truncate() | 310 f.truncate() |
| 311 return True | 311 return True |
| 312 | 312 |
| 313 class MemcheckAnalyzer: | 313 class MemcheckAnalyzer: |
| 314 ''' Given a set of Valgrind XML files, parse all the errors out of them, | 314 ''' Given a set of Valgrind XML files, parse all the errors out of them, |
| 315 unique them and output the results.''' | 315 unique them and output the results.''' |
| 316 | 316 |
| 317 SANITY_TEST_SUPPRESSIONS_LINUX = { | 317 SANITY_TEST_SUPPRESSIONS = { |
| 318 "Memcheck sanity test 01 (memory leak).": 1, | 318 "Memcheck sanity test 01 (memory leak).": 1, |
| 319 "Memcheck sanity test 02 (malloc/read left).": 1, | 319 "Memcheck sanity test 02 (malloc/read left).": 1, |
| 320 "Memcheck sanity test 03 (malloc/read right).": 1, | 320 "Memcheck sanity test 03 (malloc/read right).": 1, |
| 321 "Memcheck sanity test 04 (malloc/write left).": 1, | 321 "Memcheck sanity test 04 (malloc/write left).": 1, |
| 322 "Memcheck sanity test 05 (malloc/write right).": 1, | 322 "Memcheck sanity test 05 (malloc/write right).": 1, |
| 323 "Memcheck sanity test 06 (new/read left).": 1, | 323 "Memcheck sanity test 06 (new/read left).": 1, |
| 324 "Memcheck sanity test 07 (new/read right).": 1, | 324 "Memcheck sanity test 07 (new/read right).": 1, |
| 325 "Memcheck sanity test 08 (new/write left).": 1, | 325 "Memcheck sanity test 08 (new/write left).": 1, |
| 326 "Memcheck sanity test 09 (new/write right).": 1, | 326 "Memcheck sanity test 09 (new/write right).": 1, |
| 327 "Memcheck sanity test 10 (write after free).": 1, | 327 "Memcheck sanity test 10 (write after free).": 1, |
| 328 "Memcheck sanity test 11 (write after delete).": 1, | 328 "Memcheck sanity test 11 (write after delete).": 1, |
| 329 "Memcheck sanity test 12 (array deleted without []).": 1, | 329 "Memcheck sanity test 12 (array deleted without []).": 1, |
| 330 "Memcheck sanity test 13 (single element deleted with []).": 1, | 330 "Memcheck sanity test 13 (single element deleted with []).": 1, |
| 331 } | 331 } |
| 332 | 332 |
| 333 SANITY_TEST_SUPPRESSIONS_MAC = { | |
| 334 "Memcheck sanity test 01 (memory leak).": 1, | |
| 335 "Memcheck sanity test 02 (malloc/read left).": 1, | |
| 336 "Memcheck sanity test 03 (malloc/read right).": 1, | |
| 337 "Memcheck sanity test 06 (new/read left).": 1, | |
| 338 "Memcheck sanity test 07 (new/read right).": 1, | |
| 339 "Memcheck sanity test 10 (write after free).": 1, | |
| 340 "Memcheck sanity test 11 (write after delete).": 1, | |
| 341 "bug_49253 Memcheck sanity test 12 (array deleted without []) on Mac.": 1, | |
| 342 "bug_49253 Memcheck sanity test 13 (single element deleted with []) on Mac
.": 1, | |
| 343 "bug_49253 Memcheck sanity test 04 (malloc/write left) or Memcheck sanity
test 05 (malloc/write right) on Mac.": 2, | |
| 344 "bug_49253 Memcheck sanity test 08 (new/write left) or Memcheck sanity tes
t 09 (new/write right) on Mac.": 2, | |
| 345 } | |
| 346 | |
| 347 # Max time to wait for memcheck logs to complete. | 333 # Max time to wait for memcheck logs to complete. |
| 348 LOG_COMPLETION_TIMEOUT = 180.0 | 334 LOG_COMPLETION_TIMEOUT = 180.0 |
| 349 | 335 |
| 350 def __init__(self, source_dir, show_all_leaks=False, use_gdb=False): | 336 def __init__(self, source_dir, show_all_leaks=False, use_gdb=False): |
| 351 '''Create a parser for Memcheck logs. | 337 '''Create a parser for Memcheck logs. |
| 352 | 338 |
| 353 Args: | 339 Args: |
| 354 source_dir: Path to top of source tree for this build | 340 source_dir: Path to top of source tree for this build |
| 355 show_all_leaks: Whether to show even less important leaks | 341 show_all_leaks: Whether to show even less important leaks |
| 356 use_gdb: Whether to use gdb to resolve source filenames and line numbers | 342 use_gdb: Whether to use gdb to resolve source filenames and line numbers |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 | 506 |
| 521 if parse_failed: | 507 if parse_failed: |
| 522 logging.error("FAIL! Couldn't parse Valgrind output file") | 508 logging.error("FAIL! Couldn't parse Valgrind output file") |
| 523 return -2 | 509 return -2 |
| 524 | 510 |
| 525 is_sane = False | 511 is_sane = False |
| 526 print "-----------------------------------------------------" | 512 print "-----------------------------------------------------" |
| 527 print "Suppressions used:" | 513 print "Suppressions used:" |
| 528 print " count name" | 514 print " count name" |
| 529 | 515 |
| 530 if common.IsLinux(): | 516 remaining_sanity_supp = MemcheckAnalyzer.SANITY_TEST_SUPPRESSIONS |
| 531 remaining_sanity_supp = MemcheckAnalyzer.SANITY_TEST_SUPPRESSIONS_LINUX | |
| 532 elif common.IsMac(): | |
| 533 remaining_sanity_supp = MemcheckAnalyzer.SANITY_TEST_SUPPRESSIONS_MAC | |
| 534 else: | |
| 535 remaining_sanity_supp = {} | |
| 536 if check_sanity: | |
| 537 logging.warn("No sanity test list for platform %s", sys.platform) | |
| 538 | |
| 539 for (name, count) in sorted(suppcounts.items(), | 517 for (name, count) in sorted(suppcounts.items(), |
| 540 key=lambda (k,v): (v,k)): | 518 key=lambda (k,v): (v,k)): |
| 541 print "%7d %s" % (count, name) | 519 print "%7d %s" % (count, name) |
| 542 if name in remaining_sanity_supp and remaining_sanity_supp[name] == count: | 520 if name in remaining_sanity_supp and remaining_sanity_supp[name] == count: |
| 543 del remaining_sanity_supp[name] | 521 del remaining_sanity_supp[name] |
| 544 if len(remaining_sanity_supp) == 0: | 522 if len(remaining_sanity_supp) == 0: |
| 545 is_sane = True | 523 is_sane = True |
| 546 print "-----------------------------------------------------" | 524 print "-----------------------------------------------------" |
| 547 sys.stdout.flush() | 525 sys.stdout.flush() |
| 548 | 526 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 parser.error("no filename specified") | 564 parser.error("no filename specified") |
| 587 filenames = args | 565 filenames = args |
| 588 | 566 |
| 589 analyzer = MemcheckAnalyzer(options.source_dir, use_gdb=True) | 567 analyzer = MemcheckAnalyzer(options.source_dir, use_gdb=True) |
| 590 retcode = analyzer.Report(filenames) | 568 retcode = analyzer.Report(filenames) |
| 591 | 569 |
| 592 sys.exit(retcode) | 570 sys.exit(retcode) |
| 593 | 571 |
| 594 if __name__ == "__main__": | 572 if __name__ == "__main__": |
| 595 _main() | 573 _main() |
| OLD | NEW |