> On Oct 15, 2014, at 1:43 PM, Ryan Brown <[email protected]> wrote:
> 
> Go doesn't have exception handlers, so it doesn't write .eh_frame. Wouldn't 
> it make sense to use .debug_frame if .eh_frame is missing?

Yes it does make sense. 

> 
> With my custom RegisterContext I got backtraces to work for my memory 
> threads. But something strange is going on. I have 10 threads that should 
> have identical traces, but the first has 5 frames, then 4, 3, 2, and the rest 
> only have 1 frame.

Yeah, you will need to trace through and see what is going wrong by debugging 
this.


> 
> There's a log here, thread 6 is the one with the complete backtrace. 
> https://gist.github.com/ribrdb/386fb0e555e82483d21d
> 
> Comparing thread 7 with thread 6, things seem fine up to line 627:
>     th7/fr4 supplying caller's stack pointer (7) value, computed from CFA
>      th7/fr5 sp = 0x000000020809ffc8
>      th7/fr5 active row: 0x0000000000002050: CFA=rbp+16 => rbp=[rbp] 
> rsp=rbp+16 rip=[rbp+8]
> 
> While thread 6 has:
>      th6/fr4 supplying caller's stack pointer (7) value, computed from CFA
>      th6/fr5 sp = 0x000000020809f7c8
>      th6/fr5 active row: 0x000000000000206a: CFA=rsp+16 => rsp=rsp+16 
> rip=[rsp+8]
> 
> I don't know where rbp came from, it's not in the function at all:
> 0x2050 <main.okread>: movq   %gs:0x8a0, %rcx
> 0x2059 <main.okread+9>: cmpq   0x10(%rcx), %rsp
> 0x205d <main.okread+13>: ja     0x2066                    ; main.okread + 22 
> at test.go:9
> 0x205f <main.okread+15>: callq  0x2d510                   ; 
> runtime.morestack_noctxt at asm_amd64.s:330
> 0x2064 <main.okread+20>: jmp    0x2050                    ; main.okread at 
> test.go:9
> 0x2066 <main.okread+22>: subq   $0x8, %rsp
> 0x206a <main.okread+26>: movq   0x10(%rsp), %rbx
> 0x206f <main.okread+31>: movq   %rbx, (%rsp)
> 0x2073 <main.okread+35>: callq  0x2000                    ; main.doread at 
> test.go:5
> 0x2078 <main.okread+40>: addq   $0x8, %rsp
> 0x207c <main.okread+44>: retq
> 0x207d <main.okread+45>: addb   %al, (%rax)
> 
> 
> 
> 
> 
> -- Ryan Brown
> 
> On Wed, Oct 15, 2014 at 11:48 AM, Ryan Brown <[email protected]> wrote:
> Yes, I'm writing a class to do that now. It's just not supported by any of 
> the existing register contexts.
> 
> -- Ryan Brown
> 
> On Wed, Oct 15, 2014 at 11:37 AM, Jason Molenda <[email protected]> wrote:
> Can't your OS plugin for the goroutines use the same sp and ip register 
> numbers as x86_64 (instead of 0 and 1 like you might be using right now) when 
> it reports them to lldb, and return all the other registers as "unavailable" 
> if they're requested?
> 
> The tricky bit about living on eh_frame / debug_frame is that lldb doesn't 
> know what kind of unwind info it is being given.  Is it just for exception 
> handling locations?  Does it contain prologue setup?  epilogue?  Is it fully 
> asynchronous - giving unwind details at all locations?  There aren't any 
> flags in eh_frame/debug_frame that could give us a hint about what we're 
> working with.
> 
> 
> 
> On Oct 15, 2014, at 11:24 AM, Ryan Brown <[email protected]> wrote:
> 
> > I'm actually struggling with this right now. I'm trying to implement an OS 
> > plugin so goroutines show up as threads.
> > The go compiler puts instruction accurate unwind info into .debug_frame, 
> > I'm not sure what (if anything) goes into eh_frame.
> > However lldb uses the disassembly instead of the dwarf info. The x86 
> > unwinder assumes that all threads have the same LLDB register numbers, but 
> > other parts of the code require that the LLDB register number is < (number 
> > of registers). Goroutines only store sp and ip, so it seems I'm going to 
> > have to create a custom RegisterContext subclass to get the existing 
> > unwinder to work for goroutines.
> >
> > On Tue, Oct 14, 2014 at 5:51 PM, Jason Molenda <[email protected]> wrote:
> > > On Oct 13, 2014, at 9:55 AM, Greg Clayton <gclayton at apple.com
> > > wrote:
> >
> > >
> >
> >
> > >
> >
> >
> > >> On Oct 10, 2014, at 1:58 PM, Francois Pichet <pichet2000 at gmail.com
> > > wrote:
> >
> > >>
> >
> >
> > >>
> >
> >
> > >>
> >
> >
> > >> On Fri, Oct 10, 2014 at 4:20 PM, Greg Clayton <gclayton at apple.com
> > > wrote:
> >
> > >>
> >
> >
> > >>> On Oct 10, 2014, at 1:05 PM, Philippe Lavoie <philippe.lavoie at 
> > >>> octasic.com
> > > wrote:
> >
> > >>>
> >
> >
> > >>>
> >  Hi,
> >
> > >>>
> >
> >
> > >>>
> >  I noticed that by default lldb does not read .debug_frame section to 
> > unwind frames but relies instead on .eh_frame .
> >
> > >>>
> >
> >
> > >>>
> >  Is there a way to fallback to reading .debug_frame?
> >
> > >>
> >
> >
> > >>
> >  Not currently. Most compilers (gcc _and_ clang) put the same old stuff in 
> > .debug_frame as they do in .eh_frame, so we haven't had to use .debug_frame 
> > over .eh_frame yet. What compiler are using that is putting different (more 
> > complete) info in .debug_frame vs .eh_frame?
> >
> > >>
> >
> >
> > >>
> >
> >
> > >>
> >  What about about C or C++ program compiled with -fno-exceptions?
> >
> > >>
> >  They will fall back to the UnwindAssembly way even if the .debug_frame is 
> > present right?
> >
> > >
> >
> >
> > >
> >  If no EH frame exists for a frame, then we will always fall back to 
> > UnwindAssembly. We always use UnwindAssembly for the first frame and for 
> > any frame that is past an async interrupt (sigtramp). We use the EH 
> > frame/.debug_frame for any non-zero frames, but will always use 
> > UnwindAssembly if there is no such info.
> >
> >
> >
> > I want to expand on what Greg said earlier about eh_frame versus 
> > debug_frame.
> >
> > Ideally, eh_frame will be the minimal unwind instructions necessary to 
> > unwind the stack when exceptions are thrown/caught.  eh_frame will not 
> > include unwind instructions for the prologue instructions or epilogue 
> > instructions -- because we can't throw an exception there, or have an 
> > exception thrown from a called function "below" us on the stack.  We call 
> > these unwind instructions "synchronous" because they only describe the 
> > unwind state from a small set of locations.
> >
> > debug_frame would describe how to unwind the stack at every instruction 
> > location.  Every instruction of the prologue and epilogue.  If the code is 
> > built without a frame pointer, then it would have unwind instructions at 
> > every place where the stack pointer is modified.  We describe these unwind 
> > instructions as "asynchronous" because they describe the unwind state at 
> > every instruction location.
> >
> >
> > Instead what we have with gcc and clang is eh_frame instructions that 
> > describe the prologue (and some versions of gcc, the epilogue) plus the 
> > unwind state at synchronous unwind locations (where an exception can be 
> > thrown).  We have a half-way blend of asynchronous and synchronous ... it's 
> > "pretty good" but not "guaranteed" from a debugger's perspective.  It would 
> > be great if eh_frame was genuinely only the unwind instructions for 
> > exception handling and debug_frame had the full unwind state at every 
> > instruction and we could depend on debug_frame.  But in reality, the same 
> > unwind instructions are put in both eh_frame and debug_frame -- so there's 
> > little point in ever reading debug_frame.  lldb does not read debug_frame 
> > today, although it would be easy to do so.
> >
> >
> > As an experiment starting late August (r216406), lldb is now trying to use 
> > eh_frame for the currently-executing frame.  Even though it isn't 
> > *guaranteed* to be accurate at all instructions, in practice it's pretty 
> > good -- good enough that gdb seems to be able to live on it.  Tong Shen's 
> > patch in r216406 does augment the eh_frame unwind instructions with the 
> > epilogue unwind... newer gcc's apparently describe the epilogue in eh_frame 
> > but few other compilers do.
> >
> > It's an open question how well living off eh_frame unwind instructions will 
> > work with a non-gcc/non-clang compiler.  That's why I say this is an 
> > "experiment" - we may have to revert to lldb's UnwindAssembly profiling 
> > code for the currently-executing function if this breaks with other 
> > compilers.
> >
> > J
> >
> >
> > _______________________________________________
> > lldb-dev mailing list
> > [email protected]
> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> 
> 
> 
> _______________________________________________
> lldb-dev mailing list
> [email protected]
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev


_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to