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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/valgrind/valgrind.sh ('k') | ui/gl/gl_context_egl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/valgrind/valgrind_test.py
diff --git a/tools/valgrind/valgrind_test.py b/tools/valgrind/valgrind_test.py
index 24fa32acb49850935a7ccbdd846b9fb08de821a7..5576ed3177655d43038fc6e24609227e95610000 100644
--- a/tools/valgrind/valgrind_test.py
+++ b/tools/valgrind/valgrind_test.py
@@ -22,11 +22,9 @@ import common
import drmemory_analyze
import memcheck_analyze
-import tsan_analyze
class BaseTool(object):
- """Abstract class for running Valgrind-, PIN-based and other dynamic
- error detector tools.
+ """Abstract class for running dynamic error detection tools.
Always subclass this and implement ToolCommand with framework- and
tool-specific stuff.
@@ -107,7 +105,7 @@ class BaseTool(object):
# To add framework- or tool-specific flags, please add a hook using
# RegisterOptionParserHook in the corresponding subclass.
- # See ValgrindTool and ThreadSanitizerBase for examples.
+ # See ValgrindTool for an example.
for hook in self.option_parser_hooks:
hook(self, self._parser)
@@ -229,10 +227,6 @@ class BaseTool(object):
def Run(self, args, module, min_runtime_in_seconds=0):
MODULES_TO_SANITY_CHECK = ["base"]
- # TODO(timurrrr): this is a temporary workaround for http://crbug.com/47844
- if self.ToolName() == "tsan" and common.IsMac():
- MODULES_TO_SANITY_CHECK = []
-
check_sanity = module in MODULES_TO_SANITY_CHECK
return self.Main(args, check_sanity, min_runtime_in_seconds)
@@ -251,11 +245,6 @@ class ValgrindTool(BaseTool):
# Override if tool prefers nonxml output
return True
- def SelfContained(self):
- # Returns true iff the tool is distibuted as a self-contained
- # .sh script (e.g. ThreadSanitizer)
- return False
-
def ExtendOptionParser(self, parser):
parser.add_option("", "--suppressions", default=[],
action="append",
@@ -354,14 +343,11 @@ class ValgrindTool(BaseTool):
tool_name = self.ToolName()
# Construct the valgrind command.
- if self.SelfContained():
- proc = ["valgrind-%s.sh" % tool_name]
+ if 'CHROME_VALGRIND' in os.environ:
+ path = os.path.join(os.environ['CHROME_VALGRIND'], "bin", "valgrind")
else:
- if 'CHROME_VALGRIND' in os.environ:
- path = os.path.join(os.environ['CHROME_VALGRIND'], "bin", "valgrind")
- else:
- path = "valgrind"
- proc = [path, "--tool=%s" % tool_name]
+ path = "valgrind"
+ proc = [path, "--tool=%s" % tool_name]
proc += ["--num-callers=%i" % int(self._options.num_callers)]
@@ -583,212 +569,6 @@ class Memcheck(ValgrindTool):
return ret
-class PinTool(BaseTool):
- """Abstract class for running PIN tools.
-
- Always subclass this and implement ToolSpecificFlags() and
- ExtendOptionParser() for tool-specific stuff.
- """
- def PrepareForTest(self):
- pass
-
- def ToolSpecificFlags(self):
- raise NotImplementedError, "This method should be implemented " \
- "in the tool-specific subclass"
-
- def ToolCommand(self):
- """Get the PIN command to run."""
-
- # Construct the PIN command.
- pin_cmd = os.getenv("PIN_COMMAND")
- if not pin_cmd:
- raise RuntimeError, "Please set PIN_COMMAND environment variable " \
- "with the path to pin.exe"
- proc = pin_cmd.split(" ")
-
- proc += self.ToolSpecificFlags()
-
- # The PIN command is constructed.
-
- # PIN requires -- to separate PIN flags from the executable name.
- # self._args begins with the exe to be run.
- proc += ["--"]
-
- proc += self._args
- return proc
-
-
-class ThreadSanitizerBase(object):
- """ThreadSanitizer
- Dynamic data race detector for Linux, Mac and Windows.
-
- http://code.google.com/p/data-race-test/wiki/ThreadSanitizer
-
- Since TSan works on both Valgrind (Linux, Mac) and PIN (Windows), we need
- to have multiple inheritance
- """
-
- INFO_MESSAGE="Please see http://dev.chromium.org/developers/how-tos/" \
- "using-valgrind/threadsanitizer for the info on " \
- "ThreadSanitizer"
-
- def __init__(self):
- super(ThreadSanitizerBase, self).__init__()
- self.RegisterOptionParserHook(ThreadSanitizerBase.ExtendOptionParser)
-
- def ToolName(self):
- return "tsan"
-
- def UseXML(self):
- return False
-
- def SelfContained(self):
- return True
-
- def ExtendOptionParser(self, parser):
- parser.add_option("", "--hybrid", default="no",
- dest="hybrid",
- help="Finds more data races, may give false positive "
- "reports unless the code is annotated")
- parser.add_option("", "--announce-threads", default="yes",
- dest="announce_threads",
- help="Show the the stack traces of thread creation")
- parser.add_option("", "--free-is-write", default="no",
- dest="free_is_write",
- help="Treat free()/operator delete as memory write. "
- "This helps finding more data races, but (currently) "
- "this may give false positive reports on std::string "
- "internals, see http://code.google.com/p/data-race-test"
- "/issues/detail?id=40")
-
- def EvalBoolFlag(self, flag_value):
- if (flag_value in ["1", "true", "yes"]):
- return True
- elif (flag_value in ["0", "false", "no"]):
- return False
- raise RuntimeError, "Can't parse flag value (%s)" % flag_value
-
- def ToolSpecificFlags(self):
- ret = []
-
- ignore_files = ["ignores.txt"]
- for platform_suffix in common.PlatformNames():
- ignore_files.append("ignores_%s.txt" % platform_suffix)
- for ignore_file in ignore_files:
- fullname = os.path.join(self._source_dir,
- "tools", "valgrind", "tsan", ignore_file)
- if os.path.exists(fullname):
- fullname = common.NormalizeWindowsPath(fullname)
- ret += ["--ignore=%s" % fullname]
-
- # This should shorten filepaths for local builds.
- ret += ["--file-prefix-to-cut=%s/" % self._source_dir]
-
- # This should shorten filepaths on bots.
- ret += ["--file-prefix-to-cut=build/src/"]
- ret += ["--file-prefix-to-cut=out/Release/../../"]
-
- # This should shorten filepaths for functions intercepted in TSan.
- ret += ["--file-prefix-to-cut=scripts/tsan/tsan/"]
- ret += ["--file-prefix-to-cut=src/tsan/tsan/"]
-
- ret += ["--gen-suppressions=true"]
-
- if self.EvalBoolFlag(self._options.hybrid):
- ret += ["--hybrid=yes"] # "no" is the default value for TSAN
-
- if self.EvalBoolFlag(self._options.announce_threads):
- ret += ["--announce-threads"]
-
- if self.EvalBoolFlag(self._options.free_is_write):
- ret += ["--free-is-write=yes"]
- else:
- ret += ["--free-is-write=no"]
-
-
- # --show-pc flag is needed for parsing the error logs on Darwin.
- if platform_suffix == 'mac':
- ret += ["--show-pc=yes"]
- ret += ["--show-pid=no"]
-
- boring_callers = common.BoringCallers(mangled=False, use_re_wildcards=False)
- # TODO(timurrrr): In fact, we want "starting from .." instead of "below .."
- for bc in boring_callers:
- ret += ["--cut_stack_below=%s" % bc]
-
- return ret
-
-
-class ThreadSanitizerPosix(ThreadSanitizerBase, ValgrindTool):
- def ToolSpecificFlags(self):
- proc = ThreadSanitizerBase.ToolSpecificFlags(self)
- # The -v flag is needed for printing the list of used suppressions and
- # obtaining addresses for loaded shared libraries on Mac.
- proc += ["-v"]
- return proc
-
- def CreateAnalyzer(self):
- use_gdb = common.IsMac()
- return tsan_analyze.TsanAnalyzer(use_gdb)
-
- def Analyze(self, check_sanity=False):
- ret = self.GetAnalyzeResults(check_sanity)
-
- if ret != 0:
- logging.info(self.INFO_MESSAGE)
- return ret
-
-
-class ThreadSanitizerWindows(ThreadSanitizerBase, PinTool):
-
- def __init__(self):
- super(ThreadSanitizerWindows, self).__init__()
- self.RegisterOptionParserHook(ThreadSanitizerWindows.ExtendOptionParser)
-
- def ExtendOptionParser(self, parser):
- parser.add_option("", "--suppressions", default=[],
- action="append",
- help="path to TSan suppression file")
-
-
- def ToolSpecificFlags(self):
- add_env = {
- "CHROME_ALLOCATOR" : "WINHEAP",
- }
- for k,v in add_env.iteritems():
- logging.info("export %s=%s", k, v)
- os.putenv(k, v)
-
- proc = ThreadSanitizerBase.ToolSpecificFlags(self)
- # On PIN, ThreadSanitizer has its own suppression mechanism
- # and --log-file flag which work exactly on Valgrind.
- suppression_count = 0
- for suppression_file in self._options.suppressions:
- if os.path.exists(suppression_file):
- suppression_count += 1
- suppression_file = common.NormalizeWindowsPath(suppression_file)
- proc += ["--suppressions=%s" % suppression_file]
-
- if not suppression_count:
- logging.warning("WARNING: NOT USING SUPPRESSIONS!")
-
- logfilename = self.log_dir + "/tsan.%p"
- proc += ["--log-file=" + common.NormalizeWindowsPath(logfilename)]
-
- # TODO(timurrrr): Add flags for Valgrind trace children analog when we
- # start running complex tests (e.g. UI) under TSan/Win.
-
- return proc
-
- def Analyze(self, check_sanity=False):
- filenames = glob.glob(self.log_dir + "/tsan.*")
- analyzer = tsan_analyze.TsanAnalyzer()
- ret = analyzer.Report(filenames, None, check_sanity)
- if ret != 0:
- logging.info(self.INFO_MESSAGE)
- return ret
-
-
class DrMemory(BaseTool):
"""Dr.Memory
Dynamic memory error detector for Windows.
@@ -963,7 +743,6 @@ class DrMemory(BaseTool):
proc += ["--"]
if self._options.indirect or self._options.indirect_webkit_layout:
- # TODO(timurrrr): reuse for TSan on Windows
wrapper_path = os.path.join(self._source_dir,
"tools", "valgrind", "browser_wrapper_win.py")
wrapper = " ".join(["python", wrapper_path] + proc)
@@ -1034,146 +813,10 @@ class DrMemory(BaseTool):
return ret
-# RaceVerifier support. See
-# http://code.google.com/p/data-race-test/wiki/RaceVerifier for more details.
-class ThreadSanitizerRV1Analyzer(tsan_analyze.TsanAnalyzer):
- """ TsanAnalyzer that saves race reports to a file. """
-
- TMP_FILE = "rvlog.tmp"
-
- def __init__(self, source_dir, use_gdb):
- super(ThreadSanitizerRV1Analyzer, self).__init__(use_gdb)
- self.out = open(self.TMP_FILE, "w")
-
- def Report(self, files, testcase, check_sanity=False):
- reports = self.GetReports(files)
- for report in reports:
- print >>self.out, report
- if len(reports) > 0:
- logging.info("RaceVerifier pass 1 of 2, found %i reports" % len(reports))
- return -1
- return 0
-
- def CloseOutputFile(self):
- self.out.close()
-
-
-class ThreadSanitizerRV1Mixin(object):
- """RaceVerifier first pass.
-
- Runs ThreadSanitizer as usual, but hides race reports and collects them in a
- temporary file"""
-
- def __init__(self):
- super(ThreadSanitizerRV1Mixin, self).__init__()
- self.RegisterOptionParserHook(ThreadSanitizerRV1Mixin.ExtendOptionParser)
-
- def ExtendOptionParser(self, parser):
- parser.set_defaults(hybrid="yes")
-
- def CreateAnalyzer(self):
- use_gdb = common.IsMac()
- self.analyzer = ThreadSanitizerRV1Analyzer(self._source_dir, use_gdb)
- return self.analyzer
-
- def Cleanup(self):
- super(ThreadSanitizerRV1Mixin, self).Cleanup()
- self.analyzer.CloseOutputFile()
-
-
-class ThreadSanitizerRV2Mixin(object):
- """RaceVerifier second pass."""
-
- def __init__(self):
- super(ThreadSanitizerRV2Mixin, self).__init__()
- self.RegisterOptionParserHook(ThreadSanitizerRV2Mixin.ExtendOptionParser)
-
- def ExtendOptionParser(self, parser):
- parser.add_option("", "--race-verifier-sleep-ms",
- dest="race_verifier_sleep_ms", default=10,
- help="duration of RaceVerifier delays")
-
- def ToolSpecificFlags(self):
- proc = super(ThreadSanitizerRV2Mixin, self).ToolSpecificFlags()
- proc += ['--race-verifier=%s' % ThreadSanitizerRV1Analyzer.TMP_FILE,
- '--race-verifier-sleep-ms=%d' %
- int(self._options.race_verifier_sleep_ms)]
- return proc
-
- def Cleanup(self):
- super(ThreadSanitizerRV2Mixin, self).Cleanup()
- os.unlink(ThreadSanitizerRV1Analyzer.TMP_FILE)
-
-
-class ThreadSanitizerRV1Posix(ThreadSanitizerRV1Mixin, ThreadSanitizerPosix):
- pass
-
-
-class ThreadSanitizerRV2Posix(ThreadSanitizerRV2Mixin, ThreadSanitizerPosix):
- pass
-
-
-class ThreadSanitizerRV1Windows(ThreadSanitizerRV1Mixin,
- ThreadSanitizerWindows):
- pass
-
-
-class ThreadSanitizerRV2Windows(ThreadSanitizerRV2Mixin,
- ThreadSanitizerWindows):
- pass
-
-
-class RaceVerifier(object):
- """Runs tests under RaceVerifier/Valgrind."""
-
- MORE_INFO_URL = "http://code.google.com/p/data-race-test/wiki/RaceVerifier"
-
- def RV1Factory(self):
- if common.IsWindows():
- return ThreadSanitizerRV1Windows()
- else:
- return ThreadSanitizerRV1Posix()
-
- def RV2Factory(self):
- if common.IsWindows():
- return ThreadSanitizerRV2Windows()
- else:
- return ThreadSanitizerRV2Posix()
-
- def ToolName(self):
- return "tsan"
-
- def Main(self, args, check_sanity, min_runtime_in_seconds):
- logging.info("Running a TSan + RaceVerifier test. For more information, " +
- "see " + self.MORE_INFO_URL)
- cmd1 = self.RV1Factory()
- ret = cmd1.Main(args, check_sanity, min_runtime_in_seconds)
- # Verify race reports, if there are any.
- if ret == -1:
- logging.info("Starting pass 2 of 2. Running the same binary in " +
- "RaceVerifier mode to confirm possible race reports.")
- logging.info("For more information, see " + self.MORE_INFO_URL)
- cmd2 = self.RV2Factory()
- ret = cmd2.Main(args, check_sanity, min_runtime_in_seconds)
- else:
- logging.info("No reports, skipping RaceVerifier second pass")
- logging.info("Please see " + self.MORE_INFO_URL + " for more information " +
- "on RaceVerifier")
- return ret
-
- def Run(self, args, module, min_runtime_in_seconds=0):
- return self.Main(args, False, min_runtime_in_seconds)
-
-
class ToolFactory:
def Create(self, tool_name):
if tool_name == "memcheck":
return Memcheck()
- if tool_name == "tsan":
- if common.IsWindows():
- return ThreadSanitizerWindows()
- else:
- return ThreadSanitizerPosix()
if tool_name == "drmemory" or tool_name == "drmemory_light":
# TODO(timurrrr): remove support for "drmemory" when buildbots are
# switched to drmemory_light OR make drmemory==drmemory_full the default
@@ -1183,8 +826,6 @@ class ToolFactory:
return DrMemory(True, False)
if tool_name == "drmemory_pattern":
return DrMemory(False, True)
- if tool_name == "tsan_rv":
- return RaceVerifier()
try:
platform_name = common.PlatformNames()[0]
except common.NotImplementedError:
« 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