[lldb-dev] Stepping into function generates EXC_BAD_INSTRUCTION signal

Mario Zechner badlogicgames at gmail.com
Wed Nov 26 08:26:38 PST 2014


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.

Here's one of these function's LLVM IR:

define external void @"[J]java.lang.Object.<init>()V"(%Env* %p0, %Object*
%p1) nounwind noinline optsize {
    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}
    %r0 = alloca %Object*
    store %Object* null, %Object** %r0
    call void @"llvm.dbg.declare"(metadata !{%Object** %r0}, metadata !21),
!dbg !{i32 136, i32 0, metadata !14, null}
    store %Object* %p1, %Object** %r0
    call void @"register_finalizable"(%Env* %p0, %Object* %p1), !dbg !{i32
136, i32 0, metadata !18, null}
    ret void, !dbg !{i32 136, i32 0, metadata !18, null}

The corresponding thumbv7 assembler code as generated by LLVM:

.globl "_[J]java.lang.Object.<init>()V"
.align 2
.code 16                      @ @"[J]java.lang.Object.<init>()V"
.thumb_func "_[J]java.lang.Object.<init>()V"
.loc 1 136 0                 @ Object.java:136:0
@ BB#0:                                 @ %label0
.loc 1 136 0                 @ Object.java:136:0
push {r7, lr}
mov r7, sp
sub sp, #4
@DEBUG_VALUE: [J]java.lang.Object.<init>()V:__$env <- R0
movs r2, #0
str r2, [sp]
str r1, [sp]
.loc 1 136 0 prologue_end    @ Object.java:136:0
ldr r2, [r1]
ldr r2, [r2, #48]
tst.w r2, #1048576
@DEBUG_VALUE: [J]java.lang.Object.<init>()V:__$env <- R0
it ne
blxne __bcRegisterFinalizer
add sp, #4
pop {r7, pc}


Now, when stepping into this function, LLDB receives a signal from the
debug server:

(lldb) s
Process 176 stopped
* thread #1: tid = 0x11f5, 0x0023e2ec
__$this=0x0174cd10)V + 24 at Object.java:136, queue =
'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION
(code=EXC_ARM_UNDEFINED, subcode=0xffd1b001)
    frame #0: 0x0023e2ec
__$this=0x0174cd10)V + 24 at Object.java:136

Disassembling around the PC gives:

(lldb) disassemble --pc
AttachTestIOSDev`[J]java.lang.Object.<init>()V + 24 at Object.java:136:
-> 0x23e2ec:  .long  0xb001ffd1                ; unknown opcode
   0x23e2f0:  pop    {r7, pc}

AttachTestIOSDev`[J]java.lang.Object.<init>()V + 30:
   0x23e2f2:  nop

Disassembling until the beginning of the frame gives:

(lldb) disassemble -f
AttachTestIOSDev`[J]java.lang.Object.<init>()V at Object.java:136:
   0x23e2d4:  push   {r7, lr}
   0x23e2d6:  mov    r7, sp
   0x23e2d8:  sub    sp, #0x4
   0x23e2da:  movs   r2, #0x0
   0x23e2dc:  str    r2, [sp]
   0x23e2de:  str    r1, [sp]
   0x23e2e0:  ldr    r2, [r1]
   0x23e2e2:  ldr    r2, [r2, #0x30]
   0x23e2e4:  tst.w  r2, #0x100000
   0x23e2e8:  it     ne
   0x23e2ea:  blne   0x429290                  ; _bcRegisterFinalizer
   0x23e2ee:  add    sp, #0x4
   0x23e2f0:  pop    {r7, pc}

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.

I'd appreciate any hints. If you require more information, i got plenty of
logs :)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20141126/b36af2ba/attachment.html>

More information about the lldb-dev mailing list