The problem here is that we are modifying a 32 bit instruction with a 16 bit 
trap. The "IT" instruction isn't a branch and it shouldn't be considered one. 
The solution of using a 4 byte thumb breakpoint must be used and this will work 
for Linux, but won't work on MacOSX because our kernel, to my knowledge doesn't 
support a 32 bit thumb breakpoint. I will check on this. So the real fix is to 
use a 32 bit thumb breakpoint for 32 bit thumb instructions.

Greg

> On Dec 2, 2014, at 12:01 PM, jing...@apple.com wrote:
> 
> The question that the stepping code is really asking is "can I predict the 
> next instruction that will follow on from this one before I get there."  If 
> IsBranch isn't sufficient to know that for some instruction or class of 
> instructions, then adding whatever other tests are required seems okay 
> formally.  It would be nicer if the MC instructions had some other way to 
> characterize this and whatever other instructions behave the same way, but 
> I'm not clear enough on what the "way" is to know what question to ask the 
> instruction other than "IsBranch".  It would definitely be worth having a 
> conversation with the LLVM folks about some way to determine this.  
> Otherwise, having to special-case some instructions as "these we know confuse 
> us" seems ugly but not terrible.
> 
> Jim
> 
> 
>> On Dec 2, 2014, at 4:11 AM, Mario Zechner <badlogicga...@gmail.com> wrote:
>> 
>> Sorry Stephane, forgot to hit "Reply all".
>> 
>> I dug a bit deeper. The problem is in LLVM's instruction table for ARM 
>> Thumbv2. Here's the definition of the IT instruction 
>> (llvm/lib/Target/ARM/ARMInstrThumb2.td):
>> 
>> // IT block
>> let Defs = [ITSTATE] in
>> def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
>>                    AddrModeNone, 2,  IIC_iALUx,
>>                    "it$mask\t$cc", "", []>,
>>           ComplexDeprecationPredicate<"IT"> {
>>  // 16-bit instruction.
>>  let Inst{31-16} = 0x0000;
>>  let Inst{15-8} = 0b10111111;
>> 
>>  bits<4> cc;
>>  bits<4> mask;
>>  let Inst{7-4} = cc;
>>  let Inst{3-0} = mask;
>> 
>>  let DecoderMethod = "DecodeIT";
>> }
>> 
>> The instruction isn't marked as isBranch (e.g. via let isBranch=1). 
>> 
>> ThreadPlanStepRange retrieves the next branch instruction for an address 
>> range via InstructionList::GetIndexOfNextBranchInstruction, which uses a 
>> Disassembler instance that gets all the instruction info from that tablegen 
>> file (through the llvm::Target). For each lldb_private::Instruction in the 
>> list InstructionLLVMC::DoesBranch is called, which in turn calls 
>> DisassemblerLLVMC::LLVMCDisassembler::CanBranch. That method looks up the 
>> MCInstrDesc for the instruction's opcode. That MCInstrDesc has a Flag 
>> member, which comes from the tablegen file. That is set to 
>> MCID::UnmodeledSideEffects for the IT instruction, which is why it's not 
>> selected as the next branch instruction.
>> 
>> Now, i have no idea what side effects it would have to change the tablegen 
>> file and regenerate the table. My guess would be that it's a bad idea to 
>> change that 4.7k LOC .td file and hope for the best. I guess i'll manually 
>> check for the IT instruction in 
>> InstructionList::GetIndexOfNextBranchInstruction in case the target arch is 
>> ARM. That seems like a really dirty hack though.
>> 
>> Any other ideas? Is this something that should be brought up with the LLVM 
>> guys?
>> 
>> On Tue, Dec 2, 2014 at 1:10 PM, Mario Zechner <badlogicga...@gmail.com> 
>> wrote:
>> I dug a bit deeper. The problem is in LLVM's instruction table for ARM 
>> Thumbv2. Here's the definition of the IT instruction 
>> (llvm/lib/Target/ARM/ARMInstrThumb2.td):
>> 
>> // IT block
>> let Defs = [ITSTATE] in
>> def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
>>                    AddrModeNone, 2,  IIC_iALUx,
>>                    "it$mask\t$cc", "", []>,
>>           ComplexDeprecationPredicate<"IT"> {
>>  // 16-bit instruction.
>>  let Inst{31-16} = 0x0000;
>>  let Inst{15-8} = 0b10111111;
>> 
>>  bits<4> cc;
>>  bits<4> mask;
>>  let Inst{7-4} = cc;
>>  let Inst{3-0} = mask;
>> 
>>  let DecoderMethod = "DecodeIT";
>> }
>> 
>> The instruction isn't marked as isBranch (e.g. via let isBranch=1). 
>> 
>> ThreadPlanStepRange retrieves the next branch instruction for an address 
>> range via InstructionList::GetIndexOfNextBranchInstruction, which uses a 
>> Disassembler instance that gets all the instruction info from that tablegen 
>> file (through the llvm::Target). For each lldb_private::Instruction in the 
>> list InstructionLLVMC::DoesBranch is called, which in turn calls 
>> DisassemblerLLVMC::LLVMCDisassembler::CanBranch. That method looks up the 
>> MCInstrDesc for the instruction's opcode. That MCInstrDesc has a Flag 
>> member, which comes from the tablegen file. That is set to 
>> MCID::UnmodeledSideEffects for the IT instruction, which is why it's not 
>> selected as the next branch instruction.
>> 
>> Now, i have no idea what side effects it would have to change the tablegen 
>> file and regenerate the table. My guess would be that it's a bad idea to 
>> change that 4.7k LOC .td file and hope for the best. I guess i'll manually 
>> check for the IT instruction in 
>> InstructionList::GetIndexOfNextBranchInstruction in case the target arch is 
>> ARM. That seems like a really dirty hack though.
>> 
>> Any other ideas? Is this something that should be brought up with the LLVM 
>> guys?
>> 
>> On Mon, Dec 1, 2014 at 7:55 PM, Stephane Sezer <s...@fb.com> wrote:
>> I suppose it wouldn’t get hit, no. I don’t know about considering it 
>> instructions as a branching instruction. I guess it makes sense but I don’t 
>> know how the rest would work with it.
>> 
>> --
>> Stephane Sezer
>> 
>>> On Dec 1, 2014, at 10:47 AM, Mario Zechner <badlogicga...@gmail.com> wrote:
>>> 
>>> Thanks, i'm going to try that. I just wonder if it would make more sense to 
>>> consider the it instruction a branching instruction. Not sure what side 
>>> effects that may have.
>>> 
>>> Also, if i wrote a 4-byte breakpoint for blne, would it get hit if the it 
>>> branches over it? Guess i'll find out :)
>>> 
>>> On Dec 1, 2014 6:46 PM, "Stephane Sezer" <s...@fb.com> wrote:
>>> I remember fighting with this recently in our debug server (ds2), your 
>>> understanding of the problem is correct I believe. What you need to do is 
>>> to place a four-byte thumb breakpoint instead of a two-byte thumb 
>>> breakpoint. I don’t know what the iOS kernel expects exactly, but for 
>>> example the Linux kernel understands the following:
>>> - two-byte thumb breakpoint: 0xde01
>>> - four-byte thumb breakpoint: 0xa000f7f0
>>> - arm breakpoint: 0xe7f001f0
>>> 
>>> If you insert a four-byte thumb breakpoint at 0x27b2ea, the it instruction 
>>> will skip four bytes when skipping the breakpoint, and will end up at 
>>> address 0x27b2ee, which is what you would expect.
>>> 
>>> --
>>> Stephane Sezer
>>> 
>>>> On Dec 1, 2014, at 8:13 AM, Mario Zechner <badlogicga...@gmail.com> wrote:
>>>> 
>>>> I think i understand the issue now. 
>>>> ThreadPlanStepRange::SetNextBranchBreakpoint is falsely selecting the blne 
>>>> instruction instead of the it instruction. The condition is not meet, so 
>>>> the CPU jumps over the instruction after it. Since we have a trap there 
>>>> that's 2 bytes long, it will end up at 0x27b2ec (PC after 2 byte trap 
>>>> instruction) instead of 0x27b2ee (PC after 4 byte blne). So the CPU ends 
>>>> up in the middle of the blne instruction, which is of course not a valid 
>>>> instruction.
>>>> 
>>>> I guess the next thing i have to figure out is why the it instruction 
>>>> isn't marked as a branch instruction, which is why it isn't selected by 
>>>> ThreadPlanStepRange::SetNextBranchBreakpoint as the next branch breakpoint.
>>>> 
>>>> On Mon, Dec 1, 2014 at 4:59 PM, Mario Zechner <badlogicga...@gmail.com> 
>>>> wrote:
>>>> I traced through ThreadPlanStepRange and ThreadPlanStepRange for this 
>>>> piece of code:
>>>> 
>>>> 0x27b2d4 <[J]java.lang.Object.<init>()V>: push   {r7, lr}
>>>> 
>>>> 0x27b2d6 <[J]java.lang.Object.<init>()V+2>: mov    r7, sp
>>>> 
>>>> 0x27b2d8 <[J]java.lang.Object.<init>()V+4>: sub    sp, #0x4
>>>> 
>>>> 0x27b2da <[J]java.lang.Object.<init>()V+6>: movs   r2, #0x0
>>>> 
>>>> 0x27b2dc <[J]java.lang.Object.<init>()V+8>: str    r2, [sp]
>>>> 
>>>> 0x27b2de <[J]java.lang.Object.<init>()V+10>: str    r1, [sp]
>>>> 
>>>> 0x27b2e0 <[J]java.lang.Object.<init>()V+12>: ldr    r2, [r1]
>>>> 
>>>> 0x27b2e2 <[J]java.lang.Object.<init>()V+14>: ldr    r2, [r2, #0x30]
>>>> 
>>>> 0x27b2e4 <[J]java.lang.Object.<init>()V+16>: tst.w  r2, #0x100000
>>>> 
>>>> 0x27b2e8 <[J]java.lang.Object.<init>()V+20>: it     ne
>>>> 
>>>> 0x27b2ea <[J]java.lang.Object.<init>()V+22>: blne   0x466290               
>>>>    ; _bcRegisterFinalizer
>>>> 
>>>> 0x27b2ee <[J]java.lang.Object.<init>()V+26>: add    sp, #0x4
>>>> 
>>>> 0x27b2f0 <[J]java.lang.Object.<init>()V+28>: pop    {r7, pc}
>>>> 
>>>> 0x27b2f2 <[J]java.lang.Object.<init>()V+30>: nop
>>>> 
>>>> 
>>>> 
>>>> Execution is halted at 0x27b2e0 when i issue a source-level step. The 
>>>> ThreadPlanStepRange::DidPush method sets up a breakpoint at 0x27b2ea (2 
>>>> bytes) successfully after identifying the instruction at 0x27b2ea (blne) 
>>>> as the next branch instruction in 
>>>> ThreadPlanStepRange::SetNextBranchBreakpoint.
>>>> 
>>>> Next, the threads are then resumed by the command interpreter. We receive 
>>>> an event from the inferior with stop reason eStopReasonException 
>>>> (EXC_BAD_INSTRUCTION) right after the resume, stopping the process.
>>>> 
>>>> I guess this means i need to figure out how "it" and "blne" work together 
>>>> (my ARM assembler knowledge is minimal) to then understand why the 
>>>> breakpoint instruction that's written to the inferior results in a 
>>>> EXC_BAD_INSTRUCTION. If someone knows what could be the culprit let me 
>>>> know :)
>>>> 
>>>> Thanks,
>>>> 
>>>> Mario
>>>> 
>>>> 
>>>> On Mon, Dec 1, 2014 at 2:07 PM, Mario Zechner <badlogicga...@gmail.com> 
>>>> wrote:
>>>> Well, i wrote a very long mail detailing my journey to resolve issue #2 
>>>> (hanging after setting target.use-fast-stepping=false), only to eventually 
>>>> realize that it doesn't hang but instead just waits for the above loop to 
>>>> complete.
>>>> 
>>>> This means turning off target.use-fast-stepping is not an option and i'm 
>>>> back to square one. I'd be grateful for any pointers on how to fix issue 
>>>> #1 (EXC_BAD_INSTRUCTION). I guess i'll start by investigating the "run to 
>>>> next branch" stepping algorithm in LLDB, though my understanding is likely 
>>>> not sufficient to make a dent.
>>>> 
>>>> Thanks,
>>>> Mario
>>>> 
>>>> 
>>>> 
>>>> 
>>>> On Mon, Dec 1, 2014 at 11:05 AM, Mario Zechner <badlogicga...@gmail.com> 
>>>> wrote:
>>>> Hi,
>>>> 
>>>> setting target.use-fast-stepping to false did indeed solve this issue, 
>>>> albeit at the cost of increased runtime obviously. However, i ran into 
>>>> another issue right after i stepped out of the previously problematic 
>>>> function: http://sht.tl/bdAKRC
>>>> 
>>>> Trying to source-level step this function (with use-fast-stepping=false) 
>>>> results in 1) the disassembly getting all kinds of messed up and 2) the 
>>>> process not stepping but hanging at the `cmp r1, #0` instruction. The 
>>>> original assembly code around that PC looks like this:
>>>> 
>>>> LBB24_1:                                @ %label0
>>>>                                        @ =>This Inner Loop Header: Depth=1
>>>>      @DEBUG_VALUE: 
>>>> [J]java.lang.Thread.<init>(Ljava/lang/Runnable;Ljava/lang/String;)V:__$env 
>>>> <- R5
>>>>      ldrexd  r1, r2, [r0]
>>>>      strexd  r1, r6, r6, [r0]
>>>>      cmp     r1, #0
>>>>      bne     LBB24_1
>>>> @ BB#2:                                 @ %label0
>>>>      @DEBUG_VALUE: 
>>>> [J]java.lang.Thread.<init>(Ljava/lang/Runnable;Ljava/lang/String;)V:__$env 
>>>> <- R5
>>>>      dmb     ish
>>>>      movs    r1, #5
>>>> 
>>>> A simple loop, which is actually part of an inlined function. We had some 
>>>> issues with inlined functions previously, i assume this issue is related. 
>>>> Interestingly enough, the back trace is also a bit wonky:
>>>> 
>>>> (lldb) bt
>>>> 
>>>> * thread #1: tid = 0x18082, 0x0021a9b4 
>>>> AttachTestIOSDev`[J]java.lang.Thread.<init>(Ljava/lang/Runnable;Ljava/lang/String;)V
>>>>  [inlined] [j]java.lang.Thread.threadPtr(J)[set] + 14 at Thread.java:1, 
>>>> stop reason = trace
>>>> 
>>>>  * frame #0: 0x0021a9b4 
>>>> AttachTestIOSDev`[J]java.lang.Thread.<init>(Ljava/lang/Runnable;Ljava/lang/String;)V
>>>>  [inlined] [j]java.lang.Thread.threadPtr(J)[set] + 14 at Thread.java:1
>>>> 
>>>>    frame #1: 0x0021a9a6 
>>>> AttachTestIOSDev`[J]java.lang.Thread.<init>(__$env=0x01662fc8, 
>>>> __$this=0x64da3833, runnable=0xa4f07400, threadName=0x00286000)V + 46 at 
>>>> Thread.java:138
>>>> 
>>>> There should be a lot more frame. I'm gonna try to dig up some more 
>>>> details.
>>>> 
>>>> Thanks a lot!
>>>> Mario
>>>> 
>>>> 
>>>> 
>>>> On Sun, Nov 30, 2014 at 1:32 AM, Jason Molenda <ja...@molenda.com> wrote:
>>>> The size of the breakpoint instruction is set by 
>>>> GetSoftwareBreakpointTrapOpcode().  In your case, most likely you're in 
>>>> PlatformDarwin::GetSoftwareBreakpointTrapOpcode() - lldb uses the symbol 
>>>> table (from the binary file) to determine if the code in a given function 
>>>> is arm or thumb.  If it's arm, a 4 byte breakpoint is used.  If it's 
>>>> thumb, a 2 byte breakpoint.  Of course thumbv2 of T32 instructions can be 
>>>> 4 bytes -- the blne instruction is in your program -- but I assume the 2 
>>>> byte breakpoint instruction still works correctly in these cases; the cpu 
>>>> sees the 2-byte instruction and stops execution.
>>>> 
>>>> I am a little wary about the fact that this comes after an it instruction, 
>>>> I kind of vaguely remember issues with that instruction's behavior.
>>>> 
>>>> It shouldn't make any difference but you might want to try
>>>> 
>>>> (lldb) settings set target.use-fast-stepping false
>>>> 
>>>> which will force lldb to single instruction step through the function.  
>>>> Right now lldb is looking at the instruction stream and putting 
>>>> breakpoints on branch/call/jump instructions to do your high-level "step" 
>>>> command, instead of stopping on every instruction.  It is possible there 
>>>> could be a problem with that approach and the it instruction.  Please 
>>>> report back if this changes the behavior.
>>>> 
>>>> J
>>>> 
>>>> 
>>>>> On Nov 26, 2014, at 9:22 AM, Mario Zechner <badlogicga...@gmail.com> 
>>>>> wrote:
>>>>> 
>>>>> I dug a little deeper, inspecting the GDB remote packets send by LLDB to 
>>>>> perform the stepping. It appears when sending memory breakpoint commands 
>>>>> used for stepping, the size of the instruction being replaced isn't taken 
>>>>> into account, or writing back the original instruction isn't done 
>>>>> properly. The following log shows what happens when stepping into the 
>>>>> previously mentioned function:
>>>>> 
>>>>> (lldb) s
>>>>> Process 166 stopped
>>>>> * thread #1: tid = 0x0fd9, 0x002602e0 
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>(__$env=0x016bffc8, 
>>>>> __$this=0x017864b0)V + 12 at Object.java:136, queue = 
>>>>> 'com.apple.main-thread', stop reason = step in
>>>>>    frame #0: 0x002602e0 
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>(__$env=0x016bffc8, 
>>>>> __$this=0x017864b0)V + 12 at Object.java:136
>>>>> (lldb) disassemble -p
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>()V + 12 at Object.java:136:
>>>>> -> 0x2602e0:  ldr    r2, [r1]
>>>>>   0x2602e2:  ldr    r2, [r2, #0x30]
>>>>>   0x2602e4:  tst.w  r2, #0x100000
>>>>>   0x2602e8:  it     ne
>>>>> (lldb) s
>>>>> Process 166 stopped
>>>>> * thread #1: tid = 0x0fd9, 0x002602ec 
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>(__$env=0x016bffc8, 
>>>>> __$this=0x017864b0)V + 24 at Object.java:136, queue = 
>>>>> 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION 
>>>>> (code=EXC_ARM_UNDEFINED, subcode=0xffd1b001)
>>>>>    frame #0: 0x002602ec 
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>(__$env=0x016bffc8, 
>>>>> __$this=0x017864b0)V + 24 at Object.java:136
>>>>> (lldb) disassemble -p
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>()V + 24 at Object.java:136:
>>>>> -> 0x2602ec:  .long  0xb001ffd1                ; unknown opcode
>>>>>   0x2602f0:  pop    {r7, pc}
>>>>> 
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>()V + 30:
>>>>>   0x2602f2:  nop
>>>>> 
>>>>> AttachTestIOSDev`[J]java.lang.Object.clone()Ljava/lang/Object; at 
>>>>> Object.java:154:
>>>>>   0x2602f4:  push   {r4, r5, r7, lr}
>>>>> (lldb) disassemble -f
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>()V at Object.java:136:
>>>>>   0x2602d4:  push   {r7, lr}
>>>>>   0x2602d6:  mov    r7, sp
>>>>>   0x2602d8:  sub    sp, #0x4
>>>>>   0x2602da:  movs   r2, #0x0
>>>>>   0x2602dc:  str    r2, [sp]
>>>>>   0x2602de:  str    r1, [sp]
>>>>>   0x2602e0:  ldr    r2, [r1]
>>>>>   0x2602e2:  ldr    r2, [r2, #0x30]
>>>>>   0x2602e4:  tst.w  r2, #0x100000
>>>>>   0x2602e8:  it     ne
>>>>>   0x2602ea:  blne   0x44b290                  ; _bcRegisterFinalizer
>>>>>   0x2602ee:  add    sp, #0x4
>>>>>   0x2602f0:  pop    {r7, pc}
>>>>> 
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>()V + 30:
>>>>>   0x2602f2:  nop
>>>>> 
>>>>> The first step succeeds and ends up right after the prologue, at 
>>>>> 0x2602e0:  ldr    r2, [r1]. The next step ends up at 0x2602ec:  .long  
>>>>> 0xb001ffd1 which is wrong, it should be 0x2602ea:  blne   0x44b290.
>>>>> 
>>>>> The GDB remote conversation between lldb and the debugserver on the 
>>>>> device (only relevant parts):
>>>>> 
>>>>> # First step
>>>>> lldb->debugserver: $Z0,2602e0,2#73
>>>>> debugserver->lldb: $OK#00
>>>>> lldb->debugserver: $vCont;c:0fd9#15
>>>>> debugserver->lldb: (320) 
>>>>> $T05thread:fd9;qaddr:37ebfad0;threads:fd9,ffa,ffb,ffd,fff,1009,100a,100b;00:c8ff6b01;01:b0647801;02:00000000;03:c87d6a00;04:00000000;05:c8ff6b01;06:fc6a6501;07:0c6a6501;08:90e96b01;09:28000000;0a:74a0ea37;0b:c8ff6b01;0c:b09e5b00;0d:086a6501;0e:d1b22000;0f:
>>>>> 
>>>>> # Second step
>>>>> lldb->debugserver: $Z0,2602ea,2#a4
>>>>> debugserver->lldb: $OK#00
>>>>> lldb->debugserver: $vCont;c:0fd9#15
>>>>> debugserver->lldb: (324) 
>>>>> $T92thread:fd9;qaddr:37ebfad0;threads:fd9,ffa,ffb,ffd,fff,1009,100a,100b;00:c8ff6b01;01:b0647801;02:01004300;03:c87d6a00;04:00000000;05:c8ff6b01;06:fc6a6501;07:0c6a6501;08:90e96b01;09:28000000;0a:74a0ea37;0b:c8ff6b01;0c:b09e5b00;0d:086a6501;0e:d1b22000;0f:
>>>>> 
>>>>> For the first step, a 2 byte memory breakpoint is written to 0x2602e0 
>>>>> ($Z0,2602e0,2#73), which is where the first step ended up. The 
>>>>> instruction that got replaced is 2 bytes long. The GDB command wrote a 2 
>>>>> bytes memory breakpoint to the address, so all is good.
>>>>> 
>>>>> For the second step, a 2 byte memory breakpoint is written to 0x2602ea 
>>>>> ($Z0,2602ea,2#a4). But instead of ending up at 0x2602ec, which is in the 
>>>>> middle of the 4-byte blne instruction.
>>>>> 
>>>>> Is it correct for LLDB to set a 2 byte memory breakpoint instead of a 
>>>>> 4-byte memory breakpoint in this case? The PC will be set to an invalid 
>>>>> address, which then causes the EXC_BAD_INSTRUCTION.
>>>>> 
>>>>> Am i understanding this correctly? Is there a way for me to fix this?
>>>>> 
>>>>> On Wed, Nov 26, 2014 at 5:26 PM, Mario Zechner <badlogicga...@gmail.com> 
>>>>> wrote:
>>>>> Hi,
>>>>> 
>>>>> 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 {
>>>>> label0:
>>>>>    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"
>>>>> "_[J]java.lang.Object.<init>()V":
>>>>>      .cfi_startproc
>>>>> Lfunc_begin18:
>>>>>      .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
>>>>> Ltmp6:
>>>>>      ldr     r2, [r1]
>>>>>      ldr     r2, [r2, #48]
>>>>>      tst.w   r2, #1048576
>>>>> Ltmp7:
>>>>>      @DEBUG_VALUE: [J]java.lang.Object.<init>()V:__$env <- R0
>>>>>      it      ne
>>>>>      blxne   __bcRegisterFinalizer
>>>>>      add     sp, #4
>>>>>      pop     {r7, pc}
>>>>> Ltmp8:
>>>>> Lfunc_end18:
>>>>> "L_[J]java.lang.Object.<init>()V_end":
>>>>> 
>>>>>      .cfi_endproc
>>>>> =======================
>>>>> 
>>>>> Now, when stepping into this function, LLDB receives a signal from the 
>>>>> debug server:
>>>>> 
>>>>> =======================
>>>>> (lldb) s
>>>>> Process 176 stopped
>>>>> * 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)
>>>>>    frame #0: 0x0023e2ec 
>>>>> AttachTestIOSDev`[J]java.lang.Object.<init>(__$env=0x0169efc8, 
>>>>> __$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 :)
>>>>> 
>>>>> Thanks,
>>>>> Mario
>>>>> 
>>>>> _______________________________________________
>>>>> lldb-dev mailing list
>>>>> lldb-dev@cs.uiuc.edu
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> _______________________________________________
>>>> lldb-dev mailing list
>>>> lldb-dev@cs.uiuc.edu
>>>> https://urldefense.proofpoint.com/v1/url?u=http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev&k=ZVNjlDMF0FElm4dQtryO4A%3D%3D%0A&r=g1GoAnQQskSBaWLJWw6X6w%3D%3D%0A&m=Zl2rgz3vY3p3Z1gT4mYUogC%2B71s1vpu6iiR2%2BAqSFEs%3D%0A&s=3063d588fdc99fda75142f80da681ac13b53ba823de3e2221c1b01c0c7c54982
>>> 
>> 
>> 
>> 
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev@cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> 
> 
> _______________________________________________
> lldb-dev mailing list
> lldb-dev@cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev


_______________________________________________
lldb-dev mailing list
lldb-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to