Chromium Code Reviews| 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) |
| - |
| - |