<div dir="ltr"><div>The problem is not the __read function, but a subroutine that the __read function calls. GDB shows it as __kernel_vsyscall, but LLDB doesn't have a name for it, I don't think LLDB even considers it a function.<br></div><div><div><font face="monospace, monospace"><br></font></div><div><span style="font-size:12.8000001907349px">"image show-unwind -a $pc" in the subroutine shows no unwind data.</span><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br class="">================================================================================</font></div><div><div><div><font face="monospace, monospace">-> 0xf7fdb420: pushl %ecx</font></div><div><font face="monospace, monospace"> 0xf7fdb421: pushl %edx</font></div><div><font face="monospace, monospace"> 0xf7fdb422: pushl %ebp</font></div><div><font face="monospace, monospace"> 0xf7fdb423: movl %esp, %ebp</font></div></div><div><font face="monospace, monospace">(lldb) image show-unwind -a $pc</font></div><div><font face="monospace, monospace">error: no unwind data found that matches '$pc'.</font></div></div><span style="font-family:monospace,monospace">==============================</span><span style="font-family:monospace,monospace">==============================</span><span style="font-family:monospace,monospace">====================</span></div><div><div><font face="monospace, monospace">libc.so.6`__read:</font></div><div><font face="monospace, monospace">-> 0xf7d9cbec <+28>: calll *%gs:0x10</font></div><div><font face="monospace, monospace"> 0xf7d9cbf3 <+35>: popl %ebx</font></div><div><font face="monospace, monospace"> 0xf7d9cbf4 <+36>: cmpl $0xfffff001, %eax</font></div><div><font face="monospace, monospace"> 0xf7d9cbf9 <+41>: jae 0xf7d9cc2d ; <+93></font></div></div><div><div><font face="monospace, monospace">(lldb) si</font></div><div><font face="monospace, monospace">th1/fr0 supplying caller's saved eip (8)'s location using assembly insn profiling UnwindPlan</font></div><div><font face="monospace, monospace">th1/fr0 supplying caller's register eip (8) from the stack, saved at CFA plus offset -4 [saved at 0xffffda8c]</font></div><div><font face="monospace, monospace"> th1/fr1 pc = 0xf7d31c73</font></div><div><font face="monospace, monospace">th1/fr0 supplying caller's register ebp (6) from the live RegisterContext at frame 0</font></div><div><font face="monospace, monospace"> th1/fr1 fp = 0xf7cc1940</font></div><div><font face="monospace, monospace">th1/fr0 supplying caller's saved esp (7)'s location using assembly insn profiling UnwindPlan</font></div><div><font face="monospace, monospace">th1/fr0 supplying caller's register esp (7), value is CFA plus offset 0 [value is 0xffffda90]</font></div><div><font face="monospace, monospace"> th1/fr1 sp = 0xffffda90</font></div><div><font face="monospace, monospace"> th1/fr1 with pc value of 0xf7d31c73, symbol name is '_IO_file_underflow'</font></div><div><font face="monospace, monospace"> th1/fr1 active row: 0x00000000f7d31b67: CFA=esp+48 => ebx=[CFA-20] ebp=[CFA-8] esi=[CFA-16] edi=[CFA-12] eip=[CFA-4]</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">th1/fr0 supplying caller's saved esp (7)'s location, cached</font></div><div><font face="monospace, monospace"> th1/fr1 CFA is 0xffffdac0: Register esp (7) contents are 0xffffda90, offset is 48</font></div><div><font face="monospace, monospace"> th1/fr1 m_cfa = 0xffffdac0</font></div><div><font face="monospace, monospace"> th1/fr1 initialized frame current pc is 0xf7d31c73 cfa is 0xffffdac0</font></div><div><font face="monospace, monospace">th1/fr0 supplying caller's saved eip (8)'s location, cached</font></div><div><font face="monospace, monospace">th1/fr0 using architectural default unwind method</font></div><div><font face="monospace, monospace">th1/fr0 with pc value of 0xf7fdb420, no symbol/function name is known.</font></div><div><font face="monospace, monospace">th1/fr0 0x00000000f7fdb420: CFA=ebp +8 => esp=CFA+0 ebp=[CFA-8] eip=[CFA-4]</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">th1/fr0 CFA is 0xf7cc1948: Register ebp (6) contents are 0xf7cc1940, offset is 8</font></div><div><font face="monospace, monospace">th1/fr0 initialized frame current pc is 0xf7fdb420 cfa is 0xf7cc1948 using i386 default unwind plan UnwindPlan</font></div><div><font face="monospace, monospace"><div>Process 22545 stopped</div><div>* thread #1: tid = 22545, 0xf7fdb420, name = 'getline32', stop reason = instruction step into</div><div> frame #0: 0xf7fdb420</div><div>-> 0xf7fdb420: pushl %ecx</div><div> 0xf7fdb421: pushl %edx</div><div> 0xf7fdb422: pushl %ebp</div><div> 0xf7fdb423: movl %esp, %ebp</div><div>(lldb) bt</div><div>th1/fr0 supplying caller's saved eip (8)'s location using i386 default unwind plan UnwindPlan</div><div>th1/fr0 supplying caller's register eip (8) from the stack, saved at CFA plus offset -4 [saved at 0xf7cc1944]</div><div> th1/fr1 pc = 0xf7cc1e08</div><div>th1/fr0 supplying caller's saved ebp (6)'s location using i386 default unwind plan UnwindPlan</div><div>th1/fr0 supplying caller's register ebp (6) from the stack, saved at CFA plus offset -8 [saved at 0xf7cc1940]</div><div> th1/fr1 fp = 0xf7cc1940</div><div>th1/fr0 supplying caller's saved esp (7)'s location using i386 default unwind plan UnwindPlan</div><div>th1/fr0 supplying caller's register esp (7), value is CFA plus offset 0 [value is 0xf7cc1948]</div><div> th1/fr1 sp = 0xf7cc1948</div><div> th1/fr1 using architectural default unwind method</div><div> th1/fr1 had a pc of 0xf7cc1e08 which is not in executable memory but on frame 1 -- allowing it once.</div><div>th1/fr0 supplying caller's saved ebp (6)'s location, cached</div><div> th1/fr1 CFA is 0xf7cc1948: Register ebp (6) contents are 0xf7cc1940, offset is 8</div><div> th1/fr1 same CFA address as next frame, assuming the unwind is looping - stopping</div><div> Frame 1 invalid RegisterContext for this frame, stopping stack walk</div><div>th1 Unwind of this thread is complete.</div><div>* thread #1: tid = 22545, 0xf7fdb420, name = 'getline32', stop reason = instruction step into</div><div> * frame #0: 0xf7fdb420</div></font></div></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 10, 2015 at 5:59 PM, Jason Molenda <span dir="ltr"><<a href="mailto:jmolenda@apple.com" target="_blank">jmolenda@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi guys, sorry for not seeing this thread yesterday.<br>
<br>
lldb should be able to handle this function, if and only if it knows the start address for the function/symbol. The assembly instruction profiler can do the right thing with an instruction sequence like this.<br>
<br>
The first thing to do is<br>
<br>
(lldb) image show-unwind -a $pc<br>
<br>
when you're stopped in the function, or<br>
<br>
(lldb) image show-unwind -n __read<br>
<br>
This will dump the various UnwindPlans that lldb can use for this function.<br>
<br>
To see how the unwinder is actually walking the stack, before you step into __read, do<br>
<br>
(lldb) log enable lldb unwind<br>
<br>
then go into __read and try to backtrace a couple of frames.<br>
<br>
The output may not be easy to read - but send it along and I can interpret.<br>
<span class="HOEnZb"><font color="#888888"><br>
J<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> On Mar 10, 2015, at 5:29 PM, Chaoren Lin <<a href="mailto:chaorenl@google.com">chaorenl@google.com</a>> wrote:<br>
><br>
> After some more debugging, I no longer think it's related to the syscall. The subroutine that invokes the syscall has a strange prologue (see below) which results in a return address stored at ebp+12 instead of ebp+4, which seems to be what LLDB uses to determine if a frame is valid. Is there some way we could not rely on the return address being at ebp+4? Maybe cache esp after every call instruction? Or keep looking up the stack for a valid return address? Or should we call this an intended behavior and use something other than fgets while waiting to be attached in TestHelloWorld.<br>
><br>
> libc.so.6`__read:<br>
><br>
> -> 0xf7d9cbec <+28>: calll *%gs:0x10<br>
><br>
> -> 0xf7fdb420: pushl %ecx<br>
> 0xf7fdb421: pushl %edx<br>
> 0xf7fdb422: pushl %ebp<br>
> 0xf7fdb423: movl %esp, %ebp<br>
> 0xf7fdb425: sysenter<br>
><br>
> On Tue, Mar 10, 2015 at 10:26 AM, Pavel Labath <<a href="mailto:labath@google.com">labath@google.com</a>> wrote:<br>
><br>
> On 10 March 2015 at 17:13, Chaoren Lin <<a href="mailto:chaorenl@google.com">chaorenl@google.com</a>> wrote:<br>
> According to the Apple dudes in that conversation, UnwindLLDB and RegisterContextLLDB are what I should be looking at, correct?<br>
><br>
> Yes, those are the two main classes. I would go about by going through RegisterContextLLDB::InitializeZerothFrame and try to figure out what UnwindPlan it ends up using. Then compare the unwind plan with the information obtained from gdb, for instance.<br>
><br>
> I don't know where it gets its default unwind plan on i386 (maybe from nowhere?), but the reason the unwinding works (mostly) could be that lldb can read unwind plans from dwarf info which is generally embedded in the files.<br>
><br>
> I suspect unwinding on i386 could be a bit tricky (especially in the proximity of assembly code like syscall internals) since the architecture has less registers, so people tend to reuse ebp for storing other stuff, which makes locating stuff on the stack harder.<br>
><br>
<br>
</div></div></blockquote></div><br></div>