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

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

Issue 839143002: Roll Chrome into Mojo. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Rebase Created 5 years, 11 months 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
« no previous file with comments | « tools/valgrind/valgrind.sh ('k') | ui/gl/gl_context_egl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Runs an exe through Valgrind and puts the intermediate files in a 5 """Runs an exe through Valgrind and puts the intermediate files in a
6 directory. 6 directory.
7 """ 7 """
8 8
9 import datetime 9 import datetime
10 import glob 10 import glob
11 import logging 11 import logging
12 import optparse 12 import optparse
13 import os 13 import os
14 import re 14 import re
15 import shutil 15 import shutil
16 import stat 16 import stat
17 import subprocess 17 import subprocess
18 import sys 18 import sys
19 import tempfile 19 import tempfile
20 20
21 import common 21 import common
22 22
23 import drmemory_analyze 23 import drmemory_analyze
24 import memcheck_analyze 24 import memcheck_analyze
25 import tsan_analyze
26 25
27 class BaseTool(object): 26 class BaseTool(object):
28 """Abstract class for running Valgrind-, PIN-based and other dynamic 27 """Abstract class for running dynamic error detection tools.
29 error detector tools.
30 28
31 Always subclass this and implement ToolCommand with framework- and 29 Always subclass this and implement ToolCommand with framework- and
32 tool-specific stuff. 30 tool-specific stuff.
33 """ 31 """
34 32
35 def __init__(self): 33 def __init__(self):
36 temp_parent_dir = None 34 temp_parent_dir = None
37 self.log_parent_dir = "" 35 self.log_parent_dir = ""
38 if common.IsWindows(): 36 if common.IsWindows():
39 # gpu process on Windows Vista+ runs at Low Integrity and can only 37 # gpu process on Windows Vista+ runs at Low Integrity and can only
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 self._parser.add_option("", "--keep_logs", action="store_true", 98 self._parser.add_option("", "--keep_logs", action="store_true",
101 default=False, 99 default=False,
102 help="store memory tool logs in the <tool>.logs " 100 help="store memory tool logs in the <tool>.logs "
103 "directory instead of /tmp.\nThis can be " 101 "directory instead of /tmp.\nThis can be "
104 "useful for tool developers/maintainers.\n" 102 "useful for tool developers/maintainers.\n"
105 "Please note that the <tool>.logs directory " 103 "Please note that the <tool>.logs directory "
106 "will be clobbered on tool startup.") 104 "will be clobbered on tool startup.")
107 105
108 # To add framework- or tool-specific flags, please add a hook using 106 # To add framework- or tool-specific flags, please add a hook using
109 # RegisterOptionParserHook in the corresponding subclass. 107 # RegisterOptionParserHook in the corresponding subclass.
110 # See ValgrindTool and ThreadSanitizerBase for examples. 108 # See ValgrindTool for an example.
111 for hook in self.option_parser_hooks: 109 for hook in self.option_parser_hooks:
112 hook(self, self._parser) 110 hook(self, self._parser)
113 111
114 def ParseArgv(self, args): 112 def ParseArgv(self, args):
115 self.CreateOptionParser() 113 self.CreateOptionParser()
116 114
117 # self._tool_flags will store those tool flags which we don't parse 115 # self._tool_flags will store those tool flags which we don't parse
118 # manually in this script. 116 # manually in this script.
119 self._tool_flags = [] 117 self._tool_flags = []
120 known_args = [] 118 known_args = []
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 runtime_in_seconds < min_runtime_in_seconds): 220 runtime_in_seconds < min_runtime_in_seconds):
223 logging.error("Layout tests finished too quickly. " 221 logging.error("Layout tests finished too quickly. "
224 "It should have taken at least %d seconds. " 222 "It should have taken at least %d seconds. "
225 "Something went wrong?" % min_runtime_in_seconds) 223 "Something went wrong?" % min_runtime_in_seconds)
226 retcode = -1 224 retcode = -1
227 return retcode 225 return retcode
228 226
229 def Run(self, args, module, min_runtime_in_seconds=0): 227 def Run(self, args, module, min_runtime_in_seconds=0):
230 MODULES_TO_SANITY_CHECK = ["base"] 228 MODULES_TO_SANITY_CHECK = ["base"]
231 229
232 # TODO(timurrrr): this is a temporary workaround for http://crbug.com/47844
233 if self.ToolName() == "tsan" and common.IsMac():
234 MODULES_TO_SANITY_CHECK = []
235
236 check_sanity = module in MODULES_TO_SANITY_CHECK 230 check_sanity = module in MODULES_TO_SANITY_CHECK
237 return self.Main(args, check_sanity, min_runtime_in_seconds) 231 return self.Main(args, check_sanity, min_runtime_in_seconds)
238 232
239 233
240 class ValgrindTool(BaseTool): 234 class ValgrindTool(BaseTool):
241 """Abstract class for running Valgrind tools. 235 """Abstract class for running Valgrind tools.
242 236
243 Always subclass this and implement ToolSpecificFlags() and 237 Always subclass this and implement ToolSpecificFlags() and
244 ExtendOptionParser() for tool-specific stuff. 238 ExtendOptionParser() for tool-specific stuff.
245 """ 239 """
246 def __init__(self): 240 def __init__(self):
247 super(ValgrindTool, self).__init__() 241 super(ValgrindTool, self).__init__()
248 self.RegisterOptionParserHook(ValgrindTool.ExtendOptionParser) 242 self.RegisterOptionParserHook(ValgrindTool.ExtendOptionParser)
249 243
250 def UseXML(self): 244 def UseXML(self):
251 # Override if tool prefers nonxml output 245 # Override if tool prefers nonxml output
252 return True 246 return True
253 247
254 def SelfContained(self):
255 # Returns true iff the tool is distibuted as a self-contained
256 # .sh script (e.g. ThreadSanitizer)
257 return False
258
259 def ExtendOptionParser(self, parser): 248 def ExtendOptionParser(self, parser):
260 parser.add_option("", "--suppressions", default=[], 249 parser.add_option("", "--suppressions", default=[],
261 action="append", 250 action="append",
262 help="path to a valgrind suppression file") 251 help="path to a valgrind suppression file")
263 parser.add_option("", "--indirect", action="store_true", 252 parser.add_option("", "--indirect", action="store_true",
264 default=False, 253 default=False,
265 help="set BROWSER_WRAPPER rather than " 254 help="set BROWSER_WRAPPER rather than "
266 "running valgrind directly") 255 "running valgrind directly")
267 parser.add_option("", "--indirect_webkit_layout", action="store_true", 256 parser.add_option("", "--indirect_webkit_layout", action="store_true",
268 default=False, 257 default=False,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 logging.info("No real .dSYM for test_command. Line numbers will " 336 logging.info("No real .dSYM for test_command. Line numbers will "
348 "not be shown. Either tell xcode to generate .dSYM " 337 "not be shown. Either tell xcode to generate .dSYM "
349 "file, or use --generate_dsym option to this tool.") 338 "file, or use --generate_dsym option to this tool.")
350 339
351 def ToolCommand(self): 340 def ToolCommand(self):
352 """Get the valgrind command to run.""" 341 """Get the valgrind command to run."""
353 # Note that self._args begins with the exe to be run. 342 # Note that self._args begins with the exe to be run.
354 tool_name = self.ToolName() 343 tool_name = self.ToolName()
355 344
356 # Construct the valgrind command. 345 # Construct the valgrind command.
357 if self.SelfContained(): 346 if 'CHROME_VALGRIND' in os.environ:
358 proc = ["valgrind-%s.sh" % tool_name] 347 path = os.path.join(os.environ['CHROME_VALGRIND'], "bin", "valgrind")
359 else: 348 else:
360 if 'CHROME_VALGRIND' in os.environ: 349 path = "valgrind"
361 path = os.path.join(os.environ['CHROME_VALGRIND'], "bin", "valgrind") 350 proc = [path, "--tool=%s" % tool_name]
362 else:
363 path = "valgrind"
364 proc = [path, "--tool=%s" % tool_name]
365 351
366 proc += ["--num-callers=%i" % int(self._options.num_callers)] 352 proc += ["--num-callers=%i" % int(self._options.num_callers)]
367 353
368 if self._options.trace_children: 354 if self._options.trace_children:
369 proc += ["--trace-children=yes"] 355 proc += ["--trace-children=yes"]
370 proc += ["--trace-children-skip='*dbus-daemon*'"] 356 proc += ["--trace-children-skip='*dbus-daemon*'"]
371 proc += ["--trace-children-skip='*dbus-launch*'"] 357 proc += ["--trace-children-skip='*dbus-launch*'"]
372 proc += ["--trace-children-skip='*perl*'"] 358 proc += ["--trace-children-skip='*perl*'"]
373 proc += ["--trace-children-skip='*python*'"] 359 proc += ["--trace-children-skip='*python*'"]
374 # This is really Python, but for some reason Valgrind follows it. 360 # This is really Python, but for some reason Valgrind follows it.
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 562
577 def Analyze(self, check_sanity=False): 563 def Analyze(self, check_sanity=False):
578 ret = self.GetAnalyzeResults(check_sanity) 564 ret = self.GetAnalyzeResults(check_sanity)
579 565
580 if ret != 0: 566 if ret != 0:
581 logging.info("Please see http://dev.chromium.org/developers/how-tos/" 567 logging.info("Please see http://dev.chromium.org/developers/how-tos/"
582 "using-valgrind for the info on Memcheck/Valgrind") 568 "using-valgrind for the info on Memcheck/Valgrind")
583 return ret 569 return ret
584 570
585 571
586 class PinTool(BaseTool):
587 """Abstract class for running PIN tools.
588
589 Always subclass this and implement ToolSpecificFlags() and
590 ExtendOptionParser() for tool-specific stuff.
591 """
592 def PrepareForTest(self):
593 pass
594
595 def ToolSpecificFlags(self):
596 raise NotImplementedError, "This method should be implemented " \
597 "in the tool-specific subclass"
598
599 def ToolCommand(self):
600 """Get the PIN command to run."""
601
602 # Construct the PIN command.
603 pin_cmd = os.getenv("PIN_COMMAND")
604 if not pin_cmd:
605 raise RuntimeError, "Please set PIN_COMMAND environment variable " \
606 "with the path to pin.exe"
607 proc = pin_cmd.split(" ")
608
609 proc += self.ToolSpecificFlags()
610
611 # The PIN command is constructed.
612
613 # PIN requires -- to separate PIN flags from the executable name.
614 # self._args begins with the exe to be run.
615 proc += ["--"]
616
617 proc += self._args
618 return proc
619
620
621 class ThreadSanitizerBase(object):
622 """ThreadSanitizer
623 Dynamic data race detector for Linux, Mac and Windows.
624
625 http://code.google.com/p/data-race-test/wiki/ThreadSanitizer
626
627 Since TSan works on both Valgrind (Linux, Mac) and PIN (Windows), we need
628 to have multiple inheritance
629 """
630
631 INFO_MESSAGE="Please see http://dev.chromium.org/developers/how-tos/" \
632 "using-valgrind/threadsanitizer for the info on " \
633 "ThreadSanitizer"
634
635 def __init__(self):
636 super(ThreadSanitizerBase, self).__init__()
637 self.RegisterOptionParserHook(ThreadSanitizerBase.ExtendOptionParser)
638
639 def ToolName(self):
640 return "tsan"
641
642 def UseXML(self):
643 return False
644
645 def SelfContained(self):
646 return True
647
648 def ExtendOptionParser(self, parser):
649 parser.add_option("", "--hybrid", default="no",
650 dest="hybrid",
651 help="Finds more data races, may give false positive "
652 "reports unless the code is annotated")
653 parser.add_option("", "--announce-threads", default="yes",
654 dest="announce_threads",
655 help="Show the the stack traces of thread creation")
656 parser.add_option("", "--free-is-write", default="no",
657 dest="free_is_write",
658 help="Treat free()/operator delete as memory write. "
659 "This helps finding more data races, but (currently) "
660 "this may give false positive reports on std::string "
661 "internals, see http://code.google.com/p/data-race-test"
662 "/issues/detail?id=40")
663
664 def EvalBoolFlag(self, flag_value):
665 if (flag_value in ["1", "true", "yes"]):
666 return True
667 elif (flag_value in ["0", "false", "no"]):
668 return False
669 raise RuntimeError, "Can't parse flag value (%s)" % flag_value
670
671 def ToolSpecificFlags(self):
672 ret = []
673
674 ignore_files = ["ignores.txt"]
675 for platform_suffix in common.PlatformNames():
676 ignore_files.append("ignores_%s.txt" % platform_suffix)
677 for ignore_file in ignore_files:
678 fullname = os.path.join(self._source_dir,
679 "tools", "valgrind", "tsan", ignore_file)
680 if os.path.exists(fullname):
681 fullname = common.NormalizeWindowsPath(fullname)
682 ret += ["--ignore=%s" % fullname]
683
684 # This should shorten filepaths for local builds.
685 ret += ["--file-prefix-to-cut=%s/" % self._source_dir]
686
687 # This should shorten filepaths on bots.
688 ret += ["--file-prefix-to-cut=build/src/"]
689 ret += ["--file-prefix-to-cut=out/Release/../../"]
690
691 # This should shorten filepaths for functions intercepted in TSan.
692 ret += ["--file-prefix-to-cut=scripts/tsan/tsan/"]
693 ret += ["--file-prefix-to-cut=src/tsan/tsan/"]
694
695 ret += ["--gen-suppressions=true"]
696
697 if self.EvalBoolFlag(self._options.hybrid):
698 ret += ["--hybrid=yes"] # "no" is the default value for TSAN
699
700 if self.EvalBoolFlag(self._options.announce_threads):
701 ret += ["--announce-threads"]
702
703 if self.EvalBoolFlag(self._options.free_is_write):
704 ret += ["--free-is-write=yes"]
705 else:
706 ret += ["--free-is-write=no"]
707
708
709 # --show-pc flag is needed for parsing the error logs on Darwin.
710 if platform_suffix == 'mac':
711 ret += ["--show-pc=yes"]
712 ret += ["--show-pid=no"]
713
714 boring_callers = common.BoringCallers(mangled=False, use_re_wildcards=False)
715 # TODO(timurrrr): In fact, we want "starting from .." instead of "below .."
716 for bc in boring_callers:
717 ret += ["--cut_stack_below=%s" % bc]
718
719 return ret
720
721
722 class ThreadSanitizerPosix(ThreadSanitizerBase, ValgrindTool):
723 def ToolSpecificFlags(self):
724 proc = ThreadSanitizerBase.ToolSpecificFlags(self)
725 # The -v flag is needed for printing the list of used suppressions and
726 # obtaining addresses for loaded shared libraries on Mac.
727 proc += ["-v"]
728 return proc
729
730 def CreateAnalyzer(self):
731 use_gdb = common.IsMac()
732 return tsan_analyze.TsanAnalyzer(use_gdb)
733
734 def Analyze(self, check_sanity=False):
735 ret = self.GetAnalyzeResults(check_sanity)
736
737 if ret != 0:
738 logging.info(self.INFO_MESSAGE)
739 return ret
740
741
742 class ThreadSanitizerWindows(ThreadSanitizerBase, PinTool):
743
744 def __init__(self):
745 super(ThreadSanitizerWindows, self).__init__()
746 self.RegisterOptionParserHook(ThreadSanitizerWindows.ExtendOptionParser)
747
748 def ExtendOptionParser(self, parser):
749 parser.add_option("", "--suppressions", default=[],
750 action="append",
751 help="path to TSan suppression file")
752
753
754 def ToolSpecificFlags(self):
755 add_env = {
756 "CHROME_ALLOCATOR" : "WINHEAP",
757 }
758 for k,v in add_env.iteritems():
759 logging.info("export %s=%s", k, v)
760 os.putenv(k, v)
761
762 proc = ThreadSanitizerBase.ToolSpecificFlags(self)
763 # On PIN, ThreadSanitizer has its own suppression mechanism
764 # and --log-file flag which work exactly on Valgrind.
765 suppression_count = 0
766 for suppression_file in self._options.suppressions:
767 if os.path.exists(suppression_file):
768 suppression_count += 1
769 suppression_file = common.NormalizeWindowsPath(suppression_file)
770 proc += ["--suppressions=%s" % suppression_file]
771
772 if not suppression_count:
773 logging.warning("WARNING: NOT USING SUPPRESSIONS!")
774
775 logfilename = self.log_dir + "/tsan.%p"
776 proc += ["--log-file=" + common.NormalizeWindowsPath(logfilename)]
777
778 # TODO(timurrrr): Add flags for Valgrind trace children analog when we
779 # start running complex tests (e.g. UI) under TSan/Win.
780
781 return proc
782
783 def Analyze(self, check_sanity=False):
784 filenames = glob.glob(self.log_dir + "/tsan.*")
785 analyzer = tsan_analyze.TsanAnalyzer()
786 ret = analyzer.Report(filenames, None, check_sanity)
787 if ret != 0:
788 logging.info(self.INFO_MESSAGE)
789 return ret
790
791
792 class DrMemory(BaseTool): 572 class DrMemory(BaseTool):
793 """Dr.Memory 573 """Dr.Memory
794 Dynamic memory error detector for Windows. 574 Dynamic memory error detector for Windows.
795 575
796 http://dev.chromium.org/developers/how-tos/using-drmemory 576 http://dev.chromium.org/developers/how-tos/using-drmemory
797 It is not very mature at the moment, some things might not work properly. 577 It is not very mature at the moment, some things might not work properly.
798 """ 578 """
799 579
800 def __init__(self, full_mode, pattern_mode): 580 def __init__(self, full_mode, pattern_mode):
801 super(DrMemory, self).__init__() 581 super(DrMemory, self).__init__()
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 proc += ["-pattern", "0xf1fd", "-no_count_leaks", "-redzone_size", "0x20"] 736 proc += ["-pattern", "0xf1fd", "-no_count_leaks", "-redzone_size", "0x20"]
957 elif not self.full_mode: 737 elif not self.full_mode:
958 proc += ["-light"] 738 proc += ["-light"]
959 739
960 proc += self._tool_flags 740 proc += self._tool_flags
961 741
962 # Dr.Memory requires -- to separate tool flags from the executable name. 742 # Dr.Memory requires -- to separate tool flags from the executable name.
963 proc += ["--"] 743 proc += ["--"]
964 744
965 if self._options.indirect or self._options.indirect_webkit_layout: 745 if self._options.indirect or self._options.indirect_webkit_layout:
966 # TODO(timurrrr): reuse for TSan on Windows
967 wrapper_path = os.path.join(self._source_dir, 746 wrapper_path = os.path.join(self._source_dir,
968 "tools", "valgrind", "browser_wrapper_win.py") 747 "tools", "valgrind", "browser_wrapper_win.py")
969 wrapper = " ".join(["python", wrapper_path] + proc) 748 wrapper = " ".join(["python", wrapper_path] + proc)
970 self.CreateBrowserWrapper(wrapper) 749 self.CreateBrowserWrapper(wrapper)
971 logging.info("browser wrapper = " + " ".join(proc)) 750 logging.info("browser wrapper = " + " ".join(proc))
972 if self._options.indirect_webkit_layout: 751 if self._options.indirect_webkit_layout:
973 proc = self._args 752 proc = self._args
974 # Layout tests want forward slashes. 753 # Layout tests want forward slashes.
975 wrapper = wrapper.replace('\\', '/') 754 wrapper = wrapper.replace('\\', '/')
976 proc += ["--wrapper", wrapper] 755 proc += ["--wrapper", wrapper]
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 (self.log_dir, ppid)) 806 (self.log_dir, ppid))
1028 ret |= analyzer.Report(ppid_filenames, testcase_name, False) 807 ret |= analyzer.Report(ppid_filenames, testcase_name, False)
1029 print "=====================================================" 808 print "====================================================="
1030 sys.stdout.flush() 809 sys.stdout.flush()
1031 810
1032 logging.info("Please see http://dev.chromium.org/developers/how-tos/" 811 logging.info("Please see http://dev.chromium.org/developers/how-tos/"
1033 "using-drmemory for the info on Dr. Memory") 812 "using-drmemory for the info on Dr. Memory")
1034 return ret 813 return ret
1035 814
1036 815
1037 # RaceVerifier support. See
1038 # http://code.google.com/p/data-race-test/wiki/RaceVerifier for more details.
1039 class ThreadSanitizerRV1Analyzer(tsan_analyze.TsanAnalyzer):
1040 """ TsanAnalyzer that saves race reports to a file. """
1041
1042 TMP_FILE = "rvlog.tmp"
1043
1044 def __init__(self, source_dir, use_gdb):
1045 super(ThreadSanitizerRV1Analyzer, self).__init__(use_gdb)
1046 self.out = open(self.TMP_FILE, "w")
1047
1048 def Report(self, files, testcase, check_sanity=False):
1049 reports = self.GetReports(files)
1050 for report in reports:
1051 print >>self.out, report
1052 if len(reports) > 0:
1053 logging.info("RaceVerifier pass 1 of 2, found %i reports" % len(reports))
1054 return -1
1055 return 0
1056
1057 def CloseOutputFile(self):
1058 self.out.close()
1059
1060
1061 class ThreadSanitizerRV1Mixin(object):
1062 """RaceVerifier first pass.
1063
1064 Runs ThreadSanitizer as usual, but hides race reports and collects them in a
1065 temporary file"""
1066
1067 def __init__(self):
1068 super(ThreadSanitizerRV1Mixin, self).__init__()
1069 self.RegisterOptionParserHook(ThreadSanitizerRV1Mixin.ExtendOptionParser)
1070
1071 def ExtendOptionParser(self, parser):
1072 parser.set_defaults(hybrid="yes")
1073
1074 def CreateAnalyzer(self):
1075 use_gdb = common.IsMac()
1076 self.analyzer = ThreadSanitizerRV1Analyzer(self._source_dir, use_gdb)
1077 return self.analyzer
1078
1079 def Cleanup(self):
1080 super(ThreadSanitizerRV1Mixin, self).Cleanup()
1081 self.analyzer.CloseOutputFile()
1082
1083
1084 class ThreadSanitizerRV2Mixin(object):
1085 """RaceVerifier second pass."""
1086
1087 def __init__(self):
1088 super(ThreadSanitizerRV2Mixin, self).__init__()
1089 self.RegisterOptionParserHook(ThreadSanitizerRV2Mixin.ExtendOptionParser)
1090
1091 def ExtendOptionParser(self, parser):
1092 parser.add_option("", "--race-verifier-sleep-ms",
1093 dest="race_verifier_sleep_ms", default=10,
1094 help="duration of RaceVerifier delays")
1095
1096 def ToolSpecificFlags(self):
1097 proc = super(ThreadSanitizerRV2Mixin, self).ToolSpecificFlags()
1098 proc += ['--race-verifier=%s' % ThreadSanitizerRV1Analyzer.TMP_FILE,
1099 '--race-verifier-sleep-ms=%d' %
1100 int(self._options.race_verifier_sleep_ms)]
1101 return proc
1102
1103 def Cleanup(self):
1104 super(ThreadSanitizerRV2Mixin, self).Cleanup()
1105 os.unlink(ThreadSanitizerRV1Analyzer.TMP_FILE)
1106
1107
1108 class ThreadSanitizerRV1Posix(ThreadSanitizerRV1Mixin, ThreadSanitizerPosix):
1109 pass
1110
1111
1112 class ThreadSanitizerRV2Posix(ThreadSanitizerRV2Mixin, ThreadSanitizerPosix):
1113 pass
1114
1115
1116 class ThreadSanitizerRV1Windows(ThreadSanitizerRV1Mixin,
1117 ThreadSanitizerWindows):
1118 pass
1119
1120
1121 class ThreadSanitizerRV2Windows(ThreadSanitizerRV2Mixin,
1122 ThreadSanitizerWindows):
1123 pass
1124
1125
1126 class RaceVerifier(object):
1127 """Runs tests under RaceVerifier/Valgrind."""
1128
1129 MORE_INFO_URL = "http://code.google.com/p/data-race-test/wiki/RaceVerifier"
1130
1131 def RV1Factory(self):
1132 if common.IsWindows():
1133 return ThreadSanitizerRV1Windows()
1134 else:
1135 return ThreadSanitizerRV1Posix()
1136
1137 def RV2Factory(self):
1138 if common.IsWindows():
1139 return ThreadSanitizerRV2Windows()
1140 else:
1141 return ThreadSanitizerRV2Posix()
1142
1143 def ToolName(self):
1144 return "tsan"
1145
1146 def Main(self, args, check_sanity, min_runtime_in_seconds):
1147 logging.info("Running a TSan + RaceVerifier test. For more information, " +
1148 "see " + self.MORE_INFO_URL)
1149 cmd1 = self.RV1Factory()
1150 ret = cmd1.Main(args, check_sanity, min_runtime_in_seconds)
1151 # Verify race reports, if there are any.
1152 if ret == -1:
1153 logging.info("Starting pass 2 of 2. Running the same binary in " +
1154 "RaceVerifier mode to confirm possible race reports.")
1155 logging.info("For more information, see " + self.MORE_INFO_URL)
1156 cmd2 = self.RV2Factory()
1157 ret = cmd2.Main(args, check_sanity, min_runtime_in_seconds)
1158 else:
1159 logging.info("No reports, skipping RaceVerifier second pass")
1160 logging.info("Please see " + self.MORE_INFO_URL + " for more information " +
1161 "on RaceVerifier")
1162 return ret
1163
1164 def Run(self, args, module, min_runtime_in_seconds=0):
1165 return self.Main(args, False, min_runtime_in_seconds)
1166
1167
1168 class ToolFactory: 816 class ToolFactory:
1169 def Create(self, tool_name): 817 def Create(self, tool_name):
1170 if tool_name == "memcheck": 818 if tool_name == "memcheck":
1171 return Memcheck() 819 return Memcheck()
1172 if tool_name == "tsan":
1173 if common.IsWindows():
1174 return ThreadSanitizerWindows()
1175 else:
1176 return ThreadSanitizerPosix()
1177 if tool_name == "drmemory" or tool_name == "drmemory_light": 820 if tool_name == "drmemory" or tool_name == "drmemory_light":
1178 # TODO(timurrrr): remove support for "drmemory" when buildbots are 821 # TODO(timurrrr): remove support for "drmemory" when buildbots are
1179 # switched to drmemory_light OR make drmemory==drmemory_full the default 822 # switched to drmemory_light OR make drmemory==drmemory_full the default
1180 # mode when the tool is mature enough. 823 # mode when the tool is mature enough.
1181 return DrMemory(False, False) 824 return DrMemory(False, False)
1182 if tool_name == "drmemory_full": 825 if tool_name == "drmemory_full":
1183 return DrMemory(True, False) 826 return DrMemory(True, False)
1184 if tool_name == "drmemory_pattern": 827 if tool_name == "drmemory_pattern":
1185 return DrMemory(False, True) 828 return DrMemory(False, True)
1186 if tool_name == "tsan_rv":
1187 return RaceVerifier()
1188 try: 829 try:
1189 platform_name = common.PlatformNames()[0] 830 platform_name = common.PlatformNames()[0]
1190 except common.NotImplementedError: 831 except common.NotImplementedError:
1191 platform_name = sys.platform + "(Unknown)" 832 platform_name = sys.platform + "(Unknown)"
1192 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, 833 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name,
1193 platform_name) 834 platform_name)
1194 835
1195 def CreateTool(tool): 836 def CreateTool(tool):
1196 return ToolFactory().Create(tool) 837 return ToolFactory().Create(tool)
OLDNEW
« no previous file with comments | « tools/valgrind/valgrind.sh ('k') | ui/gl/gl_context_egl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698