summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base_unittests.isolate7
-rw-r--r--chrome/browser_tests.isolate7
-rw-r--r--chrome/chrome.isolate11
-rw-r--r--chrome/interactive_ui_tests.isolate7
-rw-r--r--chrome/unit_tests.isolate7
-rw-r--r--content/content_browsertests.isolate12
-rw-r--r--content/content_unittests.isolate7
-rw-r--r--net/net_unittests.isolate7
-rwxr-xr-xtesting/test_env.py12
-rwxr-xr-xtools/valgrind/asan/asan_symbolize.py84
10 files changed, 154 insertions, 7 deletions
diff --git a/base/base_unittests.isolate b/base/base_unittests.isolate
index fca76d5..0822b24 100644
--- a/base/base_unittests.isolate
+++ b/base/base_unittests.isolate
@@ -58,6 +58,13 @@
],
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/base_unittests.dSYM/',
+ ],
+ },
+ }],
['OS=="win" and (fastbuild==0 or fastbuild==1)', {
'variables': {
'files': [
diff --git a/chrome/browser_tests.isolate b/chrome/browser_tests.isolate
index 912fbca..2624378c 100644
--- a/chrome/browser_tests.isolate
+++ b/chrome/browser_tests.isolate
@@ -208,6 +208,13 @@
],
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/browser_tests.dSYM/',
+ ],
+ },
+ }],
['OS=="win" and libpeer_target_type=="loadable_module"', {
'variables': {
'files': [
diff --git a/chrome/chrome.isolate b/chrome/chrome.isolate
index 64ae230..061cc23 100644
--- a/chrome/chrome.isolate
+++ b/chrome/chrome.isolate
@@ -77,6 +77,17 @@
],
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/<(mac_product_name) Framework.framework.dSYM/',
+ '<(PRODUCT_DIR)/<(mac_product_name) Helper.app.dSYM/',
+ '<(PRODUCT_DIR)/<(mac_product_name).app.dSYM/',
+ '<(PRODUCT_DIR)/exif.so.dSYM/',
+ '<(PRODUCT_DIR)/ffmpegsumo.so.dSYM/',
+ ],
+ },
+ }],
['OS=="win"', {
'variables': {
'files': [
diff --git a/chrome/interactive_ui_tests.isolate b/chrome/interactive_ui_tests.isolate
index d968a7d..1d78389 100644
--- a/chrome/interactive_ui_tests.isolate
+++ b/chrome/interactive_ui_tests.isolate
@@ -70,6 +70,13 @@
],
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/interactive_ui_tests.dSYM/',
+ ],
+ },
+ }],
['OS=="mac" or OS=="win"', {
'variables': {
'command': [
diff --git a/chrome/unit_tests.isolate b/chrome/unit_tests.isolate
index a03f8a5..3c12a33 100644
--- a/chrome/unit_tests.isolate
+++ b/chrome/unit_tests.isolate
@@ -80,6 +80,13 @@
],
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/unit_tests.dSYM/',
+ ],
+ },
+ }],
['OS=="linux" or OS=="mac"', {
'variables': {
'read_only': 1,
diff --git a/content/content_browsertests.isolate b/content/content_browsertests.isolate
index 9701675..9de603a 100644
--- a/content/content_browsertests.isolate
+++ b/content/content_browsertests.isolate
@@ -86,6 +86,18 @@
],
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/content_browsertests.dSYM/',
+ '<(PRODUCT_DIR)/Content Shell.app.dSYM/',
+ '<(PRODUCT_DIR)/ffmpegsumo.so.dSYM/',
+ '<(PRODUCT_DIR)/npapi_test_plugin.plugin.dSYM/',
+ '<(PRODUCT_DIR)/test_netscape_plugin.plugin.dSYM/',
+ '<(PRODUCT_DIR)/ppapi_tests.plugin.dSYM/',
+ ],
+ },
+ }],
['OS=="mac" or OS=="win"', {
'variables': {
'command': [
diff --git a/content/content_unittests.isolate b/content/content_unittests.isolate
index b72dcee..ba15585 100644
--- a/content/content_unittests.isolate
+++ b/content/content_unittests.isolate
@@ -97,6 +97,13 @@
],
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/content_unittests.dSYM/',
+ ],
+ },
+ }],
['OS=="win" and (fastbuild==0 or fastbuild==1)', {
'variables': {
'files': [
diff --git a/net/net_unittests.isolate b/net/net_unittests.isolate
index ec515fb..877c21e 100644
--- a/net/net_unittests.isolate
+++ b/net/net_unittests.isolate
@@ -34,6 +34,13 @@
'read_only': 1,
},
}],
+ ['OS=="mac" and asan==1', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/net_unittests.dSYM/',
+ ],
+ },
+ }],
['OS=="win" and (fastbuild==0 or fastbuild==1)', {
'variables': {
'files': [
diff --git a/testing/test_env.py b/testing/test_env.py
index 597ca2a..66a3721 100755
--- a/testing/test_env.py
+++ b/testing/test_env.py
@@ -124,12 +124,14 @@ def get_sanitizer_env(cmd, asan, lsan, msan, tsan):
return extra_env
-def get_sanitizer_symbolize_command(json_path=None):
+def get_sanitizer_symbolize_command(json_path=None, executable_path=None):
"""Construct the command to invoke offline symbolization script."""
script_path = '../tools/valgrind/asan/asan_symbolize.py'
cmd = [sys.executable, script_path]
if json_path is not None:
cmd.append('--test-summary-json-file=%s' % json_path)
+ if executable_path is not None:
+ cmd.append('--executable-path=%s' % executable_path)
return cmd
@@ -149,7 +151,8 @@ def symbolize_snippets_in_json(cmd, env):
return
try:
- symbolize_command = get_sanitizer_symbolize_command(json_path=json_path)
+ symbolize_command = get_sanitizer_symbolize_command(
+ json_path=json_path, executable_path=cmd[0])
p = subprocess.Popen(symbolize_command, stderr=subprocess.PIPE, env=env)
(_, stderr) = p.communicate()
except OSError as e:
@@ -207,8 +210,9 @@ def run_executable(cmd, env):
# Need to pipe to the symbolizer script.
p1 = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE,
stderr=sys.stdout)
- p2 = subprocess.Popen(get_sanitizer_symbolize_command(),
- env=env, stdin=p1.stdout)
+ p2 = subprocess.Popen(
+ get_sanitizer_symbolize_command(executable_path=cmd[0]),
+ env=env, stdin=p1.stdout)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
p1.wait()
p2.wait()
diff --git a/tools/valgrind/asan/asan_symbolize.py b/tools/valgrind/asan/asan_symbolize.py
index cd61dae..9280d7a 100755
--- a/tools/valgrind/asan/asan_symbolize.py
+++ b/tools/valgrind/asan/asan_symbolize.py
@@ -10,6 +10,8 @@ import argparse
import base64
import json
import os
+import re
+import subprocess
import sys
class LineBuffered(object):
@@ -48,6 +50,73 @@ def set_symbolizer_path():
os.environ['LLVM_SYMBOLIZER_PATH'] = os.path.abspath(symbolizer_path)
+def is_hash_name(name):
+ match = re.match('[0-9a-f]+$', name)
+ return bool(match)
+
+
+def split_path(path):
+ ret = []
+ while True:
+ head, tail = os.path.split(path)
+ if head == path:
+ return [head] + ret
+ ret, path = [tail] + ret, head
+
+
+def chrome_product_dir_path(exe_path):
+ if exe_path is None:
+ return None
+ path_parts = split_path(exe_path)
+ # Make sure the product dir path isn't empty if |exe_path| consists of
+ # a single component.
+ if len(path_parts) == 1:
+ path_parts = ['.'] + path_parts
+ for index, part in enumerate(path_parts):
+ if part.endswith('.app'):
+ return os.path.join(*path_parts[:index])
+ # If the executable isn't an .app bundle, it's a commandline binary that
+ # resides right in the product dir.
+ return os.path.join(*path_parts[:-1])
+
+
+inode_path_cache = {}
+
+
+def find_inode_at_path(inode, path):
+ if inode in inode_path_cache:
+ return inode_path_cache[inode]
+ cmd = ['find', path, '-inum', str(inode)]
+ find_line = subprocess.check_output(cmd).rstrip()
+ lines = find_line.split('\n')
+ ret = None
+ if lines:
+ # `find` may give us several paths (e.g. 'Chromium Framework' in the
+ # product dir and 'Chromium Framework' inside 'Chromium.app',
+ # chrome_dsym_hints() will produce correct .dSYM path for any of them.
+ ret = lines[0]
+ inode_path_cache[inode] = ret
+ return ret
+
+
+# Create a binary name filter that works around https://crbug.com/444835.
+# When running tests on OSX swarming servers, ASan sometimes prints paths to
+# files in cache (ending with SHA1 filenames) instead of paths to hardlinks to
+# those files in the product dir.
+# For a given |binary_path| chrome_osx_binary_name_filter() returns one of the
+# hardlinks to the same inode in |product_dir_path|.
+def make_chrome_osx_binary_name_filter(product_dir_path=''):
+ def chrome_osx_binary_name_filter(binary_path):
+ basename = os.path.basename(binary_path)
+ if is_hash_name(basename) and product_dir_path:
+ inode = os.stat(binary_path).st_ino
+ new_binary_path = find_inode_at_path(inode, product_dir_path)
+ if new_binary_path:
+ return new_binary_path
+ return binary_path
+ return chrome_osx_binary_name_filter
+
+
# Construct a path to the .dSYM bundle for the given binary.
# There are three possible cases for binary location in Chromium:
# 1. The binary is a standalone executable or dynamic library in the product
@@ -63,7 +132,7 @@ def set_symbolizer_path():
# path. Only one of these bundles may be a framework and frameworks cannot
# contain other bundles.
def chrome_dsym_hints(binary):
- path_parts = binary.split(os.path.sep)
+ path_parts = split_path(binary)
app_positions = []
framework_positions = []
for index, part in enumerate(path_parts):
@@ -89,7 +158,7 @@ def chrome_dsym_hints(binary):
# In case 2 this is the same as |outermost_bundle|.
innermost_bundle = bundle_positions[-1]
dsym_path = product_dir + [path_parts[innermost_bundle]]
- result = '%s.dSYM' % os.path.sep.join(dsym_path)
+ result = '%s.dSYM' % os.path.join(*dsym_path)
return [result]
@@ -169,13 +238,22 @@ def main():
parser.add_argument('strip_path_prefix', nargs='*',
help='When printing source file names, the longest prefix ending in one '
'of these substrings will be stripped. E.g.: "Release/../../".')
+ parser.add_argument('--executable-path',
+ help='Path to program executable. Used on OSX swarming bots to locate '
+ 'dSYM bundles for associated frameworks and bundles.')
args = parser.parse_args()
disable_buffering()
set_symbolizer_path()
asan_symbolize.demangle = True
asan_symbolize.fix_filename_patterns = args.strip_path_prefix
- loop = asan_symbolize.SymbolizationLoop(dsym_hint_producer=chrome_dsym_hints)
+ binary_name_filter = None
+ if os.uname()[0] == 'Darwin':
+ binary_name_filter = make_chrome_osx_binary_name_filter(
+ chrome_product_dir_path(args.executable_path))
+ loop = asan_symbolize.SymbolizationLoop(
+ binary_name_filter=binary_name_filter,
+ dsym_hint_producer=chrome_dsym_hints)
if args.test_summary_json_file:
symbolize_snippets_in_json(args.test_summary_json_file, loop)