Chromium Code Reviews| Index: build/android/java_deobfuscate.py |
| diff --git a/build/android/java_deobfuscate.py b/build/android/java_deobfuscate.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..150b87c902b078d6d3e0157d3b03e3986fa78261 |
| --- /dev/null |
| +++ b/build/android/java_deobfuscate.py |
| @@ -0,0 +1,95 @@ |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +# A tool to deobfuscate java stack traces |
|
agrieve
2016/07/08 14:40:13
nit: change this to pydoc:
"""A tool to deobfusca
smaier
2016/07/08 16:00:31
Done.
|
| + |
| +# Can just run: |
| +# java -jar third_party/proguard/lib/retrace.jar -regex \ |
| +# "(?:.*?\bat\s+%c\.%m\s*\(%s(?::%l)?\)\s*)|(?:(?:.*?[:\"]\s+)?%c(?::.*)?)" \ |
| +# ~/mapping |
| +# in terminal to achieve same effect as this tool. |
| + |
| +import argparse |
| +import fcntl |
| +import os |
| +import select |
| +import subprocess |
| +import time |
| + |
| +# This regex is taken from |
| +# http://proguard.sourceforge.net/manual/retrace/usage.html. |
| +LINE_PARSE_REGEX = ( |
|
agrieve
2016/07/08 14:40:13
nit: prefix with _
smaier
2016/07/08 16:00:30
Done.
|
| + r'(?:.*?\bat\s+%c\.%m\s*\(%s(?::%l)?\)\s*)|(?:(?:.*?[:"]\s+)?%c(?::.*)?)') |
| + |
|
agrieve
2016/07/08 14:40:14
nit: here and below - 2 blank lines between top-le
smaier
2016/07/08 16:00:31
Done.
|
| +def _IterProcessStdout(process, timeout=None, buffer_size=4096, |
|
agrieve
2016/07/08 14:40:14
Probably it'd be nicer to depend on the version in
smaier
2016/07/08 16:00:30
Done.
|
| + poll_interval=1): |
| + try: |
| + # Enable non-blocking reads from the child's stdout. |
| + child_fd = process.stdout.fileno() |
| + fl = fcntl.fcntl(child_fd, fcntl.F_GETFL) |
| + fcntl.fcntl(child_fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) |
| + |
| + end_time = (time.time() + timeout) if timeout else None |
| + while True: |
| + if end_time and time.time() > end_time: |
| + break |
| + read_fds, _, _ = select.select([child_fd], [], [], poll_interval) |
| + if child_fd in read_fds: |
| + data = os.read(child_fd, buffer_size) |
| + if not data: |
| + break |
| + yield data |
| + if process.poll() is not None: |
| + break |
| + finally: |
| + try: |
| + # Make sure the process doesn't stick around if we fail with an |
| + # exception. |
| + process.kill() |
| + except OSError: |
| + pass |
| + process.wait() |
| + |
| +def _IterCmdOutputLines(args): |
| + process = subprocess.Popen( |
| + args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| + buffer_output = '' |
| + for data in _IterProcessStdout(process): |
| + buffer_output += data |
| + has_incomplete_line = buffer_output[-1] not in '\r\n' |
| + lines = buffer_output.splitlines() |
| + buffer_output = lines.pop() if has_incomplete_line else '' |
| + for line in lines: |
| + yield line |
| + if buffer_output: |
| + yield buffer_output |
| + |
| +def main(): |
| + parser = argparse.ArgumentParser( |
| + description=('Utility wrapper around ReTrace to deobfuscate stack traces ' |
|
agrieve
2016/07/08 14:40:13
move this to file's docstring and use: description
smaier
2016/07/08 16:00:30
Done.
|
| + 'that have been mangled by ProGuard. Takes stack traces ' |
| + 'from stdin (eg. adb logcat | ' |
| + 'java_deobfuscate.py proguard.mapping) and files.')) |
| + parser.add_argument( |
| + 'mapping_file', |
| + help='ProGuard mapping file from build which the stacktrace is from.') |
| + parser.add_argument( |
| + '--stacktrace', |
| + help='Stacktrace file to be deobfuscated.') |
| + args = parser.parse_args() |
| + |
| + retrace_path = os.path.abspath(os.path.join( |
| + os.path.abspath(__file__), os.pardir, os.pardir, os.pardir, 'third_party', |
| + 'proguard', 'lib', 'retrace.jar')) |
| + |
| + base_args = ['java', '-jar', retrace_path, '-regex', LINE_PARSE_REGEX, |
| + args.mapping_file] |
| + if args.stacktrace is not None: |
|
agrieve
2016/07/08 14:40:13
nit: drop the "is not None" part
smaier
2016/07/08 16:00:31
Done.
|
| + subprocess.call(base_args + [args.stacktrace]) |
| + else: |
| + for line in _IterCmdOutputLines(base_args): |
| + print line |
| + |
| +if __name__ == '__main__': |
| + main() |