Index: third_party/android_platform/development/scripts/stack_core.py |
diff --git a/third_party/android_platform/development/scripts/stack_core.py b/third_party/android_platform/development/scripts/stack_core.py |
index 3430978703f8f230121c0865aa1e12bbc87f8de8..c0ad96505a45278d6f3fad8e905a2816fdbafb59 100755 |
--- a/third_party/android_platform/development/scripts/stack_core.py |
+++ b/third_party/android_platform/development/scripts/stack_core.py |
@@ -94,7 +94,8 @@ def PrintTraceLines(trace_lines): |
print ' RELADDR ' + 'FUNCTION'.ljust(maxlen) + ' FILE:LINE' |
for tl in trace_lines: |
(addr, symbol_with_offset, location) = tl |
- print ' %8s %s %s' % (addr, symbol_with_offset.ljust(maxlen), location) |
+ normalized = os.path.normpath(location) |
+ print ' %8s %s %s' % (addr, symbol_with_offset.ljust(maxlen), normalized) |
return |
@@ -126,13 +127,13 @@ def PrintDivider(): |
print '-----------------------------------------------------\n' |
-def ConvertTrace(lines, more_info): |
+def ConvertTrace(lines, load_vaddrs, more_info): |
"""Convert strings containing native crash to a stack.""" |
start = time.time() |
chunks = [lines[i: i+_CHUNK_SIZE] for i in xrange(0, len(lines), _CHUNK_SIZE)] |
pool = multiprocessing.Pool(processes=_DEFAULT_JOBS) |
- useful_log = itertools.chain(*pool.map(PreProcessLog, chunks)) |
+ useful_log = itertools.chain(*pool.map(PreProcessLog(load_vaddrs), chunks)) |
pool.close() |
pool.join() |
end = time.time() |
@@ -143,37 +144,73 @@ def ConvertTrace(lines, more_info): |
logging.debug('Finished resolving symbols. Elapsed time: %.4fs', |
(end - start)) |
- |
-def PreProcessLog(lines): |
- """Preprocess the strings, only keep the useful ones. |
+def _AdjustAddress(address, lib, load_vaddrs): |
rmcilroy
2015/10/23 16:25:10
nit - make this a private function in the PreProce
simonb (inactive)
2015/10/26 12:38:31
Done.
|
+ """Add the vaddr of the library's first LOAD segment to address. |
Args: |
- lines: a list of byte strings read from logcat |
+ address: symbol address as a hexadecimal string |
+ lib: path to loaded library |
+ load_vaddrs: LOAD segment min_vaddrs keyed on mapped executable |
Returns: |
- A list of unicode strings related to native crash |
+ address+load_vaddrs[key] if lib ends with /key, otherwise address |
""" |
- useful_log = [] |
- for ln in lines: |
- line = unicode(ln, errors='ignore') |
- if (_PROCESS_INFO_LINE.search(line) |
- or _SIGNAL_LINE.search(line) |
- or _REGISTER_LINE.search(line) |
- or _THREAD_LINE.search(line) |
- or _DALVIK_JNI_THREAD_LINE.search(line) |
- or _DALVIK_NATIVE_THREAD_LINE.search(line) |
- or _LOG_FATAL_LINE.search(line) |
- or _TRACE_LINE.match(line) |
- or _DEBUG_TRACE_LINE.match(line)): |
- useful_log.append(line) |
- continue |
- if code_line.match(line): |
- # Code lines should be ignored. If this were excluded the 'code around' |
- # sections would trigger value_line matches. |
- continue |
- if _VALUE_LINE.match(line): |
- useful_log.append(line) |
- return useful_log |
+ for key, offset in load_vaddrs.iteritems(): |
+ if lib.endswith('/' + key): |
+ # Add offset to address, and return the result as a hexadecimal string |
+ # with the same number of digits as the original. This allows the caller |
+ # to make a direct textual substitution. |
+ return ('%%0%dx' % len(address)) % (int(address, 16) + offset) |
+ return address |
+ |
+class PreProcessLog: |
+ """Closure wrapper, for multiprocessing.Pool.map.""" |
+ def __init__(self, load_vaddrs): |
+ """Bind load_vaddrs to the PreProcessLog closure. |
+ Args: |
+ load_vaddrs: LOAD segment min_vaddrs keyed on mapped executable |
+ """ |
+ self._load_vaddrs = load_vaddrs; |
+ |
+ def __call__(self, lines): |
+ """Preprocess the strings, only keep the useful ones. |
+ Args: |
+ lines: a list of byte strings read from logcat |
+ |
+ Returns: |
+ A list of unicode strings related to native crash |
+ """ |
+ useful_log = [] |
+ for ln in lines: |
+ line = unicode(ln, errors='ignore') |
+ if (_PROCESS_INFO_LINE.search(line) |
+ or _SIGNAL_LINE.search(line) |
+ or _REGISTER_LINE.search(line) |
+ or _THREAD_LINE.search(line) |
+ or _DALVIK_JNI_THREAD_LINE.search(line) |
+ or _DALVIK_NATIVE_THREAD_LINE.search(line) |
+ or _LOG_FATAL_LINE.search(line) |
+ or _DEBUG_TRACE_LINE.match(line)): |
+ useful_log.append(line) |
+ continue |
+ |
+ match = _TRACE_LINE.match(line) |
+ if match: |
+ # For trace lines specifically, the address may need to be adjusted |
+ # to account for relocation packing. This is because debuggerd on |
+ # pre-M platforms does not understand non-zero vaddr LOAD segments. |
+ address, lib = match.group('address', 'lib') |
+ adjusted_address = _AdjustAddress(address, lib, self._load_vaddrs) |
+ useful_log.append(line.replace(address, adjusted_address, 1)) |
+ continue |
+ |
+ if code_line.match(line): |
+ # Code lines should be ignored. If this were excluded the 'code around' |
+ # sections would trigger value_line matches. |
+ continue |
+ if _VALUE_LINE.match(line): |
rmcilroy
2015/10/23 16:25:10
nit - I know it was this way before you made your
simonb (inactive)
2015/10/26 12:38:31
According to commentary above, we need to do the c
rmcilroy
2015/10/26 16:42:17
Acknowledged.
|
+ useful_log.append(line) |
+ return useful_log |
def ResolveCrashSymbol(lines, more_info): |
"""Convert unicode strings which contains native crash to a stack |
@@ -304,5 +341,3 @@ def ResolveCrashSymbol(lines, more_info): |
source_location)) |
PrintOutput(trace_lines, value_lines, more_info) |
- |
- |