summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglider@chromium.org <glider@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-17 12:05:57 +0000
committerglider@chromium.org <glider@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-17 12:05:57 +0000
commitb503fe3b0bc358db7f19a052fd144c4e719fd285 (patch)
tree7309ad7daef9e030bbcab9472279047f5d346864
parenta703bebfba0afde4112c833504e98c94f558e5eb (diff)
downloadchromium_src-b503fe3b0bc358db7f19a052fd144c4e719fd285.zip
chromium_src-b503fe3b0bc358db7f19a052fd144c4e719fd285.tar.gz
chromium_src-b503fe3b0bc358db7f19a052fd144c4e719fd285.tar.bz2
Reuse BaseTool.Execute in EmbeddedTool.
Implement a dummy GccTsan test runner that just invokes the instrumented binary. Make sure there are 2 blank lines between the top-level definitions. Review URL: http://codereview.chromium.org/8275001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105793 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-xtools/valgrind/common.py7
-rwxr-xr-xtools/valgrind/valgrind_test.py105
2 files changed, 80 insertions, 32 deletions
diff --git a/tools/valgrind/common.py b/tools/valgrind/common.py
index 98eecb7..9ff0d5f 100755
--- a/tools/valgrind/common.py
+++ b/tools/valgrind/common.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -146,3 +146,8 @@ def PlatformNames():
if IsWindows():
return ['win32']
raise NotImplementedError('Unknown platform "%s".' % sys.platform)
+
+
+def PutEnvAndLog(env_name, env_value):
+ os.putenv(env_name, env_value)
+ logging.info('export %s=%s', env_name, env_value)
diff --git a/tools/valgrind/valgrind_test.py b/tools/valgrind/valgrind_test.py
index ebafe5d..f56774d 100755
--- a/tools/valgrind/valgrind_test.py
+++ b/tools/valgrind/valgrind_test.py
@@ -39,6 +39,14 @@ class BaseTool(object):
self.temp_dir = tempfile.mkdtemp(prefix="vg_logs_") # Generated every time
self.log_dir = self.temp_dir # overridable by --keep_logs
self.option_parser_hooks = []
+ # TODO(glider): we may not need some of the env vars on some of the
+ # platforms.
+ self._env = {
+ "G_SLICE" : "always-malloc",
+ "NSS_DISABLE_UNLOAD" : "1",
+ "NSS_DISABLE_ARENA_FREE_LIST" : "1",
+ "GTEST_DEATH_TEST_USE_FORK": "1",
+ }
def ToolName(self):
raise NotImplementedError, "This method should be implemented " \
@@ -148,19 +156,9 @@ class BaseTool(object):
""" Execute the app to be tested after successful instrumentation.
Full execution command-line provided by subclassers via proc."""
logging.info("starting execution...")
-
proc = self.ToolCommand()
-
- add_env = {
- "G_SLICE" : "always-malloc",
- "NSS_DISABLE_UNLOAD" : "1",
- "NSS_DISABLE_ARENA_FREE_LIST" : "1",
- "GTEST_DEATH_TEST_USE_FORK" : "1",
- }
- for k,v in add_env.iteritems():
- logging.info("export %s=%s", k, v)
- os.putenv(k, v)
-
+ for var in self._env:
+ common.PutEnvAndLog(var, self._env[var])
return common.RunSubprocess(proc, self._timeout)
def RunTestsAndAnalyze(self, check_sanity):
@@ -452,6 +450,7 @@ class ValgrindTool(BaseTool):
return ret
+
# TODO(timurrrr): Split into a separate file.
class Memcheck(ValgrindTool):
"""Memcheck
@@ -511,6 +510,7 @@ class Memcheck(ValgrindTool):
"using-valgrind for the info on Memcheck/Valgrind")
return ret
+
class PinTool(BaseTool):
"""Abstract class for running PIN tools.
@@ -545,6 +545,7 @@ class PinTool(BaseTool):
proc += self._args
return proc
+
class ThreadSanitizerBase(object):
"""ThreadSanitizer
Dynamic data race detector for Linux, Mac and Windows.
@@ -647,6 +648,7 @@ class ThreadSanitizerBase(object):
return ret
+
class ThreadSanitizerPosix(ThreadSanitizerBase, ValgrindTool):
def ToolSpecificFlags(self):
proc = ThreadSanitizerBase.ToolSpecificFlags(self)
@@ -666,6 +668,7 @@ class ThreadSanitizerPosix(ThreadSanitizerBase, ValgrindTool):
logging.info(self.INFO_MESSAGE)
return ret
+
class ThreadSanitizerWindows(ThreadSanitizerBase, PinTool):
def __init__(self):
@@ -860,7 +863,6 @@ class DrMemory(BaseTool):
# 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. """
@@ -905,6 +907,7 @@ class ThreadSanitizerRV1Mixin(object):
super(ThreadSanitizerRV1Mixin, self).Cleanup()
self.analyzer.CloseOutputFile()
+
class ThreadSanitizerRV2Mixin(object):
"""RaceVerifier second pass."""
@@ -932,17 +935,21 @@ class ThreadSanitizerRV2Mixin(object):
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."""
@@ -984,32 +991,16 @@ class RaceVerifier(object):
def Run(self, args, module):
return self.Main(args, False)
+
class EmbeddedTool(BaseTool):
"""Abstract class for tools embedded directly into the test binary.
-
- Attributes:
- _env: dictionary of environment variable names and their values.
"""
- def __init__(self):
- super(EmbeddedTool, self).__init__()
- self._env = {}
+ # TODO(glider): need to override Execute() and support process chaining here.
def ToolCommand(self):
# In the simplest case just the args of the script.
return self._args
- def Execute(self):
- for var in self._env:
- self.PutEnvAndLog(var, self._env[var])
- proc = self.ToolCommand()
- logging.info('starting execution...')
- # TODO(glider): need to support process chaining here.
- return common.RunSubprocess(proc, self._timeout)
-
- def PutEnvAndLog(self, env_name, env_value):
- os.putenv(env_name, env_value)
- logging.info('export %s=%s', env_name, env_value)
-
class Asan(EmbeddedTool):
"""AddressSanitizer, a memory error detector.
@@ -1037,6 +1028,56 @@ class Asan(EmbeddedTool):
def Analyze(sels, unused_check_sanity):
return 0
+
+class TsanGcc(EmbeddedTool):
+ """ThreadSanitizer with compile-time instrumentation done using GCC.
+
+ More information at
+ code.google.com/p/data-race-test/wiki/GccInstrumentation
+ """
+ def __init__(self):
+ super(TsanGcc, self).__init__()
+ self.RegisterOptionParserHook(TsanGcc.ExtendOptionParser)
+
+ def ExtendOptionParser(self, parser):
+ parser.add_option("", "--suppressions", default=[],
+ action="append",
+ help="path to TSan suppression file")
+
+ def Setup(self, args):
+ if not super(TsanGcc, self).Setup(args):
+ return False
+ ld_library_paths = []
+ for tail in "lib32", "lib64":
+ ld_library_paths.append(os.path.join(self._source_dir, "third_party",
+ "compiler-tsan", "gcc-4.5.3", tail))
+ # LD_LIBRARY_PATH will be overriden.
+ self._env["LD_LIBRARY_PATH"] = ":".join(ld_library_paths)
+
+ # TODO(glider): this is a temporary solution until Analyze is implemented.
+ env_options = ["--error-exitcode=1"]
+ # TODO(glider): merge this with other TSan suppressions code.
+ suppression_count = 0
+ for suppression_file in self._options.suppressions:
+ if os.path.exists(suppression_file):
+ suppression_count += 1
+ env_options += ["--suppressions=%s" % suppression_file]
+ if not suppression_count:
+ logging.warning("WARNING: NOT USING SUPPRESSIONS!")
+
+ self._env["TSAN_ARGS"] = " ".join(env_options)
+ return True
+
+ def ToolName(self):
+ return "tsan"
+
+ def Analyze(self, unused_check_sanity):
+ # TODO(glider): this should use tsan_analyze.TsanAnalyzer. As a temporary
+ # solution we set the exit code to 1 when a report occurs, because TSan-GCC
+ # does not support the --log-file flag yet.
+ return 0
+
+
class ToolFactory:
def Create(self, tool_name):
if tool_name == "memcheck":
@@ -1055,6 +1096,8 @@ class ToolFactory:
return DrMemory(True)
if tool_name == "tsan_rv":
return RaceVerifier()
+ if tool_name == "tsan_gcc":
+ return TsanGcc()
if tool_name == "asan":
return Asan()
try: