redex: Redex crashes with specific input during regalloc pass with compiler optimisations disabled

I’ve used https://github.com/google/iosched application as an input file with with following configuration: { “redex” : { “passes” : [ “RegAllocPass”, “InstructionSelectionPass” ] } } Default redex binary with all the compiler optimisations turned on works perfectly fine but if you compile with -O0 the process crashes during regalloc pass: `deephole-MBP:redex-master deep.hole$ ./redex.py app-debug.apk -c config/default.config (modified) Using config config/default.config Using binary (default) Extracting apk… Detected dex mode Api21DexMode Unpacking dex files Detecting Application Modules Unpacking APK finished in 0.31 seconds Running redex-all on 2 dex files Running redex binary at /Users/deep.hole/Downloads/redex-master/redex-all Verify-none mode: No Loading classes from dex from /var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/tmpajr924pl.redex_dexen/dex0/classes.dex Loading classes from dex from /var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/tmpajr924pl.redex_dexen/dex1/classes2.dex Load classes from dexes completed in 1.4 seconds Deobfuscating dex elements completed in 0.3 seconds Initializing reachable classes completed in 0.3 seconds Processing proguard rules completed in 0.1 seconds Evaluating RegAllocPass… RegAllocPass (eval) completed in 0.0 seconds Evaluating InstructionSelectionPass… InstructionSelectionPass (eval) completed in 0.0 seconds Running RegAllocPass… Traceback (most recent call last): File “./redex.py”, line 152, in run_pass subprocess.check_call(args, env=env) File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py”, line 291, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command ‘[’/Users/deep.hole/Downloads/redex-master/redex-all’, ‘–apkdir’, ‘/var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/tmpvh5d59zw.redex_extracted_apk’, ‘–outdir’, ‘/var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/tmpajr924pl.redex_dexen’, ‘–config’, ‘config/default.config’, ‘/var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/tmpajr924pl.redex_dexen/dex0/classes.dex’, ‘/var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/tmpajr924pl.redex_dexen/dex1/classes2.dex’]’ died with <Signals.SIGILL: 4>.

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File “./redex.py”, line 636, in <module> run_redex(args) File “./redex.py”, line 568, in run_redex debugger) File “./redex.py”, line 165, in run_pass ‘by running %(lldb_script_name)s’) % script_filenames) RuntimeError: redex-all crashed with exit code -4! You can re-run it under gdb by running /var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/redex-gdb-ao9k29_m.sh or under lldb by running /var/folders/cc/gz_1p6j11hvglj_h79vhpg300000gn/T/redex-lldb-ccxr_1zu.sh deephole-MBP:redex-master deep.hole$ `

I didn't manage to extract crash logs from vanilla redex, but on my forked project where I'm using ASAN and cmake crashlog looks like this :

`Evaluating InstructionSelectionPass… InstructionSelectionPass (eval) completed in 0.0 seconds Running RegAllocPass… ASAN:DEADLYSIGNAL

==49993==ERROR: AddressSanitizer: stack-overflow on address 0x700000645f40 (pc 0x000109726186 bp 0x700000646310 sp 0x700000645f40 T18) #0 0x109726185 in std::__1::__hash_iterator<std::__1::__hash_node<Block*, void*>> std::__1::__hash_table<Block, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >::find<Block*>(Block* const&) __hash_table:2169 #1 0x10a33c475 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) unordered_set:558 #2 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #3 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #4 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #5 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #6 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #7 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #8 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #9 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #10 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #11 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #12 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #13 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #14 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #15 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #16 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #17 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #18 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #19 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #20 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #21 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #22 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #23 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #24 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #25 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #26 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #27 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #28 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #29 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #30 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #31 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #32 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #33 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #34 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #35 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #36 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #37 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #38 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #39 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #40 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #41 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #42 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #43 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #44 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #45 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #46 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #47 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #48 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #49 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #50 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #51 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #52 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #53 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #54 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #55 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #56 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #57 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #58 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #59 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #60 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #61 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #62 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #63 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #64 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #65 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #66 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #67 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #68 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #69 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #70 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #71 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #72 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #73 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #74 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #75 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #76 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #77 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #78 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #79 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #80 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #81 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #82 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #83 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #84 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #85 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #86 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #87 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #88 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #89 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #90 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #91 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #92 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #93 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #94 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #95 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #96 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #97 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #98 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #99 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #100 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #101 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #102 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #103 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #104 0x10a33f864 in transform::visit(Block*, std::__1::unordered_set<Block*, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >&) Transform.cpp:99 #105 0x1099c39a0 in ControlFlowGraph::ControlFlowGraph(IRCode*, bool) ControlFlow.cpp:191 #106 0x1099cff4b in ControlFlowGraph::ControlFlowGraph(IRCode*, bool) ControlFlow.cpp:63 #107 0x109e5389b in IRCode::build_cfg(bool) memory:3153 #108 0x1098cd43a in RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0::operator()(std::nullptr_t&, DexMethod*) const RegAlloc.cpp:86 #109 0x1098cbe81 in regalloc::graph_coloring::Allocator::Stats walk_methods_parallel<std::nullptr_t, regalloc::graph_coloring::Allocator::Stats, std::__1::vector<DexClass*, std::__1::allocator<DexClass*> >, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2>(std::__1::vector<DexClass*, std::__1::allocator<DexClass*> > const&, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2, regalloc::graph_coloring::Allocator::Stats const&, unsigned long)::‘lambda’(std::nullptr_t&, DexClass*)::operator()(std::nullptr_t&, DexClass*) const ParallelWalkers.h:50 #110 0x1098cb399 in regalloc::graph_coloring::Allocator::Stats std::__1::__invoke_void_return_wrapperregalloc::graph_coloring::Allocator::Stats::__call<regalloc::graph_coloring::Allocator::Stats walk_methods_parallel<std::nullptr_t, regalloc::graph_coloring::Allocator::Stats, std::__1::vector<DexClass*, std::__1::allocator<DexClass*> >, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2>(std::__1::vector<DexClass*, std::__1::allocator<DexClass*> > const&, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2, regalloc::graph_coloring::Allocator::Stats const&, unsigned long)::‘lambda’(std::nullptr_t&, DexClass*)&, std::nullptr_t&, DexClass*>(regalloc::graph_coloring::Allocator::Stats walk_methods_parallel<std::nullptr_t, regalloc::graph_coloring::Allocator::Stats, std::__1::vector<DexClass*, std::__1::allocator<DexClass*> >, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2>(std::__1::vector<DexClass*, std::__1::allocator<DexClass*> > const&, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2, regalloc::graph_coloring::Allocator::Stats const&, unsigned long)::‘lambda’(std::nullptr_t&, DexClass*)&&&, std::nullptr_t&&&, DexClass*&&) __functional_base:416 #111 0x1098cb14f in std::__1::__function::__func<regalloc::graph_coloring::Allocator::Stats walk_methods_parallel<std::nullptr_t, regalloc::graph_coloring::Allocator::Stats, std::__1::vector<DexClass*, std::__1::allocator<DexClass*> >, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2>(std::__1::vector<DexClass*, std::__1::allocator<DexClass*> > const&, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2, regalloc::graph_coloring::Allocator::Stats const&, unsigned long)::‘lambda’(std::nullptr_t&, DexClass*), std::__1::allocator<regalloc::graph_coloring::Allocator::Stats walk_methods_parallel<std::nullptr_t, regalloc::graph_coloring::Allocator::Stats, std::__1::vector<DexClass*, std::__1::allocator<DexClass*> >, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2>(std::__1::vector<DexClass*, std::__1::allocator<DexClass*> > const&, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2, regalloc::graph_coloring::Allocator::Stats const&, unsigned long)::‘lambda’(std::nullptr_t&, DexClass*)>, regalloc::graph_coloring::Allocator::Stats (std::nullptr_t&, DexClass*)>::operator()(std::nullptr_t&, DexClass*&&) functional:1437 #112 0x1098f0a7c in std::__1::function<regalloc::graph_coloring::Allocator::Stats (std::nullptr_t&, DexClass*)>::operator()(std::nullptr_t&, DexClass*) const functional:1817 #113 0x1098eee39 in WorkQueue<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::consume(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, DexClass) WorkQueue.h:76 #114 0x1098ec118 in WorkQueue<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long)::operator()(WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long) const WorkQueue.h:185 #115 0x1098eb248 in void std::__1::__thread_proxy<std::__1::tuple<WorkQueue<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long), WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long> >(void) __functional_base:416 #116 0x7fffa774a93a in _pthread_body (libsystem_pthread.dylib:x86_64+0x393a) #117 0x7fffa774a886 in _pthread_start (libsystem_pthread.dylib:x86_64+0x3886) #118 0x7fffa774a08c in thread_start (libsystem_pthread.dylib:x86_64+0x308c)

SUMMARY: AddressSanitizer: stack-overflow __hash_table:2169 in std::__1::__hash_iterator<std::__1::__hash_node<Block*, void*>> std::__1::__hash_table<Block, std::__1::hash<Block*>, std::__1::equal_to<Block*>, std::__1::allocator<Block*> >::find<Block*>(Block* const&) Thread T18 created by T0 here: #0 0x10bf2fca6 in wrap_pthread_create (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4cca6) #1 0x1098ea70f in std::__1:🧵:thread<WorkQueue<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long)&, WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long&, void>(WorkQueue<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long)&&&, WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>&&, unsigned long&&&) thread:369 #2 0x1098e9c5c in std::__1:🧵:thread<WorkQueue<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long)&, WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long&, void>(WorkQueue<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long)&&&, WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>&&, unsigned long&&&) thread:365 #3 0x1098e9a5f in void std::__1::vector<std::__1::thread, std::__1::allocatorstd::__1::thread >::__emplace_back_slow_path<WorkQueue<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long)&, WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long&>(WorkQueue<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&)::‘lambda’(WorkerState<DexClass*, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>, unsigned long)&&&, WorkerState<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>&&, unsigned long&&&) memory:1752 #4 0x1098c729f in WorkQueue<DexClass, std::nullptr_t, regalloc::graph_coloring::Allocator::Stats>::run_all(regalloc::graph_coloring::Allocator::Stats const&) vector:1650 #5 0x1098c53be in regalloc::graph_coloring::Allocator::Stats walk_methods_parallel<std::nullptr_t, regalloc::graph_coloring::Allocator::Stats, std::__1::vector<DexClass*, std::__1::allocator<DexClass*> >, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2>(std::__1::vector<DexClass*, std::__1::allocator<DexClass*> > const&, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_0, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_1, RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&):😒_2, regalloc::graph_coloring::Allocator::Stats const&, unsigned long) ParallelWalkers.h:65 #6 0x1098c3aa3 in RegAllocPass::run_pass(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, ConfigFiles&, PassManager&) RegAlloc.cpp:62 #7 0x109f9a6c6 in PassManager::run_passes(std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, std::__1::vector<DexClass*, std::__1::allocator<DexClass*> > const&, ConfigFiles&) PassManager.cpp:141 #8 0x1091fe660 in (anonymous namespace)::runOptimizationPasses(ConfigFiles&, std::__1::vector<DexStore, std::__1::allocator<DexStore> >&, redex::ProguardConfiguration const&, Json::Value const&, std::__1::vector< #19 0x7fffa7531234 in start (libdyld.dylib:x86_64+0x5234)

==49993==ABORTING

Process finished with exit code 6`

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 15 (8 by maintainers)

Most upvoted comments

I can confirm that increasing stack size via -stack_size linker flag helped me. Thank you!

Fix which worked for me using boost if anybody is interested:

@@ -16,7 +16,8 @@
 #include <mutex>
 #include <queue>
 #include <random>
-#include <thread>
+//#include <thread>
+#include "boost/thread.hpp"
 
 namespace workqueue_impl {
 
@@ -121,7 +122,7 @@
 WorkQueue<Input, std::nullptr_t /*Data*/, std::nullptr_t /*Output*/>
 workqueue_foreach(
     const std::function<void(Input)>& func,
-    unsigned int num_threads = std::thread::hardware_concurrency()) {
+    unsigned int num_threads = boost::thread::hardware_concurrency()) {
   using Data = std::nullptr_t;
   using Output = std::nullptr_t;
   return WorkQueue<Input, Data, Output>(
@@ -142,7 +143,7 @@
 WorkQueue<Input, std::nullptr_t /*Data*/, Output> workqueue_mapreduce(
     const std::function<Output(Input)>& mapper,
     const std::function<Output(Output, Output)>& reducer,
-    unsigned int num_threads = std::thread::hardware_concurrency()) {
+    unsigned int num_threads = boost::thread::hardware_concurrency()) {
   using Data = std::nullptr_t;
   return WorkQueue<Input, Data, Output>(
       [mapper](Data&, Input a) -> Output { return mapper(a); },
@@ -170,7 +171,7 @@
 template <class Input, class Data, class Output>
 Output WorkQueue<Input, Data, Output>::run_all(const Output& init_output) {
   m_currently_running = true;
-  std::vector<std::thread> all_threads;
+  std::vector<boost::thread> all_threads;
   auto worker = [&](WorkerState<Input, Data, Output>* state, size_t state_idx) {
     state->result = init_output;
     auto attempts =
@@ -192,8 +193,11 @@
     }
   };
 
+  boost::thread::attributes attrs;
+  attrs.set_stack_size(4096*500);
+
   for (size_t i = 0; i < m_num_threads; ++i) {
-    all_threads.emplace_back(worker, m_states[i].get(), i);
+    all_threads.emplace_back(attrs, boost::bind<void>(worker, m_states[i].get(), i));
   }
 
   for (auto& thread : all_threads) {

I’ve rewritten visit with a loop instead of recursion. That change should land tomorrow.