[lldb-dev] RFC: Support for unwinding on windows

Pavel Labath via lldb-dev lldb-dev at lists.llvm.org
Fri Aug 23 03:52:47 PDT 2019


Hello everyone,

after a short recess, I have started to resume work on the breakpad 
symbols project. The project is "nearly" finished, but there is one more 
thing remaining to be done. This is to support stack unwinding for 32 
bit windows targets.

The unwinding info in breakpad is represented differently in breakpad, 
because unwinding on 32bit windows is... different. For example, an 
"unwind plan" for a typical win32 function would be described by a 
string like "$T0 .raSearch = $eip $TO ^ = $esp $TO 4 + =". Now, this 
string is basically a program in a special postfix language, and if you 
look closely, you can recognise fragments like "$eip = deref(T0)", and 
"$esp = $T0 + 4", which look fairly typical. However, there's this 
".raSearch" bit that is unlike anything we have in lldb at the moment.

The way that .raSearch works is that it asks the debugger to look around 
the stack for something that looks like a plausible return address, and 
then return the address of that return address. Now, the reason that 
this works (mostly) reliably is that on windows, the debug info contains 
information about the size of functions' stack frames -- the number of 
bytes taken up by local variables, arguments, etc. Armed with this 
knowledge, the debugger can skip portions of the stack that definitely 
do not hold the return address and can e.g. avoid confusing function 
pointer arguments for the return addresses.

The way I propose to implement this in lldb is:
- SymbolFile: add two new APIs to get the number of stack bytes used by 
a function for locals and the size of function arguments. Two functions 
are needed because (as usual) the function arguments are considered a 
part of the callers stack frame, and so the number of arguments for a 
function is relevant not when unwinding this function, but for the 
unwinding of its caller. SymbolFileBreakpad (and later SymbolFilePDB -- 
Adrian is working on that) will implement these function to return the 
appropriate values.
- UnwindPlan: add a new value (isFoundHeuristically) to the CFA kind 
enumeration. When encountering this value, the unwinder will search the 
stack for a value that looks like a pointer to a known code section. It 
will use the above SymbolFile APIs to skip over uninteresting parts of 
the stack. SymbolFileBreakpad will search for the known usage patterns 
of the .raSearch keyword and generate appropriate unwind plans (i.e. set 
CFA to "isFoundHeuristically", and appropriate rules for the other 
registers)

I've created a couple of patches which demonstrate how this could be 
implemented. The most interesting one is 
<https://reviews.llvm.org/D66638>, which is WIP, but I should be 
sufficient for demonstration purposes. 
<https://reviews.llvm.org/D66634>, and <https://reviews.llvm.org/D66633> 
are also needed for this patch to work, but they are largely 
uninteresting from an general unwind perspective.

Let me know if you have any questions, concerns, suggestions, etc.

Pavel


More information about the lldb-dev mailing list