def run_redex_binary(state): if state.args.redex_binary is None: try: state.args.redex_binary = subprocess.check_output( ['which', 'redex-all']).rstrip().decode('ascii') except subprocess.CalledProcessError: pass if state.args.redex_binary is None: # __file__ can be /path/fb-redex.pex/redex.pyc dir_name = dirname(abspath(__file__)) while not isdir(dir_name): dir_name = dirname(dir_name) state.args.redex_binary = join(dir_name, 'redex-all') if not isfile(state.args.redex_binary) or not os.access( state.args.redex_binary, os.X_OK): sys.exit('redex-all is not found or is not executable: ' + state.args.redex_binary) log('Running redex binary at ' + state.args.redex_binary) args = [state.args.redex_binary] + [ '--apkdir', state.extracted_apk_dir, '--outdir', state.dex_dir ] if state.args.config: args += ['--config', state.args.config] if state.args.verify_none_mode or state.config_dict.get( "verify_none_mode"): args += ['--verify-none-mode'] if state.args.is_art_build: args += ['--is-art-build'] if state.args.enable_instrument_pass or state.config_dict.get( "enable_instrument_pass"): args += ['--enable-instrument-pass'] if state.args.warn: args += ['--warn', state.args.warn] args += ['--proguard-config=' + x for x in state.args.proguard_configs] if state.args.proguard_map: args += ['-Sproguard_map=' + state.args.proguard_map] args += ['--jarpath=' + x for x in state.args.jarpaths] if state.args.printseeds: args += ['--printseeds=' + state.args.printseeds] if state.args.used_js_assets: args += ['--used-js-assets=' + x for x in state.args.used_js_assets] if state.args.arch: args += ['--arch=' + state.args.arch] args += ['-S' + x for x in state.args.passthru] args += ['-J' + x for x in state.args.passthru_json] args += state.dexen # Stop before a pass and output intermediate dex and IR meta data. if state.stop_pass_idx != -1: args += [ '--stop-pass', str(state.stop_pass_idx), '--output-ir', state.args.output_ir ] if state.debugger == 'lldb': args = ['lldb', '--'] + args elif state.debugger == 'gdb': args = ['gdb', '--args'] + args start = timer() if state.args.debug: print('cd %s && %s' % (os.getcwd(), ' '.join(map(quote, args)))) sys.exit() env = logger.setup_trace_for_child(os.environ) logger.flush() add_extra_environment_args(env) # Our CI system occasionally fails because it is trying to write the # redex-all binary when this tries to run. This shouldn't happen, and # might be caused by a JVM bug. Anyways, let's retry and hope it stops. for i in range(5): try: subprocess.check_call(args, env=env) except OSError as err: if err.errno == errno.ETXTBSY: if i < 4: time.sleep(5) continue raise err except subprocess.CalledProcessError as err: script_filenames = write_debugger_commands(args) raise RuntimeError( ('redex-all crashed with exit code %s! ' % err.returncode) + ('You can re-run it ' 'under gdb by running %(gdb_script_name)s or under lldb ' 'by running %(lldb_script_name)s') % script_filenames) break log('Dex processing finished in {:.2f} seconds'.format(timer() - start))
def run_redex_binary(state, exception_formatter, output_line_handler): if state.args.redex_binary is None: state.args.redex_binary = shutil.which("redex-all") if state.args.redex_binary is None: # __file__ can be /path/fb-redex.pex/redex.pyc dir_name = dirname(abspath(__file__)) while not isdir(dir_name): dir_name = dirname(dir_name) state.args.redex_binary = join(dir_name, "redex-all") if not isfile(state.args.redex_binary) or not os.access( state.args.redex_binary, os.X_OK): sys.exit("redex-all is not found or is not executable: " + state.args.redex_binary) logging.debug("Running redex binary at %s", state.args.redex_binary) args = [state.args.redex_binary] + [ "--apkdir", state.extracted_apk_dir, "--outdir", state.dex_dir, ] if state.args.cmd_prefix is not None: args = shlex.split(state.args.cmd_prefix) + args if state.args.config: args += ["--config", state.args.config] if state.args.verify_none_mode or state.config_dict.get( "verify_none_mode"): args += ["--verify-none-mode"] if state.args.is_art_build: args += ["--is-art-build"] if state.args.redacted: args += ["--redacted"] if state.args.disable_dex_hasher: args += ["--disable-dex-hasher"] if state.args.enable_instrument_pass or state.config_dict.get( "enable_instrument_pass"): args += ["--enable-instrument-pass"] if state.args.warn: args += ["--warn", state.args.warn] args += ["--proguard-config=" + x for x in state.args.proguard_configs] if state.args.proguard_map: args += ["-Sproguard_map=" + state.args.proguard_map] args += ["--jarpath=" + x for x in state.args.jarpaths] if state.args.printseeds: args += ["--printseeds=" + state.args.printseeds] if state.args.used_js_assets: args += ["--used-js-assets=" + x for x in state.args.used_js_assets] if state.args.arch: args += ["--arch=" + state.args.arch] args += ["-S" + x for x in state.args.passthru] args += ["-J" + x for x in state.args.passthru_json] args += state.dexen # Stop before a pass and output intermediate dex and IR meta data. if state.stop_pass_idx != -1: args += [ "--stop-pass", str(state.stop_pass_idx), "--output-ir", state.args.output_ir, ] prefix = (dbg_prefix(state.debugger, state.args.debug_source_root) if state.debugger is not None else []) start = timer() if state.args.debug: print("cd %s && %s" % (os.getcwd(), " ".join(prefix + list(map(quote, args))))) sys.exit() env = os.environ.copy() if state.args.quiet: # Remove TRACE if it exists. env.pop("TRACE", None) else: # Check whether TRACE is set. If not, use "TIME:1,PM:1". if "TRACE" not in env: env["TRACE"] = "TIME:1,PM:1" env = logger.setup_trace_for_child(env) logger.flush() add_extra_environment_args(env) def run(): sigint_handler = SigIntHandler() sigint_handler.install() try: proc, handler = run_and_stream_stderr(prefix + args, env, (logger.trace_fp.fileno(), )) sigint_handler.set_proc(proc) sigint_handler.set_state(RedexState.STARTED) returncode, err_out = handler(output_line_handler) sigint_handler.set_state(RedexState.POSTPROCESSING) if returncode != 0: # Check for crash traces. maybe_addr2line(err_out) abort_error = None if returncode == -6: # SIGABRT abort_error = find_abort_error(err_out) if abort_error is not None: abort_error = "\n" + abort_error else: abort_error = "" default_error_msg = "redex-all crashed with exit code {}!{}".format( returncode, abort_error) if IS_WINDOWS: raise RuntimeError(default_error_msg) gdb_script_name = write_debugger_command( "gdb", state.args.debug_source_root, args) lldb_script_name = write_debugger_command( "lldb", state.args.debug_source_root, args) msg = exception_formatter.format_message( err_out, default_error_msg, gdb_script_name, lldb_script_name) raise RuntimeError(msg) return True except OSError as err: if err.errno == errno.ETXTBSY: return False raise err finally: sigint_handler.set_state(RedexState.FINISHED) sigint_handler.uninstall() # Our CI system occasionally fails because it is trying to write the # redex-all binary when this tries to run. This shouldn't happen, and # might be caused by a JVM bug. Anyways, let's retry and hope it stops. for _ in range(5): if run(): break logging.debug("Dex processing finished in {:.2f} seconds".format(timer() - start))
def run_redex_binary(state): if state.args.redex_binary is None: state.args.redex_binary = shutil.which("redex-all") if state.args.redex_binary is None: # __file__ can be /path/fb-redex.pex/redex.pyc dir_name = dirname(abspath(__file__)) while not isdir(dir_name): dir_name = dirname(dir_name) state.args.redex_binary = join(dir_name, "redex-all") if not isfile(state.args.redex_binary) or not os.access( state.args.redex_binary, os.X_OK): sys.exit("redex-all is not found or is not executable: " + state.args.redex_binary) log("Running redex binary at " + state.args.redex_binary) args = [state.args.redex_binary] + [ "--apkdir", state.extracted_apk_dir, "--outdir", state.dex_dir, ] if state.args.config: args += ["--config", state.args.config] if state.args.verify_none_mode or state.config_dict.get( "verify_none_mode"): args += ["--verify-none-mode"] if state.args.is_art_build: args += ["--is-art-build"] if state.args.force_class_data_end_of_file: args += ["--force-class-data-end-of-file"] if state.args.disable_dex_hasher: args += ["--disable-dex-hasher"] if state.args.enable_instrument_pass or state.config_dict.get( "enable_instrument_pass"): args += ["--enable-instrument-pass"] if state.args.warn: args += ["--warn", state.args.warn] args += ["--proguard-config=" + x for x in state.args.proguard_configs] if state.args.proguard_map: args += ["-Sproguard_map=" + state.args.proguard_map] args += ["--jarpath=" + x for x in state.args.jarpaths] if state.args.printseeds: args += ["--printseeds=" + state.args.printseeds] if state.args.used_js_assets: args += ["--used-js-assets=" + x for x in state.args.used_js_assets] if state.args.arch: args += ["--arch=" + state.args.arch] args += ["-S" + x for x in state.args.passthru] args += ["-J" + x for x in state.args.passthru_json] args += state.dexen # Stop before a pass and output intermediate dex and IR meta data. if state.stop_pass_idx != -1: args += [ "--stop-pass", str(state.stop_pass_idx), "--output-ir", state.args.output_ir, ] if state.debugger == "lldb": args = ["lldb", "--"] + args elif state.debugger == "gdb": args = ["gdb", "--args"] + args start = timer() if state.args.debug: print("cd %s && %s" % (os.getcwd(), " ".join(map(quote, args)))) sys.exit() env = logger.setup_trace_for_child(os.environ) logger.flush() add_extra_environment_args(env) def run(): sigint_handler = SigIntHandler() sigint_handler.install() try: proc, handler = run_and_stream_stderr(args, env, (logger.trace_fp.fileno(), )) sigint_handler.set_proc(proc) sigint_handler.set_state(RedexState.STARTED) returncode, err_out = handler() sigint_handler.set_state(RedexState.POSTPROCESSING) if returncode != 0: # Check for crash traces. maybe_addr2line(err_out) script_filenames = write_debugger_commands(args) raise RuntimeError( ("redex-all crashed with exit code %s! " % returncode) + ("You can re-run it " "under gdb by running %(gdb_script_name)s or under lldb " "by running %(lldb_script_name)s") % script_filenames) return True except OSError as err: if err.errno == errno.ETXTBSY: return False raise err finally: sigint_handler.set_state(RedexState.FINISHED) sigint_handler.uninstall() # Our CI system occasionally fails because it is trying to write the # redex-all binary when this tries to run. This shouldn't happen, and # might be caused by a JVM bug. Anyways, let's retry and hope it stops. for _ in range(5): if run(): break log("Dex processing finished in {:.2f} seconds".format(timer() - start))
def run_pass( executable_path, script_args, config_path, config_json, apk_dir, dex_dir, dexfiles, debugger, ): if executable_path is None: try: executable_path = subprocess.check_output(['which', 'redex-all'] ).rstrip().decode('ascii') except subprocess.CalledProcessError: pass if executable_path is None: # __file__ can be /path/fb-redex.pex/redex.pyc dir_name = dirname(abspath(__file__)) while not isdir(dir_name): dir_name = dirname(dir_name) executable_path = join(dir_name, 'redex-all') if not isfile(executable_path) or not os.access(executable_path, os.X_OK): sys.exit('redex-all is not found or is not executable: ' + executable_path) log('Running redex binary at ' + executable_path) args = [executable_path] + [ '--apkdir', apk_dir, '--outdir', dex_dir] if config_path: args += ['--config', config_path] if script_args.verify_none_mode or config_json.get("verify_none_mode"): args += ['--verify-none-mode'] if script_args.is_art_build: args += ['--is-art-build'] if script_args.warn: args += ['--warn', script_args.warn] args += ['--proguard-config=' + x for x in script_args.proguard_configs] if script_args.proguard_map: args += ['-Sproguard_map=' + script_args.proguard_map] args += ['--jarpath=' + x for x in script_args.jarpaths] if script_args.printseeds: args += ['--printseeds=' + script_args.printseeds] args += ['-S' + x for x in script_args.passthru] args += ['-J' + x for x in script_args.passthru_json] args += dexfiles if debugger == 'lldb': args = ['lldb', '--'] + args elif debugger == 'gdb': args = ['gdb', '--args'] + args start = timer() if script_args.debug: print(' '.join(map(quote, args))) sys.exit() env = logger.setup_trace_for_child(os.environ) logger.flush() add_extra_environment_args(env) # Our CI system occasionally fails because it is trying to write the # redex-all binary when this tries to run. This shouldn't happen, and # might be caused by a JVM bug. Anyways, let's retry and hope it stops. for i in range(5): try: subprocess.check_call(args, env=env) except OSError as err: if err.errno == errno.ETXTBSY: if i < 4: time.sleep(5) continue raise err except subprocess.CalledProcessError as err: script_filenames = write_debugger_commands(args) raise RuntimeError( ('redex-all crashed with exit code %s! ' % err.returncode) + ('You can re-run it ' 'under gdb by running %(gdb_script_name)s or under lldb ' 'by running %(lldb_script_name)s') % script_filenames) break log('Dex processing finished in {:.2f} seconds'.format(timer() - start))
def run_redex_binary(state): if state.args.redex_binary is None: try: state.args.redex_binary = subprocess.check_output(['which', 'redex-all'] ).rstrip().decode('ascii') except subprocess.CalledProcessError: pass if state.args.redex_binary is None: # __file__ can be /path/fb-redex.pex/redex.pyc dir_name = dirname(abspath(__file__)) while not isdir(dir_name): dir_name = dirname(dir_name) state.args.redex_binary = join(dir_name, 'redex-all') if not isfile(state.args.redex_binary) or not os.access(state.args.redex_binary, os.X_OK): sys.exit('redex-all is not found or is not executable: ' + state.args.redex_binary) log('Running redex binary at ' + state.args.redex_binary) args = [state.args.redex_binary] + [ '--apkdir', state.extracted_apk_dir, '--outdir', state.dex_dir] if state.args.config: args += ['--config', state.args.config] if state.args.verify_none_mode or state.config_dict.get("verify_none_mode"): args += ['--verify-none-mode'] if state.args.is_art_build: args += ['--is-art-build'] if state.args.enable_instrument_pass or state.config_dict.get("enable_instrument_pass"): args += ['--enable-instrument-pass'] if state.args.warn: args += ['--warn', state.args.warn] args += ['--proguard-config=' + x for x in state.args.proguard_configs] if state.args.proguard_map: args += ['-Sproguard_map=' + state.args.proguard_map] args += ['--jarpath=' + x for x in state.args.jarpaths] if state.args.printseeds: args += ['--printseeds=' + state.args.printseeds] if state.args.used_js_assets: args += ['--used-js-assets=' + x for x in state.args.used_js_assets] args += ['-S' + x for x in state.args.passthru] args += ['-J' + x for x in state.args.passthru_json] args += state.dexen # Stop before a pass and output intermediate dex and IR meta data. if state.stop_pass_idx != -1: args += ['--stop-pass', str(state.stop_pass_idx), '--output-ir', state.args.output_ir] if state.debugger == 'lldb': args = ['lldb', '--'] + args elif state.debugger == 'gdb': args = ['gdb', '--args'] + args start = timer() if state.args.debug: print('cd %s && %s' % (os.getcwd(), ' '.join(map(quote, args)))) sys.exit() env = logger.setup_trace_for_child(os.environ) logger.flush() add_extra_environment_args(env) # Our CI system occasionally fails because it is trying to write the # redex-all binary when this tries to run. This shouldn't happen, and # might be caused by a JVM bug. Anyways, let's retry and hope it stops. for i in range(5): try: subprocess.check_call(args, env=env) except OSError as err: if err.errno == errno.ETXTBSY: if i < 4: time.sleep(5) continue raise err except subprocess.CalledProcessError as err: script_filenames = write_debugger_commands(args) raise RuntimeError( ('redex-all crashed with exit code %s! ' % err.returncode) + ('You can re-run it ' 'under gdb by running %(gdb_script_name)s or under lldb ' 'by running %(lldb_script_name)s') % script_filenames) break log('Dex processing finished in {:.2f} seconds'.format(timer() - start))
def run_pass( executable_path, script_args, config_path, config_json, apk_dir, dex_dir, dexfiles, debugger, ): if executable_path is None: try: executable_path = subprocess.check_output(['which', 'redex-all']).rstrip() except subprocess.CalledProcessError: pass if executable_path is None: # __file__ can be /path/fb-redex.pex/redex.pyc dir_name = dirname(abspath(__file__)) while not isdir(dir_name): dir_name = dirname(dir_name) executable_path = join(dir_name, 'redex-all') if not isfile(executable_path) or not os.access(executable_path, os.X_OK): sys.exit('redex-all is not found or is not executable') log('Running redex binary at ' + executable_path) args = [executable_path] + ['--apkdir', apk_dir, '--outdir', dex_dir] if config_path: args += ['--config', config_path] if script_args.warn: args += ['--warn', script_args.warn] args += ['--proguard-config=' + x for x in script_args.proguard_configs] if script_args.keep: args += ['--seeds', script_args.keep] if script_args.proguard_map: args += ['-Sproguard_map=' + script_args.proguard_map] args += ['--jarpath=' + x for x in script_args.jarpaths] if script_args.printseeds: args += ['--printseeds=' + script_args.printseeds] args += ['-S' + x for x in script_args.passthru] args += ['-J' + x for x in script_args.passthru_json] args += dexfiles if debugger == 'lldb': args = ['lldb', '--'] + args elif debugger == 'gdb': args = ['gdb', '--args'] + args start = timer() if script_args.debug: print(' '.join(args)) sys.exit() env = logger.setup_trace_for_child(os.environ) logger.flush() # Our CI system occasionally fails because it is trying to write the # redex-all binary when this tries to run. This shouldn't happen, and # might be caused by a JVM bug. Anyways, let's retry and hope it stops. for i in range(5): try: subprocess.check_call(args, env=env) except OSError as err: if err.errno == errno.ETXTBSY: if i < 4: time.sleep(5) continue raise err except subprocess.CalledProcessError as err: err.cmd = ' '.join(args) raise err break log('Dex processing finished in {:.2f} seconds'.format(timer() - start))
def run_pass( executable_path, script_args, config_path, config_json, apk_dir, dex_dir, dexfiles, debugger, ): if executable_path is None: try: executable_path = subprocess.check_output(['which', 'redex-all'] ).rstrip().decode('ascii') except subprocess.CalledProcessError: pass if executable_path is None: # __file__ can be /path/fb-redex.pex/redex.pyc dir_name = dirname(abspath(__file__)) while not isdir(dir_name): dir_name = dirname(dir_name) executable_path = join(dir_name, 'redex-all') if not isfile(executable_path) or not os.access(executable_path, os.X_OK): sys.exit('redex-all is not found or is not executable: ' + executable_path) log('Running redex binary at ' + executable_path) args = [executable_path] + [ '--apkdir', apk_dir, '--outdir', dex_dir] if config_path: args += ['--config', config_path] if script_args.verify_none_mode or config_json.get("verify_none_mode"): args += ['--verify-none-mode'] if script_args.is_art_build: args += ['--is-art-build'] if script_args.warn: args += ['--warn', script_args.warn] args += ['--proguard-config=' + x for x in script_args.proguard_configs] if script_args.proguard_map: args += ['-Sproguard_map=' + script_args.proguard_map] args += ['--jarpath=' + x for x in script_args.jarpaths] if script_args.printseeds: args += ['--printseeds=' + script_args.printseeds] if script_args.rmethods: args += ['--rmethods=' + script_args.rmethods] if script_args.amethods: args += ['--amethods=' + script_args.amethods] args += ['-S' + x for x in script_args.passthru] args += ['-J' + x for x in script_args.passthru_json] args += dexfiles if debugger == 'lldb': args = ['lldb', '--'] + args elif debugger == 'gdb': args = ['gdb', '--args'] + args start = timer() if script_args.debug: print(' '.join(args)) sys.exit() env = logger.setup_trace_for_child(os.environ) logger.flush() add_extra_environment_args(env) # Our CI system occasionally fails because it is trying to write the # redex-all binary when this tries to run. This shouldn't happen, and # might be caused by a JVM bug. Anyways, let's retry and hope it stops. for i in range(5): try: subprocess.check_call(args, env=env) except OSError as err: if err.errno == errno.ETXTBSY: if i < 4: time.sleep(5) continue raise err except subprocess.CalledProcessError as err: script_filenames = write_debugger_commands(args) raise RuntimeError( ('redex-all crashed with exit code %s! ' % err.returncode) + ('You can re-run it ' 'under gdb by running %(gdb_script_name)s or under lldb ' 'by running %(lldb_script_name)s') % script_filenames) break log('Dex processing finished in {:.2f} seconds'.format(timer() - start))