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

Unified Diff: third_party/android_platform/development/scripts/symbol.py

Issue 18715002: Android: apply some optimizations to the stack symbolization tools. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 | « third_party/android_platform/development/scripts/stack_core.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/android_platform/development/scripts/symbol.py
diff --git a/third_party/android_platform/development/scripts/symbol.py b/third_party/android_platform/development/scripts/symbol.py
index 0f58df64cd04e15e08583f044a3c589dc8dbcf2b..0f1cf647a485822bfcc9e3df807cafaad6ad8579 100755
--- a/third_party/android_platform/development/scripts/symbol.py
+++ b/third_party/android_platform/development/scripts/symbol.py
@@ -23,23 +23,11 @@ import os
import re
import subprocess
-ANDROID_BUILD_TOP = os.environ["ANDROID_BUILD_TOP"]
-if not ANDROID_BUILD_TOP:
- ANDROID_BUILD_TOP = "."
-
-def FindSymbolsDir():
- saveddir = os.getcwd()
- os.chdir(ANDROID_BUILD_TOP)
- try:
- cmd = ("CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core "
- "SRC_TARGET_DIR=build/target make -f build/core/config.mk "
- "dumpvar-abs-TARGET_OUT_UNSTRIPPED")
- stream = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout
- return os.path.join(ANDROID_BUILD_TOP, stream.read().strip())
- finally:
- os.chdir(saveddir)
-
-SYMBOLS_DIR = FindSymbolsDir()
+CHROME_SRC = os.path.join(os.path.realpath(os.path.dirname(__file__)),
+ os.pardir, os.pardir, os.pardir, os.pardir)
+ANDROID_BUILD_TOP = CHROME_SRC
+SYMBOLS_DIR = CHROME_SRC
+CHROME_SYMBOLS_DIR = CHROME_SRC
ARCH = "arm"
@@ -59,11 +47,22 @@ def Uname():
def ToolPath(tool, toolchain_info=None):
"""Return a full qualified path to the specified tool"""
- if not toolchain_info:
- toolchain_info = FindToolchain()
- (label, platform, target) = toolchain_info
- return os.path.join(ANDROID_BUILD_TOP, "prebuilts/gcc", Uname(), platform, label, "bin",
- target + "-" + tool)
+ # ToolPath looks for the tools in the completely incorrect directory.
+ # This looks in the checked in android_tools.
+ if ARCH == "arm":
+ toolchain_source = "arm-linux-androideabi-4.6"
+ toolchain_prefix = "arm-linux-androideabi"
+ else:
+ toolchain_source = "x86-4.6"
+ toolchain_prefix = "i686-android-linux"
+
+ toolchain_subdir = (
+ "third_party/android_tools/ndk/toolchains/%s/prebuilt/linux-x86_64/bin" %
+ toolchain_source)
+
+ return os.path.join(CHROME_SRC,
+ toolchain_subdir,
+ toolchain_prefix + "-" + tool)
def FindToolchain():
"""Look for the latest available toolchain
@@ -80,9 +79,8 @@ def FindToolchain():
## Known toolchains, newer ones in the front.
if ARCH == "arm":
- gcc_version = os.environ["TARGET_GCC_VERSION"]
known_toolchains = [
- ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi"),
+ ("arm-linux-androideabi-4.6", "arm", "arm-linux-androideabi"),
]
elif ARCH =="x86":
known_toolchains = [
@@ -100,7 +98,35 @@ def FindToolchain():
raise Exception("Could not find tool chain")
-def SymbolInformation(lib, addr):
+def TranslateLibPath(lib):
+ # SymbolInformation(lib, addr) receives lib as the path from symbols
+ # root to the symbols file. This needs to be translated to point to the
+ # correct .so path. If the user doesn't explicitly specify which directory to
+ # use, then use the most recently updated one in one of the known directories.
+ # If the .so is not found somewhere in CHROME_SYMBOLS_DIR, leave it
+ # untranslated in case it is an Android symbol in SYMBOLS_DIR.
+ library_name = os.path.basename(lib)
+ candidate_dirs = ['.',
+ 'out/Debug/lib',
+ 'out/Debug/lib.target',
+ 'out/Release/lib',
+ 'out/Release/lib.target',
+ ]
+
+ candidate_libraries = map(
+ lambda d: ('%s/%s/%s' % (CHROME_SYMBOLS_DIR, d, library_name)),
+ candidate_dirs)
+ candidate_libraries = filter(os.path.exists, candidate_libraries)
+ candidate_libraries = sorted(candidate_libraries,
+ key=os.path.getmtime, reverse=True)
+
+ if not candidate_libraries:
+ return lib
+
+ library_path = os.path.relpath(candidate_libraries[0], SYMBOLS_DIR)
+ return '/' + library_path
+
+def SymbolInformation(lib, addr, get_detailed_info):
"""Look up symbol information about an address.
Args:
@@ -119,11 +145,12 @@ def SymbolInformation(lib, addr):
Usually you want to display the source_location and
object_symbol_with_offset from the last element in the list.
"""
- info = SymbolInformationForSet(lib, set([addr]))
+ lib = TranslateLibPath(lib)
+ info = SymbolInformationForSet(lib, set([addr]), get_detailed_info)
return (info and info.get(addr)) or [(None, None, None)]
-def SymbolInformationForSet(lib, unique_addrs):
+def SymbolInformationForSet(lib, unique_addrs, get_detailed_info):
"""Look up symbol information for a set of addresses from the given library.
Args:
@@ -150,9 +177,12 @@ def SymbolInformationForSet(lib, unique_addrs):
if not addr_to_line:
return None
- addr_to_objdump = CallObjdumpForSet(lib, unique_addrs)
- if not addr_to_objdump:
- return None
+ if get_detailed_info:
+ addr_to_objdump = CallObjdumpForSet(lib, unique_addrs)
+ if not addr_to_objdump:
+ return None
+ else:
+ addr_to_objdump = dict((addr, ("", 0)) for addr in unique_addrs)
result = {}
for addr in unique_addrs:
@@ -171,6 +201,25 @@ def SymbolInformationForSet(lib, unique_addrs):
return result
+class MemoizedForSet(object):
+ def __init__(self, fn):
+ self.fn = fn
+ self.cache = {}
+
+ def __call__(self, lib, unique_addrs):
+ lib_cache = self.cache.setdefault(lib, {})
+
+ no_cache = filter(lambda x: x not in lib_cache, unique_addrs)
+ if no_cache:
+ lib_cache.update((k, None) for k in no_cache)
+ result = self.fn(lib, no_cache)
+ if result:
+ lib_cache.update(result)
+
+ return dict((k, lib_cache[k]) for k in unique_addrs if lib_cache[k])
+
+
+@MemoizedForSet
def CallAddr2LineForSet(lib, unique_addrs):
"""Look up line and symbol information for a set of addresses.
@@ -244,6 +293,7 @@ def StripPC(addr):
return addr & ~1
return addr
+@MemoizedForSet
def CallObjdumpForSet(lib, unique_addrs):
"""Use objdump to find out the names of the containing functions.
@@ -265,16 +315,7 @@ def CallObjdumpForSet(lib, unique_addrs):
if not os.path.exists(symbols):
return None
- addrs = sorted(unique_addrs)
- start_addr_dec = str(StripPC(int(addrs[0], 16)))
- stop_addr_dec = str(StripPC(int(addrs[-1], 16)) + 8)
- cmd = [ToolPath("objdump"),
- "--section=.text",
- "--demangle",
- "--disassemble",
- "--start-address=" + start_addr_dec,
- "--stop-address=" + stop_addr_dec,
- symbols]
+ result = {}
# Function lines look like:
# 000177b0 <android::IBinder::~IBinder()+0x2c>:
@@ -284,46 +325,51 @@ def CallObjdumpForSet(lib, unique_addrs):
offset_regexp = re.compile("(.*)\+0x([a-f0-9]*)")
# A disassembly line looks like:
- # 177b2: b510 push {r4, lr}
+ # 177b2: b510 push {r4, lr}
asm_regexp = re.compile("(^[ a-f0-9]*):[ a-f0-0]*.*$")
- current_symbol = None # The current function symbol in the disassembly.
- current_symbol_addr = 0 # The address of the current function.
- addr_index = 0 # The address that we are currently looking for.
-
- stream = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
- result = {}
- for line in stream:
- # Is it a function line like:
- # 000177b0 <android::IBinder::~IBinder()>:
- components = func_regexp.match(line)
- if components:
- # This is a new function, so record the current function and its address.
- current_symbol_addr = int(components.group(1), 16)
- current_symbol = components.group(2)
-
- # Does it have an optional offset like: "foo(..)+0x2c"?
- components = offset_regexp.match(current_symbol)
+ for target_addr in unique_addrs:
+ start_addr_dec = str(StripPC(int(target_addr, 16)))
+ stop_addr_dec = str(StripPC(int(target_addr, 16)) + 8)
+ cmd = [ToolPath("objdump"),
+ "--section=.text",
+ "--demangle",
+ "--disassemble",
+ "--start-address=" + start_addr_dec,
+ "--stop-address=" + stop_addr_dec,
+ symbols]
+
+ current_symbol = None # The current function symbol in the disassembly.
+ current_symbol_addr = 0 # The address of the current function.
+
+ stream = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
+ for line in stream:
+ # Is it a function line like:
+ # 000177b0 <android::IBinder::~IBinder()>:
+ components = func_regexp.match(line)
+ if components:
+ # This is a new function, so record the current function and its address.
+ current_symbol_addr = int(components.group(1), 16)
+ current_symbol = components.group(2)
+
+ # Does it have an optional offset like: "foo(..)+0x2c"?
+ components = offset_regexp.match(current_symbol)
+ if components:
+ current_symbol = components.group(1)
+ offset = components.group(2)
+ if offset:
+ current_symbol_addr -= int(offset, 16)
+
+ # Is it an disassembly line like:
+ # 177b2: b510 push {r4, lr}
+ components = asm_regexp.match(line)
if components:
- current_symbol = components.group(1)
- offset = components.group(2)
- if offset:
- current_symbol_addr -= int(offset, 16)
-
- # Is it an disassembly line like:
- # 177b2: b510 push {r4, lr}
- components = asm_regexp.match(line)
- if components:
- addr = components.group(1)
- target_addr = addrs[addr_index]
- i_addr = int(addr, 16)
- i_target = StripPC(int(target_addr, 16))
- if i_addr == i_target:
- result[target_addr] = (current_symbol, i_target - current_symbol_addr)
- addr_index += 1
- if addr_index >= len(addrs):
- break
- stream.close()
+ addr = components.group(1)
+ i_addr = int(addr, 16)
+ i_target = StripPC(int(target_addr, 16))
+ if i_addr == i_target:
+ result[target_addr] = (current_symbol, i_target - current_symbol_addr)
+ stream.close()
return result
« no previous file with comments | « third_party/android_platform/development/scripts/stack_core.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698