<div dir="ltr">Hi,<div><br></div><div>we generate thumbv7 binaries for iOS devices. We deploy, launch and debug those via LLDB. Stepping into functions seems to almost always generate a EXC_BAD_INSTRUCTION signal. The signal is not generated when running the app without the debugger attached. It is also not generated when we attach a debugger, but simply let the app run without breakpoints or any stepping.</div><div><br></div><div>Here's one of these function's LLVM IR:</div><div><br></div><div>=======================</div><div><div>define external void @"[J]java.lang.Object.<init>()V"(%Env* %p0, %Object* %p1) nounwind noinline optsize {</div><div>label0:</div><div>    call void @"llvm.dbg.declare"(metadata !{%Env* %p0}, metadata !19), !dbg !{i32 136, i32 0, metadata !{i32 786478, metadata !0, metadata !1, metadata !"[J]java.lang.Object.<init>()V", metadata !"[J]java.lang.Object.<init>()V", metadata !"", i32 136, metadata !15, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%Env*, %Object*)* @"[J]java.lang.Object.<init>()V", null, null, metadata !17, i32 136}, null}</div><div>    %r0 = alloca %Object*</div><div>    store %Object* null, %Object** %r0</div><div>    call void @"llvm.dbg.declare"(metadata !{%Object** %r0}, metadata !21), !dbg !{i32 136, i32 0, metadata !14, null}</div><div>    store %Object* %p1, %Object** %r0</div><div>    call void @"register_finalizable"(%Env* %p0, %Object* %p1), !dbg !{i32 136, i32 0, metadata !18, null}</div><div>    ret void, !dbg !{i32 136, i32 0, metadata !18, null}</div><div>}</div></div><div>=======================<br></div><div><br></div><div>The corresponding thumbv7 assembler code as generated by LLVM:</div><div><br></div><div>=======================<br></div><div><div><span class="" style="white-space:pre">      </span>.globl<span class="" style="white-space:pre">    </span>"_[J]java.lang.Object.<init>()V"</div><div><span class="" style="white-space:pre">   </span>.align<span class="" style="white-space:pre">    </span>2</div><div><span class="" style="white-space:pre">  </span>.code<span class="" style="white-space:pre">     </span>16                      @ @"[J]java.lang.Object.<init>()V"</div><div><span class="" style="white-space:pre">      </span>.thumb_func<span class="" style="white-space:pre">       </span>"_[J]java.lang.Object.<init>()V"</div><div>"_[J]java.lang.Object.<init>()V":</div><div><span class="" style="white-space:pre">   </span>.cfi_startproc</div><div>Lfunc_begin18:</div><div><span class="" style="white-space:pre">        </span>.loc<span class="" style="white-space:pre">      </span>1 136 0                 @ Object.java:136:0</div><div>@ BB#0:                                 @ %label0</div><div><span class="" style="white-space:pre">        </span>.loc<span class="" style="white-space:pre">      </span>1 136 0                 @ Object.java:136:0</div><div><span class="" style="white-space:pre">        </span>push<span class="" style="white-space:pre">      </span>{r7, lr}</div><div><span class="" style="white-space:pre">   </span>mov<span class="" style="white-space:pre">       </span>r7, sp</div><div><span class="" style="white-space:pre">     </span>sub<span class="" style="white-space:pre">       </span>sp, #4</div><div><span class="" style="white-space:pre">     </span>@DEBUG_VALUE: [J]java.lang.Object.<init>()V:__$env <- R0</div><div><span class="" style="white-space:pre">  </span>movs<span class="" style="white-space:pre">      </span>r2, #0</div><div><span class="" style="white-space:pre">     </span>str<span class="" style="white-space:pre">       </span>r2, [sp]</div><div><span class="" style="white-space:pre">   </span>str<span class="" style="white-space:pre">       </span>r1, [sp]</div><div><span class="" style="white-space:pre">   </span>.loc<span class="" style="white-space:pre">      </span>1 136 0 prologue_end    @ Object.java:136:0</div><div>Ltmp6:</div><div><span class="" style="white-space:pre"> </span>ldr<span class="" style="white-space:pre">       </span>r2, [r1]</div><div><span class="" style="white-space:pre">   </span>ldr<span class="" style="white-space:pre">       </span>r2, [r2, #48]</div><div><span class="" style="white-space:pre">      </span>tst.w<span class="" style="white-space:pre">     </span>r2, #1048576</div><div>Ltmp7:</div><div><span class="" style="white-space:pre">  </span>@DEBUG_VALUE: [J]java.lang.Object.<init>()V:__$env <- R0</div><div><span class="" style="white-space:pre">  </span>it<span class="" style="white-space:pre">        </span>ne</div><div><span class="" style="white-space:pre"> </span>blxne<span class="" style="white-space:pre">     </span>__bcRegisterFinalizer</div><div><span class="" style="white-space:pre">      </span>add<span class="" style="white-space:pre">       </span>sp, #4</div><div><span class="" style="white-space:pre">     </span>pop<span class="" style="white-space:pre">       </span>{r7, pc}</div><div>Ltmp8:</div><div>Lfunc_end18:</div><div>"L_[J]java.lang.Object.<init>()V_end":</div><div><br></div><div><span class="" style="white-space:pre">     </span>.cfi_endproc</div></div><div>=======================<br></div><div><br></div><div>Now, when stepping into this function, LLDB receives a signal from the debug server:</div><div><br></div><div><div>=======================<br></div><div>(lldb) s</div><div>Process 176 stopped</div><div>* thread #1: tid = 0x11f5, 0x0023e2ec AttachTestIOSDev`[J]java.lang.Object.<init>(__$env=0x0169efc8, __$this=0x0174cd10)V + 24 at Object.java:136, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_ARM_UNDEFINED, subcode=0xffd1b001)</div><div>    frame #0: 0x0023e2ec AttachTestIOSDev`[J]java.lang.Object.<init>(__$env=0x0169efc8, __$this=0x0174cd10)V + 24 at Object.java:136</div></div><div>=======================<br></div><div><br></div><div>Disassembling around the PC gives:</div><div><br></div><div>=======================<br></div><div><div>(lldb) disassemble --pc</div><div>AttachTestIOSDev`[J]java.lang.Object.<init>()V + 24 at Object.java:136:</div><div>-> 0x23e2ec:  .long  0xb001ffd1                ; unknown opcode</div><div>   0x23e2f0:  pop    {r7, pc}</div><div><br></div><div>AttachTestIOSDev`[J]java.lang.Object.<init>()V + 30:</div><div>   0x23e2f2:  nop</div></div><div><br></div><div>Disassembling until the beginning of the frame gives:</div><div><br></div><div><div>(lldb) disassemble -f</div><div>AttachTestIOSDev`[J]java.lang.Object.<init>()V at Object.java:136:</div><div>   0x23e2d4:  push   {r7, lr}</div><div>   0x23e2d6:  mov    r7, sp</div><div>   0x23e2d8:  sub    sp, #0x4</div><div>   0x23e2da:  movs   r2, #0x0</div><div>   0x23e2dc:  str    r2, [sp]</div><div>   0x23e2de:  str    r1, [sp]</div><div>   0x23e2e0:  ldr    r2, [r1]</div><div>   0x23e2e2:  ldr    r2, [r2, #0x30]</div><div>   0x23e2e4:  tst.w  r2, #0x100000</div><div>   0x23e2e8:  it     ne</div><div>   0x23e2ea:  blne   0x429290                  ; _bcRegisterFinalizer</div><div>   0x23e2ee:  add    sp, #0x4</div><div>   0x23e2f0:  pop    {r7, pc}</div></div><div><br></div><div>Accprding to this, execution should never end up at address 0x23e2ec. That's right in the middle of the blne and add instructions in the second disassembly. I have a hunch that the debugserver on the device may interfere here, e.g. add a trap instruction to implement the stepping. I'm not quite sure what to make of it.</div><div><br></div><div>I'd appreciate any hints. If you require more information, i got plenty of logs :)</div><div><br></div><div>Thanks,</div><div>Mario</div></div>