[lldb-dev] Problem unwinding from inside of a CRT function

jingham at apple.com jingham at apple.com
Wed Jan 21 14:30:05 PST 2015

> On Jan 21, 2015, at 2:16 PM, Zachary Turner <zturner at google.com> wrote:
> On Fri Jan 16 2015 at 1:53:00 PM Greg Clayton <gclayton at apple.com> wrote:
> Also, did you get my comment about improving functions bounds in the COFF parser? If you can do this, you won't really need to do any of the unwinding stuff because the assembly unwinder will take care of it, you just need to get good function bounds for everything using any means necessary in the ObjectFileCOFF parser by making all the symbols you can. You also need to identify what parts are trampolines. For example a call to printf usually goes through a PLT entry. These are often in one place in your binary and often there are not symbols in the symbol table for these. Identifying the symbols with a name like "printf" and also making the symbol a eSymbolTypeTrampoline will allow us to not set a breakpoint on your "printf" trampoline when you say "b printf" on the command line, and it will also give function bounds to these small trampoline code sections so we can step and unwind through them.
>  Regarding the function bounds, I thought about this some, and I'm not sure if this is going to be possible.  Consider a system library, like the CRT, being linked against with no symbol information.  Where are the function bounds going to coem from?  There's nothing in the symbol table of the COFF file, and there's no debug info.  And since we're talking about an x86 binary, unwind info is not part of the ABI.  There's just a huge block of code in the code section.  Even if we do have symbols (which is how we would determine function bounds for code we have no control over), we will only have "public symbols" released by Microsoft.  Public symbols do not consist of information about every function, and practically any non-trivial call is going to at some point transfer control to one of the private functions that have no symbol information.

For generic backtracing, that's going to be a problem.  For instance, if you want to interrupt & do a backtrace at some random point, you may get a frame wrong.  If the MS unwind library gets this right, by all means use that as a host function.  If they get that right, I'd be interested to see how they do that (though we probably will never know...)  After all, just doing "find the instruction just before from the current pc" is not entirely trivial on x86...

Anyway, for "step-over" and so on unexported functions will be less of a problem in practice, since for source level stepping, you are generally stepping from your user code to some other routine.  So the library routine you are stepping into has pretty much got to be an exported routine.  And since source level stepping doesn't by default stop in code with no debug info (though this is settable) you're just going to get out of there...

Now if you "step-into" and stop in system routines, and then try to use step-over-inst through the instructions in that routine, you may get into some more trouble. 

That is the sort of situation where being able to understand the caller instruction(s) could help out.  But step-over-inst (gdb's nexti) in code without symbols has generally been a bit of a crap shoot both in lldb & gdb.  Dunno how well the Windows debugger does with this.


More information about the lldb-dev mailing list