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

Unified Diff: tools/valgrind/asan/asan_symbolize.py

Issue 859293002: Fix report symbolization on swarming bots. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 10 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 | « testing/test_env.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/valgrind/asan/asan_symbolize.py
diff --git a/tools/valgrind/asan/asan_symbolize.py b/tools/valgrind/asan/asan_symbolize.py
index cd61daeb29ae867cf3dbffce876ba0a92b0aa6b6..9280d7a893ecf3bf3f07275a14cca3efe506fa76 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':
Timur Iskhodzhanov 2015/02/11 21:36:16 this asserts on Windows, again.
+ 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)
« no previous file with comments | « testing/test_env.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698