summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Abd-El-Malek <jam@chromium.org>2014-10-15 10:52:31 -0700
committerJohn Abd-El-Malek <jam@chromium.org>2014-10-15 17:53:26 +0000
commit14ae054faefb81d8a1f8de1c3e0f399902d65843 (patch)
tree4c00fe647c131d78b318861df28ac05841c62122
parente10063a6f20a685af1291c510299dc15a1313f03 (diff)
downloadchromium_src-14ae054faefb81d8a1f8de1c3e0f399902d65843.zip
chromium_src-14ae054faefb81d8a1f8de1c3e0f399902d65843.tar.gz
chromium_src-14ae054faefb81d8a1f8de1c3e0f399902d65843.tar.bz2
Fix LSan on swarming.
ASAN_OPTIONS=detect_leaks=1 needs to be passed in. BUG=414808 R=earthdok@chromium.org, maruel@chromium.org Review URL: https://codereview.chromium.org/659543003 Cr-Commit-Position: refs/heads/master@{#299712}
-rw-r--r--base/base.isolate8
-rwxr-xr-xtesting/test_env.py109
2 files changed, 98 insertions, 19 deletions
diff --git a/base/base.isolate b/base/base.isolate
index 9813d6a..762d915 100644
--- a/base/base.isolate
+++ b/base/base.isolate
@@ -28,6 +28,14 @@
'files': [
'../tools/valgrind/asan/',
'../third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer',
+ '../third_party/llvm-build/Release+Asserts/lib/libstdc++.so.6',
+ ],
+ },
+ }],
+ ['lsan==1', {
+ 'variables': {
+ 'files': [
+ '../tools/lsan/suppressions.txt',
],
},
}],
diff --git a/testing/test_env.py b/testing/test_env.py
index 2c39508..0539309 100755
--- a/testing/test_env.py
+++ b/testing/test_env.py
@@ -5,7 +5,6 @@
"""Sets environment variables needed to run a chromium unit test."""
-import collections
import os
import stat
import subprocess
@@ -39,20 +38,31 @@ def should_enable_sandbox(cmd, sandbox_path):
return False
-def enable_sandbox_if_required(cmd, env, verbose=False):
- """Checks enables the sandbox if it is required, otherwise it disables it."""
+def get_sandbox_env(cmd, env, verbose=False):
+ """Checks enables the sandbox if it is required, otherwise it disables it.
+ Returns the environment flags to set."""
+ extra_env = {}
chrome_sandbox_path = env.get(CHROME_SANDBOX_ENV, CHROME_SANDBOX_PATH)
if should_enable_sandbox(cmd, chrome_sandbox_path):
if verbose:
print 'Enabling sandbox. Setting environment variable:'
print ' %s="%s"' % (CHROME_SANDBOX_ENV, chrome_sandbox_path)
- env[CHROME_SANDBOX_ENV] = chrome_sandbox_path
+ extra_env[CHROME_SANDBOX_ENV] = chrome_sandbox_path
else:
if verbose:
print 'Disabling sandbox. Setting environment variable:'
print ' CHROME_DEVEL_SANDBOX=""'
- env['CHROME_DEVEL_SANDBOX'] = ''
+ extra_env['CHROME_DEVEL_SANDBOX'] = ''
+
+ return extra_env
+
+
+def trim_cmd(cmd):
+ """Removes internal flags from cmd since they're just used to communicate from
+ the host machine to this script running on the swarm slaves."""
+ internal_flags = frozenset(['--asan=0', '--asan=1', '--lsan=0', '--lsan=1'])
+ return [i for i in cmd if i not in internal_flags]
def fix_python_path(cmd):
@@ -65,6 +75,63 @@ def fix_python_path(cmd):
return out
+def get_asan_env(cmd, lsan):
+ """Returns the envirnoment flags needed for ASan and LSan."""
+
+ extra_env = {}
+
+ # Instruct GTK to use malloc while running ASan or LSan tests.
+ # TODO(earthdok): enabling G_SLICE gives these leaks, locally and on swarming
+ #0 0x62c01b in __interceptor_malloc (/tmp/run_tha_testXukBDT/out/Release/browser_tests+0x62c01b)
+ #1 0x7fb64ab64a38 in g_malloc /build/buildd/glib2.0-2.32.4/./glib/gmem.c:159
+ #extra_env['G_SLICE'] = 'always-malloc'
+
+ extra_env['NSS_DISABLE_ARENA_FREE_LIST'] = '1'
+ extra_env['NSS_DISABLE_UNLOAD'] = '1'
+
+ # TODO(glider): remove the symbolizer path once
+ # https://code.google.com/p/address-sanitizer/issues/detail?id=134 is fixed.
+ symbolizer_path = os.path.abspath(os.path.join(ROOT_DIR, 'third_party',
+ 'llvm-build', 'Release+Asserts', 'bin', 'llvm-symbolizer'))
+
+ asan_options = []
+ if lsan:
+ asan_options.append('detect_leaks=1')
+ if sys.platform == 'linux2':
+ # Use the debug version of libstdc++ under LSan. If we don't, there will
+ # be a lot of incomplete stack traces in the reports.
+ extra_env['LD_LIBRARY_PATH'] = '/usr/lib/x86_64-linux-gnu/debug:'
+
+ # LSan is not sandbox-compatible, so we can use online symbolization. In
+ # fact, it needs symbolization to be able to apply suppressions.
+ symbolization_options = ['symbolize=1',
+ 'external_symbolizer_path=%s' % symbolizer_path]
+
+ suppressions_file = os.path.join(ROOT_DIR, 'tools', 'lsan',
+ 'suppressions.txt')
+ lsan_options = ['suppressions=%s' % suppressions_file,
+ 'print_suppressions=1']
+ extra_env['LSAN_OPTIONS'] = ' '.join(lsan_options)
+ else:
+ # ASan uses a script for offline symbolization.
+ # Important note: when running ASan with leak detection enabled, we must use
+ # the LSan symbolization options above.
+ symbolization_options = ['symbolize=0']
+
+ asan_options.extend(symbolization_options)
+
+ extra_env['ASAN_OPTIONS'] = ' '.join(asan_options)
+
+ if sys.platform == 'darwin':
+ isolate_output_dir = os.path.abspath(os.path.dirname(cmd[0]))
+ # This is needed because the test binary has @executable_path embedded in it
+ # it that the OS tries to resolve to the cache directory and not the mapped
+ # directory.
+ extra_env['DYLD_LIBRARY_PATH'] = str(isolate_output_dir)
+
+ return extra_env
+
+
def run_executable(cmd, env):
"""Runs an executable with:
- environment variable CR_SOURCE_ROOT set to the root directory.
@@ -72,34 +139,38 @@ def run_executable(cmd, env):
- environment variable CHROME_DEVEL_SANDBOX set if need
- Reuses sys.executable automatically.
"""
- env = collections.defaultdict(str, env)
+ extra_env = {}
# Many tests assume a English interface...
- env['LANG'] = 'en_US.UTF-8'
+ extra_env['LANG'] = 'en_US.UTF-8'
# Used by base/base_paths_linux.cc as an override. Just make sure the default
# logic is used.
env.pop('CR_SOURCE_ROOT', None)
- enable_sandbox_if_required(cmd, env)
+ extra_env.update(get_sandbox_env(cmd, env))
# Copy logic from tools/build/scripts/slave/runtest.py.
asan = '--asan=1' in cmd
lsan = '--lsan=1' in cmd
- if lsan and sys.platform == 'linux2':
- # Use the debug version of libstdc++ under LSan. If we don't, there will
- # be a lot of incomplete stack traces in the reports.
- env['LD_LIBRARY_PATH'] = '/usr/lib/x86_64-linux-gnu/debug:'
- if asan and sys.platform == 'darwin':
- isolate_output_dir = os.path.abspath(os.path.dirname(cmd[0]))
- # This is needed because the test binary has @executable_path embedded in it
- # that the OS tries to resolve to the cache directory and not the mapped
- # directory.
- env['DYLD_LIBRARY_PATH'] = str(isolate_output_dir)
+ if asan:
+ extra_env.update(get_asan_env(cmd, lsan))
+ if lsan:
+ cmd.append('--no-sandbox')
+
+ cmd = trim_cmd(cmd)
# Ensure paths are correctly separated on windows.
cmd[0] = cmd[0].replace('/', os.path.sep)
cmd = fix_python_path(cmd)
+
+ print('Additional test environment:\n%s\n'
+ 'Command: %s\n' % (
+ '\n'.join(' %s=%s' %
+ (k, v) for k, v in sorted(extra_env.iteritems())),
+ ' '.join(cmd)))
+ env.update(extra_env or {})
try:
- if asan:
+ # See above comment regarding offline symbolization.
+ if asan and not lsan:
# Need to pipe to the symbolizer script.
p1 = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE,
stderr=sys.stdout)