| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 # suppressions.py | 6 # suppressions.py |
| 7 | 7 |
| 8 """Post-process Valgrind suppression matcher. | 8 """Post-process Valgrind suppression matcher. |
| 9 | 9 |
| 10 Suppressions are defined as follows: | 10 Suppressions are defined as follows: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 | 39 |
| 40 def GetSuppressions(): | 40 def GetSuppressions(): |
| 41 suppressions_root = path_utils.ScriptDir() | 41 suppressions_root = path_utils.ScriptDir() |
| 42 JOIN = os.path.join | 42 JOIN = os.path.join |
| 43 | 43 |
| 44 result = {} | 44 result = {} |
| 45 | 45 |
| 46 supp_filename = JOIN(suppressions_root, "memcheck", "suppressions.txt") | 46 supp_filename = JOIN(suppressions_root, "memcheck", "suppressions.txt") |
| 47 vg_common = ReadSuppressionsFromFile(supp_filename) | 47 vg_common = ReadSuppressionsFromFile(supp_filename) |
| 48 supp_filename = JOIN(suppressions_root, "tsan", "suppressions.txt") | 48 result['common_suppressions'] = vg_common |
| 49 tsan_common = ReadSuppressionsFromFile(supp_filename) | |
| 50 result['common_suppressions'] = vg_common + tsan_common | |
| 51 | 49 |
| 52 supp_filename = JOIN(suppressions_root, "memcheck", "suppressions_linux.txt") | 50 supp_filename = JOIN(suppressions_root, "memcheck", "suppressions_linux.txt") |
| 53 vg_linux = ReadSuppressionsFromFile(supp_filename) | 51 vg_linux = ReadSuppressionsFromFile(supp_filename) |
| 54 supp_filename = JOIN(suppressions_root, "tsan", "suppressions_linux.txt") | 52 result['linux_suppressions'] = vg_linux |
| 55 tsan_linux = ReadSuppressionsFromFile(supp_filename) | |
| 56 result['linux_suppressions'] = vg_linux + tsan_linux | |
| 57 | 53 |
| 58 supp_filename = JOIN(suppressions_root, "memcheck", "suppressions_mac.txt") | 54 supp_filename = JOIN(suppressions_root, "memcheck", "suppressions_mac.txt") |
| 59 vg_mac = ReadSuppressionsFromFile(supp_filename) | 55 vg_mac = ReadSuppressionsFromFile(supp_filename) |
| 60 supp_filename = JOIN(suppressions_root, "tsan", "suppressions_mac.txt") | 56 result['mac_suppressions'] = vg_mac |
| 61 tsan_mac = ReadSuppressionsFromFile(supp_filename) | |
| 62 result['mac_suppressions'] = vg_mac + tsan_mac | |
| 63 | |
| 64 supp_filename = JOIN(suppressions_root, "tsan", "suppressions_win32.txt") | |
| 65 tsan_win = ReadSuppressionsFromFile(supp_filename) | |
| 66 result['win_suppressions'] = tsan_win | |
| 67 | 57 |
| 68 supp_filename = JOIN(suppressions_root, "drmemory", "suppressions.txt") | 58 supp_filename = JOIN(suppressions_root, "drmemory", "suppressions.txt") |
| 69 result['drmem_suppressions'] = ReadSuppressionsFromFile(supp_filename) | 59 result['drmem_suppressions'] = ReadSuppressionsFromFile(supp_filename) |
| 70 supp_filename = JOIN(suppressions_root, "drmemory", "suppressions_full.txt") | 60 supp_filename = JOIN(suppressions_root, "drmemory", "suppressions_full.txt") |
| 71 result['drmem_full_suppressions'] = ReadSuppressionsFromFile(supp_filename) | 61 result['drmem_full_suppressions'] = ReadSuppressionsFromFile(supp_filename) |
| 72 | 62 |
| 73 return result | 63 return result |
| 74 | 64 |
| 75 | 65 |
| 76 def GlobToRegex(glob_pattern, ignore_case=False): | 66 def GlobToRegex(glob_pattern, ignore_case=False): |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 if not self.stack: | 130 if not self.stack: |
| 141 return False | 131 return False |
| 142 lines = [f.strip() for f in suppression_from_report] | 132 lines = [f.strip() for f in suppression_from_report] |
| 143 return self.regex.match('\n'.join(lines) + '\n') is not None | 133 return self.regex.match('\n'.join(lines) + '\n') is not None |
| 144 | 134 |
| 145 | 135 |
| 146 def FilenameToTool(filename): | 136 def FilenameToTool(filename): |
| 147 """Return the name of the tool that a file is related to, or None. | 137 """Return the name of the tool that a file is related to, or None. |
| 148 | 138 |
| 149 Example mappings: | 139 Example mappings: |
| 150 tools/valgrind/tsan/suppressions.txt -> tsan | |
| 151 tools/valgrind/drmemory/suppressions.txt -> drmemory | 140 tools/valgrind/drmemory/suppressions.txt -> drmemory |
| 152 tools/valgrind/drmemory/suppressions_full.txt -> drmemory | 141 tools/valgrind/drmemory/suppressions_full.txt -> drmemory |
| 153 tools/valgrind/memcheck/suppressions.txt -> memcheck | 142 tools/valgrind/memcheck/suppressions.txt -> memcheck |
| 154 tools/valgrind/memcheck/suppressions_mac.txt -> memcheck | 143 tools/valgrind/memcheck/suppressions_mac.txt -> memcheck |
| 155 """ | 144 """ |
| 156 filename = os.path.abspath(filename) | 145 filename = os.path.abspath(filename) |
| 157 parts = filename.split(os.sep) | 146 parts = filename.split(os.sep) |
| 158 tool = parts[-2] | 147 tool = parts[-2] |
| 159 if tool in ('drmemory', 'memcheck', 'tsan'): | 148 if tool in ('drmemory', 'memcheck'): |
| 160 return tool | 149 return tool |
| 161 return None | 150 return None |
| 162 | 151 |
| 163 | 152 |
| 164 def ReadSuppressionsFromFile(filename): | 153 def ReadSuppressionsFromFile(filename): |
| 165 """Read suppressions from the given file and return them as a list""" | 154 """Read suppressions from the given file and return them as a list""" |
| 166 tool_to_parser = { | 155 tool_to_parser = { |
| 167 "drmemory": ReadDrMemorySuppressions, | 156 "drmemory": ReadDrMemorySuppressions, |
| 168 "memcheck": ReadValgrindStyleSuppressions, | 157 "memcheck": ReadValgrindStyleSuppressions, |
| 169 "tsan": ReadValgrindStyleSuppressions, | |
| 170 } | 158 } |
| 171 tool = FilenameToTool(filename) | 159 tool = FilenameToTool(filename) |
| 172 assert tool in tool_to_parser, ( | 160 assert tool in tool_to_parser, ( |
| 173 "unknown tool %s for filename %s" % (tool, filename)) | 161 "unknown tool %s for filename %s" % (tool, filename)) |
| 174 parse_func = tool_to_parser[tool] | 162 parse_func = tool_to_parser[tool] |
| 175 | 163 |
| 176 # Consider non-existent files to be empty. | 164 # Consider non-existent files to be empty. |
| 177 if not os.path.exists(filename): | 165 if not os.path.exists(filename): |
| 178 return [] | 166 return [] |
| 179 | 167 |
| 180 input_file = file(filename, 'r') | 168 input_file = file(filename, 'r') |
| 181 try: | 169 try: |
| 182 return parse_func(input_file, filename) | 170 return parse_func(input_file, filename) |
| 183 except SuppressionError: | 171 except SuppressionError: |
| 184 input_file.close() | 172 input_file.close() |
| 185 raise | 173 raise |
| 186 | 174 |
| 187 | 175 |
| 188 class ValgrindStyleSuppression(Suppression): | 176 class ValgrindStyleSuppression(Suppression): |
| 189 """A suppression using the Valgrind syntax. | 177 """A suppression using the Valgrind syntax. |
| 190 | 178 |
| 191 Most tools, even ones that are not Valgrind-based, use this syntax, ie | 179 Most tools, even ones that are not Valgrind-based, use this syntax. |
| 192 TSan, etc. | |
| 193 | 180 |
| 194 Attributes: | 181 Attributes: |
| 195 Same as Suppression. | 182 Same as Suppression. |
| 196 """ | 183 """ |
| 197 | 184 |
| 198 def __init__(self, description, type, stack, defined_at): | 185 def __init__(self, description, type, stack, defined_at): |
| 199 """Creates a suppression using the Memcheck and TSan, syntax.""" | 186 """Creates a suppression using the Memcheck syntax.""" |
| 200 regex = '{\n.*\n%s\n' % type | 187 regex = '{\n.*\n%s\n' % type |
| 201 for line in stack: | 188 for line in stack: |
| 202 if line == ELLIPSIS: | 189 if line == ELLIPSIS: |
| 203 regex += '(.*\n)*' | 190 regex += '(.*\n)*' |
| 204 else: | 191 else: |
| 205 regex += GlobToRegex(line) | 192 regex += GlobToRegex(line) |
| 206 regex += '\n' | 193 regex += '\n' |
| 207 regex += '(.*\n)*' | 194 regex += '(.*\n)*' |
| 208 regex += '}' | 195 regex += '}' |
| 209 | 196 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 ValgrindStyleSuppression(cur_descr, cur_type, cur_stack, | 276 ValgrindStyleSuppression(cur_descr, cur_type, cur_stack, |
| 290 "%s:%d" % (supp_descriptor, nline))) | 277 "%s:%d" % (supp_descriptor, nline))) |
| 291 cur_descr = '' | 278 cur_descr = '' |
| 292 cur_type = '' | 279 cur_type = '' |
| 293 cur_stack = [] | 280 cur_stack = [] |
| 294 in_suppression = False | 281 in_suppression = False |
| 295 elif not cur_descr: | 282 elif not cur_descr: |
| 296 cur_descr = line | 283 cur_descr = line |
| 297 continue | 284 continue |
| 298 elif not cur_type: | 285 elif not cur_type: |
| 299 if (not line.startswith("Memcheck:") and | 286 if not line.startswith("Memcheck:"): |
| 300 not line.startswith("ThreadSanitizer:")): | |
| 301 raise SuppressionError( | 287 raise SuppressionError( |
| 302 'Expected "Memcheck:TYPE" or "ThreadSanitizer:TYPE", ' | 288 'Expected "Memcheck:TYPE", got "%s"' % line, |
| 303 'got "%s"' % line, | |
| 304 "%s:%d" % (supp_descriptor, nline)) | 289 "%s:%d" % (supp_descriptor, nline)) |
| 305 supp_type = line.split(':')[1] | 290 supp_type = line.split(':')[1] |
| 306 if not supp_type in ["Addr1", "Addr2", "Addr4", "Addr8", | 291 if not supp_type in ["Addr1", "Addr2", "Addr4", "Addr8", |
| 307 "Cond", "Free", "Jump", "Leak", "Overlap", "Param", | 292 "Cond", "Free", "Jump", "Leak", "Overlap", "Param", |
| 308 "Value1", "Value2", "Value4", "Value8", | 293 "Value1", "Value2", "Value4", "Value8", |
| 309 "Race", "UnlockNonLocked", "InvalidLock", | |
| 310 "Unaddressable", "Uninitialized"]: | 294 "Unaddressable", "Uninitialized"]: |
| 311 raise SuppressionError('Unknown suppression type "%s"' % supp_type, | 295 raise SuppressionError('Unknown suppression type "%s"' % supp_type, |
| 312 "%s:%d" % (supp_descriptor, nline)) | 296 "%s:%d" % (supp_descriptor, nline)) |
| 313 cur_type = line | 297 cur_type = line |
| 314 continue | 298 continue |
| 315 elif re.match("^fun:.*|^obj:.*|^\.\.\.$", line): | 299 elif re.match("^fun:.*|^obj:.*|^\.\.\.$", line): |
| 316 cur_stack.append(line.strip()) | 300 cur_stack.append(line.strip()) |
| 317 elif len(cur_stack) == 0 and cur_type == "Memcheck:Param": | 301 elif len(cur_stack) == 0 and cur_type == "Memcheck:Param": |
| 318 cur_stack.append(line.strip()) | 302 cur_stack.append(line.strip()) |
| 319 else: | 303 else: |
| 320 raise SuppressionError( | 304 raise SuppressionError( |
| 321 '"fun:function_name" or "obj:object_file" or "..." expected', | 305 '"fun:function_name" or "obj:object_file" or "..." expected', |
| 322 "%s:%d" % (supp_descriptor, nline)) | 306 "%s:%d" % (supp_descriptor, nline)) |
| 323 return result | 307 return result |
| 324 | 308 |
| 325 | 309 |
| 326 def PresubmitCheckSuppressions(supps): | 310 def PresubmitCheckSuppressions(supps): |
| 327 """Check a list of suppressions and return a list of SuppressionErrors. | 311 """Check a list of suppressions and return a list of SuppressionErrors. |
| 328 | 312 |
| 329 Mostly useful for separating the checking logic from the Presubmit API for | 313 Mostly useful for separating the checking logic from the Presubmit API for |
| 330 testing. | 314 testing. |
| 331 """ | 315 """ |
| 332 known_supp_names = {} # Key: name, Value: suppression. | 316 known_supp_names = {} # Key: name, Value: suppression. |
| 333 errors = [] | 317 errors = [] |
| 334 for s in supps: | 318 for s in supps: |
| 335 if re.search("<.*suppression.name.here>", s.description): | 319 if re.search("<.*suppression.name.here>", s.description): |
| 336 # Suppression name line is | 320 # Suppression name line is |
| 337 # <insert_a_suppression_name_here> for Memcheck, | 321 # <insert_a_suppression_name_here> for Memcheck, |
| 338 # <Put your suppression name here> for TSan, | |
| 339 # name=<insert_a_suppression_name_here> for DrMemory | 322 # name=<insert_a_suppression_name_here> for DrMemory |
| 340 errors.append( | 323 errors.append( |
| 341 SuppressionError( | 324 SuppressionError( |
| 342 "You've forgotten to put a suppression name like bug_XXX", | 325 "You've forgotten to put a suppression name like bug_XXX", |
| 343 s.defined_at)) | 326 s.defined_at)) |
| 344 continue | 327 continue |
| 345 | 328 |
| 346 if s.description in known_supp_names: | 329 if s.description in known_supp_names: |
| 347 errors.append( | 330 errors.append( |
| 348 SuppressionError( | 331 SuppressionError( |
| 349 'Suppression named "%s" is defined more than once, ' | 332 'Suppression named "%s" is defined more than once, ' |
| 350 'see %s' % (s.description, | 333 'see %s' % (s.description, |
| 351 known_supp_names[s.description].defined_at), | 334 known_supp_names[s.description].defined_at), |
| 352 s.defined_at)) | 335 s.defined_at)) |
| 353 else: | 336 else: |
| 354 known_supp_names[s.description] = s | 337 known_supp_names[s.description] = s |
| 355 return errors | 338 return errors |
| 356 | 339 |
| 357 | 340 |
| 358 def PresubmitCheck(input_api, output_api): | 341 def PresubmitCheck(input_api, output_api): |
| 359 """A helper function useful in PRESUBMIT.py | 342 """A helper function useful in PRESUBMIT.py |
| 360 Returns a list of errors or []. | 343 Returns a list of errors or []. |
| 361 """ | 344 """ |
| 362 sup_regex = re.compile('suppressions.*\.txt$') | 345 sup_regex = re.compile('suppressions.*\.txt$') |
| 363 filenames = [f.AbsoluteLocalPath() for f in input_api.AffectedFiles() | 346 filenames = [f.AbsoluteLocalPath() for f in input_api.AffectedFiles() |
| 364 if sup_regex.search(f.LocalPath())] | 347 if sup_regex.search(f.LocalPath())] |
| 365 | 348 |
| 366 errors = [] | 349 errors = [] |
| 367 | 350 |
| 368 # TODO(timurrrr): warn on putting suppressions into a wrong file, | |
| 369 # e.g. TSan suppression in a memcheck file. | |
| 370 | |
| 371 for f in filenames: | 351 for f in filenames: |
| 372 try: | 352 try: |
| 373 supps = ReadSuppressionsFromFile(f) | 353 supps = ReadSuppressionsFromFile(f) |
| 374 errors.extend(PresubmitCheckSuppressions(supps)) | 354 errors.extend(PresubmitCheckSuppressions(supps)) |
| 375 except SuppressionError as e: | 355 except SuppressionError as e: |
| 376 errors.append(e) | 356 errors.append(e) |
| 377 | 357 |
| 378 return [output_api.PresubmitError(str(e)) for e in errors] | 358 return [output_api.PresubmitError(str(e)) for e in errors] |
| 379 | 359 |
| 380 | 360 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 test_memcheck_stack_4 = """{ | 602 test_memcheck_stack_4 = """{ |
| 623 test | 603 test |
| 624 Memcheck:Addr4 | 604 Memcheck:Addr4 |
| 625 fun:absolutly | 605 fun:absolutly |
| 626 fun:brilliant | 606 fun:brilliant |
| 627 obj:condition | 607 obj:condition |
| 628 fun:detection | 608 fun:detection |
| 629 fun:expression | 609 fun:expression |
| 630 }""" | 610 }""" |
| 631 | 611 |
| 632 test_tsan_stack = """{ | |
| 633 test | |
| 634 ThreadSanitizer:Race | |
| 635 fun:absolutly | |
| 636 fun:brilliant | |
| 637 obj:condition | |
| 638 fun:detection | |
| 639 fun:expression | |
| 640 }""" | |
| 641 | |
| 642 | |
| 643 positive_memcheck_suppressions_1 = [ | 612 positive_memcheck_suppressions_1 = [ |
| 644 "{\nzzz\nMemcheck:Leak\nfun:absolutly\n}", | 613 "{\nzzz\nMemcheck:Leak\nfun:absolutly\n}", |
| 645 "{\nzzz\nMemcheck:Leak\nfun:ab*ly\n}", | 614 "{\nzzz\nMemcheck:Leak\nfun:ab*ly\n}", |
| 646 "{\nzzz\nMemcheck:Leak\nfun:absolutly\nfun:brilliant\n}", | 615 "{\nzzz\nMemcheck:Leak\nfun:absolutly\nfun:brilliant\n}", |
| 647 "{\nzzz\nMemcheck:Leak\n...\nfun:brilliant\n}", | 616 "{\nzzz\nMemcheck:Leak\n...\nfun:brilliant\n}", |
| 648 "{\nzzz\nMemcheck:Leak\n...\nfun:detection\n}", | 617 "{\nzzz\nMemcheck:Leak\n...\nfun:detection\n}", |
| 649 "{\nzzz\nMemcheck:Leak\nfun:absolutly\n...\nfun:detection\n}", | 618 "{\nzzz\nMemcheck:Leak\nfun:absolutly\n...\nfun:detection\n}", |
| 650 "{\nzzz\nMemcheck:Leak\nfun:ab*ly\n...\nfun:detection\n}", | 619 "{\nzzz\nMemcheck:Leak\nfun:ab*ly\n...\nfun:detection\n}", |
| 651 "{\nzzz\nMemcheck:Leak\n...\nobj:condition\n}", | 620 "{\nzzz\nMemcheck:Leak\n...\nobj:condition\n}", |
| 652 "{\nzzz\nMemcheck:Leak\n...\nobj:condition\nfun:detection\n}", | 621 "{\nzzz\nMemcheck:Leak\n...\nobj:condition\nfun:detection\n}", |
| (...skipping 20 matching lines...) Expand all Loading... |
| 673 ] | 642 ] |
| 674 | 643 |
| 675 positive_memcheck_suppressions_4 = [ | 644 positive_memcheck_suppressions_4 = [ |
| 676 "{\nzzz\nMemcheck:Addr4\nfun:absolutly\n}", | 645 "{\nzzz\nMemcheck:Addr4\nfun:absolutly\n}", |
| 677 "{\nzzz\nMemcheck:Unaddressable\nfun:absolutly\n}", | 646 "{\nzzz\nMemcheck:Unaddressable\nfun:absolutly\n}", |
| 678 "{\nzzz\nMemcheck:Addr4\nfun:absolutly\nfun:brilliant\n}", | 647 "{\nzzz\nMemcheck:Addr4\nfun:absolutly\nfun:brilliant\n}", |
| 679 "{\nzzz\nMemcheck:Unaddressable\n...\nfun:brilliant\n}", | 648 "{\nzzz\nMemcheck:Unaddressable\n...\nfun:brilliant\n}", |
| 680 "{\nzzz\nMemcheck:Addr4\n...\nfun:detection\n}", | 649 "{\nzzz\nMemcheck:Addr4\n...\nfun:detection\n}", |
| 681 ] | 650 ] |
| 682 | 651 |
| 683 positive_tsan_suppressions = [ | |
| 684 "{\nzzz\nThreadSanitizer:Race\n...\nobj:condition\n}", | |
| 685 "{\nzzz\nThreadSanitizer:Race\nfun:absolutly\n}", | |
| 686 ] | |
| 687 | |
| 688 negative_memcheck_suppressions_1 = [ | 652 negative_memcheck_suppressions_1 = [ |
| 689 "{\nzzz\nMemcheck:Leak\nfun:abnormal\n}", | 653 "{\nzzz\nMemcheck:Leak\nfun:abnormal\n}", |
| 690 "{\nzzz\nMemcheck:Leak\nfun:ab*liant\n}", | 654 "{\nzzz\nMemcheck:Leak\nfun:ab*liant\n}", |
| 691 "{\nzzz\nMemcheck:Leak\nfun:brilliant\n}", | 655 "{\nzzz\nMemcheck:Leak\nfun:brilliant\n}", |
| 692 "{\nzzz\nMemcheck:Leak\nobj:condition\n}", | 656 "{\nzzz\nMemcheck:Leak\nobj:condition\n}", |
| 693 "{\nzzz\nMemcheck:Addr8\nfun:brilliant\n}", | 657 "{\nzzz\nMemcheck:Addr8\nfun:brilliant\n}", |
| 694 ] | 658 ] |
| 695 | 659 |
| 696 negative_memcheck_suppressions_2 = [ | 660 negative_memcheck_suppressions_2 = [ |
| 697 "{\nzzz\nMemcheck:Cond\nfun:abnormal\n}", | 661 "{\nzzz\nMemcheck:Cond\nfun:abnormal\n}", |
| (...skipping 18 matching lines...) Expand all Loading... |
| 716 "{\nzzz\nMemcheck:Addr1\nfun:abnormal\n}", | 680 "{\nzzz\nMemcheck:Addr1\nfun:abnormal\n}", |
| 717 "{\nzzz\nMemcheck:Addr4\nfun:abnormal\n}", | 681 "{\nzzz\nMemcheck:Addr4\nfun:abnormal\n}", |
| 718 "{\nzzz\nMemcheck:Unaddressable\nfun:abnormal\n}", | 682 "{\nzzz\nMemcheck:Unaddressable\nfun:abnormal\n}", |
| 719 "{\nzzz\nMemcheck:Addr1\nfun:absolutly\n}", | 683 "{\nzzz\nMemcheck:Addr1\nfun:absolutly\n}", |
| 720 "{\nzzz\nMemcheck:Addr2\nfun:ab*liant\n}", | 684 "{\nzzz\nMemcheck:Addr2\nfun:ab*liant\n}", |
| 721 "{\nzzz\nMemcheck:Value4\nfun:brilliant\n}", | 685 "{\nzzz\nMemcheck:Value4\nfun:brilliant\n}", |
| 722 "{\nzzz\nMemcheck:Leak\nobj:condition\n}", | 686 "{\nzzz\nMemcheck:Leak\nobj:condition\n}", |
| 723 "{\nzzz\nMemcheck:Addr8\nfun:brilliant\n}", | 687 "{\nzzz\nMemcheck:Addr8\nfun:brilliant\n}", |
| 724 ] | 688 ] |
| 725 | 689 |
| 726 negative_tsan_suppressions = [ | |
| 727 "{\nzzz\nThreadSanitizer:Leak\nfun:absolutly\n}", | |
| 728 "{\nzzz\nThreadSanitizer:Race\nfun:brilliant\n}", | |
| 729 ] | |
| 730 | |
| 731 TestStack(test_memcheck_stack_1, | 690 TestStack(test_memcheck_stack_1, |
| 732 positive_memcheck_suppressions_1, | 691 positive_memcheck_suppressions_1, |
| 733 negative_memcheck_suppressions_1) | 692 negative_memcheck_suppressions_1) |
| 734 TestStack(test_memcheck_stack_2, | 693 TestStack(test_memcheck_stack_2, |
| 735 positive_memcheck_suppressions_2, | 694 positive_memcheck_suppressions_2, |
| 736 negative_memcheck_suppressions_2) | 695 negative_memcheck_suppressions_2) |
| 737 TestStack(test_memcheck_stack_3, | 696 TestStack(test_memcheck_stack_3, |
| 738 positive_memcheck_suppressions_3, | 697 positive_memcheck_suppressions_3, |
| 739 negative_memcheck_suppressions_3) | 698 negative_memcheck_suppressions_3) |
| 740 TestStack(test_memcheck_stack_4, | 699 TestStack(test_memcheck_stack_4, |
| 741 positive_memcheck_suppressions_4, | 700 positive_memcheck_suppressions_4, |
| 742 negative_memcheck_suppressions_4) | 701 negative_memcheck_suppressions_4) |
| 743 TestStack(test_tsan_stack, positive_tsan_suppressions, | |
| 744 negative_tsan_suppressions) | |
| 745 | 702 |
| 746 # TODO(timurrrr): add TestFailPresubmit tests. | 703 # TODO(timurrrr): add TestFailPresubmit tests. |
| 747 | 704 |
| 748 ### DrMemory self tests. | 705 ### DrMemory self tests. |
| 749 | 706 |
| 750 # http://crbug.com/96010 suppression. | 707 # http://crbug.com/96010 suppression. |
| 751 stack_96010 = """{ | 708 stack_96010 = """{ |
| 752 UNADDRESSABLE ACCESS | 709 UNADDRESSABLE ACCESS |
| 753 name=<insert_a_suppression_name_here> | 710 name=<insert_a_suppression_name_here> |
| 754 *!TestingProfile::FinishInit | 711 *!TestingProfile::FinishInit |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 bad_stack_frame = """ | 882 bad_stack_frame = """ |
| 926 UNADDRESSABLE ACCESS | 883 UNADDRESSABLE ACCESS |
| 927 name=http://crbug.com/1234 | 884 name=http://crbug.com/1234 |
| 928 fun:memcheck_style_frame | 885 fun:memcheck_style_frame |
| 929 """ | 886 """ |
| 930 TestFailPresubmit(bad_stack_frame, 'Unexpected stack frame pattern', | 887 TestFailPresubmit(bad_stack_frame, 'Unexpected stack frame pattern', |
| 931 suppression_parser=ReadDrMemorySuppressions) | 888 suppression_parser=ReadDrMemorySuppressions) |
| 932 | 889 |
| 933 # Test FilenameToTool. | 890 # Test FilenameToTool. |
| 934 filenames_to_tools = { | 891 filenames_to_tools = { |
| 935 "tools/valgrind/tsan/suppressions.txt": "tsan", | |
| 936 "tools/valgrind/drmemory/suppressions.txt": "drmemory", | 892 "tools/valgrind/drmemory/suppressions.txt": "drmemory", |
| 937 "tools/valgrind/drmemory/suppressions_full.txt": "drmemory", | 893 "tools/valgrind/drmemory/suppressions_full.txt": "drmemory", |
| 938 "tools/valgrind/memcheck/suppressions.txt": "memcheck", | 894 "tools/valgrind/memcheck/suppressions.txt": "memcheck", |
| 939 "tools/valgrind/memcheck/suppressions_mac.txt": "memcheck", | 895 "tools/valgrind/memcheck/suppressions_mac.txt": "memcheck", |
| 940 "asdf/tools/valgrind/memcheck/suppressions_mac.txt": "memcheck", | 896 "asdf/tools/valgrind/memcheck/suppressions_mac.txt": "memcheck", |
| 941 "foo/bar/baz/tools/valgrind/memcheck/suppressions_mac.txt": "memcheck", | 897 "foo/bar/baz/tools/valgrind/memcheck/suppressions_mac.txt": "memcheck", |
| 942 "foo/bar/baz/tools/valgrind/suppressions.txt": None, | 898 "foo/bar/baz/tools/valgrind/suppressions.txt": None, |
| 943 "tools/valgrind/suppressions.txt": None, | 899 "tools/valgrind/suppressions.txt": None, |
| 944 } | 900 } |
| 945 for (filename, expected_tool) in filenames_to_tools.items(): | 901 for (filename, expected_tool) in filenames_to_tools.items(): |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 "instruction=test 0x08(%eax) $0x01\n" | 936 "instruction=test 0x08(%eax) $0x01\n" |
| 981 "ntdll.dll!*\n" | 937 "ntdll.dll!*\n" |
| 982 "*!foo\n") | 938 "*!foo\n") |
| 983 assert str(supp) == supp_str, ( | 939 assert str(supp) == supp_str, ( |
| 984 "str(supp) != supp_str:\nleft: %s\nright: %s" % (str(supp), supp_str)) | 940 "str(supp) != supp_str:\nleft: %s\nright: %s" % (str(supp), supp_str)) |
| 985 | 941 |
| 986 | 942 |
| 987 if __name__ == '__main__': | 943 if __name__ == '__main__': |
| 988 SelfTest() | 944 SelfTest() |
| 989 print 'PASS' | 945 print 'PASS' |
| OLD | NEW |