NB I do know about one remaining small problem with this on your example program. The eh_frame augmentation is doing the correct thing, e.g. image show-unwind says that the original eh_frame instructions were
row[0]: 0: CFA=rsp +8 => rip=[rsp] row[1]: 1: CFA=rsp+16 => rbp=[rsp] rip=[rsp+8] row[2]: 4: CFA=rbp+16 => rbp=[rbp] rip=[rbp+8] & the augmented instructions identify the mid-function epilogue at offset 41, re-instate the unwind rules on offset 42, and then get the unwind rules correct for the final epilogue instruction at offset 68: row[0]: 0: CFA=rsp +8 => rip=[rsp] row[1]: 1: CFA=rsp+16 => rbp=[rsp] rip=[rsp+8] row[2]: 4: CFA=rbp+16 => rbp=[rbp] rip=[rbp+8] row[3]: 41: CFA=rsp +8 => rbp=[rsp-8] rip=[rsp] row[4]: 42: CFA=rbp+16 => rbp=[rbp] rip=[rbp+8] row[5]: 68: CFA=rsp +8 => rbp=[rsp-8] rip=[rsp] But the assembly language unwinder, which you wouldn't use here, is missing the final epilogue. It gets row[0]: 0: CFA=rsp +8 => rsp=rsp+8 rip=[rsp] row[1]: 1: CFA=rsp+16 => rbp=[rsp] rsp=rsp+16 rip=[rsp+8] row[2]: 4: CFA=rbp+16 => rbp=[rbp] rsp=rbp+16 rip=[rbp+8] row[3]: 41: CFA=rsp +8 => rsp=rsp+8 rip=[rsp] row[4]: 42: CFA=rbp+16 => rbp=[rbp] rsp=rbp+16 rip=[rbp+8] I need to track that down still but it's time to go home. For simple test programs I tried, it's doing the correct thing. But there's an off-by-one error with this particular function that I need to track down before this is complete. J > On Jan 12, 2015, at 11:41 PM, Jason Molenda <jmole...@apple.com> wrote: > > Give top of tree a try if you're still doing codegen like this. Let me know > if it doesn't look correct. > > > Sending source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp > Transmitting file data . > Committed revision 225773. > > > >> On Jan 8, 2015, at 8:10 AM, Mario Zechner <badlogicga...@gmail.com> wrote: >> >> Hi, >> >> sorry for taking so long. You can find a binary at >> http://libgdx.badlogicgames.com/downloads/InvalidFrameTest.zip >> >> This is a debug build for Mac OS X 64-bit. You should be able to run >> it, the README.md file has a few notes about that in it. Let me know >> if i can help any other way. >> >> Thanks, >> Mario >> >> On Jan 7, 2015 2:55 AM, "Jason Molenda" <jmole...@apple.com> wrote: >>> >>> Can you send me a binary with one of these mid-function epilogues in the >>> middle? I'm not going to run it. (I mean, if you want to make a self >>> contained binary that I *could* run, that'd be awesome but I can test it by >>> static inspection by using 'image show-unwind' after loading the binary >>> into an x86-64 debug session) it'll be easier to add support for >>> mid-function epilogues if I have an example of one without having to write >>> it myself. >>> >>> J >>> >>>> On Jan 5, 2015, at 4:34 PM, Jason Molenda <jmole...@apple.com> wrote: >>>> >>>> I should fix the x86 assembly unwinder, it's something I knew would fail >>>> eventually when lldb was used on a significantly different code generation >>>> style. It's not terribly difficult - assembly profiler code needs to save >>>> the unwind state once the prologue has finished. When it detects the >>>> start of the epilogue instruction sequence, it preserves the unwind state >>>> until the epilogue has finished and then re-installs it. >>>> >>>> If you can change your codegen to have a single return for i386/x86_64, >>>> that would definitely work. But this is a limitation in the x86 unwinder >>>> right now - that's where the real fix should be done. >>>> >>>> J >>>> >>>>> On Jan 5, 2015, at 4:10 PM, Mario Zechner <badlogicga...@gmail.com> wrote: >>>>> >>>>> Hi Jason, >>>>> >>>>> thanks for the response. We temporarily 'fixed' it by disabling the >>>>> eh_frame unwinder [1] in our LLDB fork. We did this after figuring out >>>>> that the LLDB version shipped with XCode didn't exhibit the issue. We >>>>> compared the diagnostic unwind info and found XCode's LLDB not using that >>>>> unwinder plan. It's a nasty hack we'd like to get rid of. >>>>> >>>>> We also found that the latest trunk of LLDB has the same issue with >>>>> 32-bit x86. Here's the 32-bit version of the failing method [2]. It also >>>>> contains a mid-function epilogue, bumping esp instead of rsp. >>>>> >>>>> The mid-functiom epilogues are a result of translating JVM bytecode [3] >>>>> straight to LLVM IR. The bytecode contains mid-function returns. I guess >>>>> we could coalesce those into a single basic block just like Clang does, >>>>> using a temporary to store the return value. >>>>> >>>>> Thanks! >>>>> Mario >>>>> >>>>> [1] https://gist.github.com/badlogic/f7d65aca25270ee3b93d >>>>> [2] https://gist.github.com/badlogic/da0c7a3de6ffa3446bba >>>>> [3] https://gist.github.com/badlogic/571fdcced98968e08499 >>>>> >>>>> On Jan 6, 2015 12:41 AM, "Jason Molenda" <jmole...@apple.com> wrote: >>>>> Hi Mario, sorry I missed this one over the holidays. >>>>> >>>>> The problem here is the >>>>> '[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V' >>>>> function. It has a mid-function epilogue which lldb can't handle today >>>>> on x86_64. This is a common idiom on armv7/arm64 - I have experience >>>>> with how to solve the problem there but I had never seen a compiler >>>>> generate code like this on x86_64 so it wasn't handled there. >>>>> >>>>> In your example session, when you're stopped at 0x000000010014bb5f, lldb >>>>> is no longer able to backtrace. Looking at the disassembly, we see that >>>>> 0x10014bb5f is just past a mid-function epilogue. We'll need to update >>>>> the x86_64 assembly unwinder to recognize the epilogue sequence and >>>>> re-install the previous unwind state before the epilogue unwound it. >>>>> >>>>> 0x10014bb38 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V>: pushq >>>>> %rbp >>>>> 0x10014bb39 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+1>: movq >>>>> %rsp, %rbp >>>>> 0x10014bb3c >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+4>: subq >>>>> $0x20, %rsp >>>>> 0x10014bb40 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+8>: movq >>>>> %rdi, -0x8(%rbp) >>>>> 0x10014bb44 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+12>: movq >>>>> -0x10000(%rsp), %rax >>>>> 0x10014bb4c >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+20>: movl >>>>> %esi, -0xc(%rbp) >>>>> 0x10014bb4f >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+23>: cmpl >>>>> $0x64, -0xc(%rbp) >>>>> 0x10014bb53 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+27>: movq >>>>> %rdi, -0x18(%rbp) >>>>> 0x10014bb57 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+31>: jle >>>>> 0x10014bb5f ; >>>>> [J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V + 39 at >>>>> InvalidFrame.java:13 >>>>> 0x10014bb59 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+33>: addq >>>>> $0x20, %rsp >>>>> 0x10014bb5d >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+37>: popq >>>>> %rbp >>>>> 0x10014bb5e >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+38>: retq >>>>> 0x10014bb5f >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+39>: movl >>>>> -0xc(%rbp), %eax >>>>> 0x10014bb62 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+42>: addl >>>>> $0x1, %eax >>>>> 0x10014bb65 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+45>: movl >>>>> %eax, -0x10(%rbp) >>>>> 0x10014bb68 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+48>: movl >>>>> -0x10(%rbp), %esi >>>>> 0x10014bb6b >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+51>: movq >>>>> -0x18(%rbp), %rdi >>>>> 0x10014bb6f >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+55>: >>>>> callq 0x10014bb38 ; >>>>> [J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V at >>>>> InvalidFrame.java:10 >>>>> 0x10014bb74 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+60>: addq >>>>> $0x20, %rsp >>>>> 0x10014bb78 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+64>: popq >>>>> %rbp >>>>> 0x10014bb79 >>>>> <[J]com.robovm.debug.server.apps.InvalidFrame.testRecursion(I)V+65>: retq >>>>> >>>>> >>>>> >>>>> >>>>> >>>>>> On Dec 23, 2014, at 6:59 AM, Mario Zechner <badlogicga...@gmail.com> >>>>>> wrote: >>>>>> >>>>>> Hi, >>>>>> >>>>>> i'm running into stack unwinding issues when trying to get a backtrace >>>>>> for a currently selected thread. You can see the output of >>>>>> diagnose-unwind here: >>>>>> https://gist.github.com/badlogic/99736e5c37f54ea08481 >>>>>> >>>>>> The simple stack walking algorithm in diagnose-unwind succeeds in >>>>>> reconstructing the correct frames. >>>>>> >>>>>> Any idea what I could be doing wrong or how i could fix this issue? >>>>>> >>>>>> 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 http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev