[lldb-dev] LLDB deadlocks trying to unwind
jmolenda at apple.com
Thu Aug 22 15:50:40 PDT 2013
You'll want to use UnwindLLDB.
Your ABI plugin may need to define the following methods (used by UnwindLLDB, RegisterContextLLDB):
The (*) ones are important for unwinding.
For CreateDefaultUnwindPlan, the "default unwind plan" is how lldb will unwind a stack frame by default. e.g. on architectures where there is a frame pointer, dereferencing the frame pointer address often gives you the calling frame's frame pointer, and one word off of that you'll find the caller's saved pc value.
For CreateFunctionEntryUnwindPlan, this is the unwind plan which tells lldb how to find the caller function when it is sitting on the first instruction of a function. e.g. it was single-instruction-stepping along, it stepped into a new function, and it needs to find the caller.
RegisterIsVolatile tells lldb whether a register is callee-saved or not. Whether it is preserved or not. Whether it is spilled or not. Whether it is volatile or not. Different people use different terms. Your ABI doc will specify which registers are volatile or not. NB: on architectures that use registers for argument passing, the argument registers are "volatile" because they are assumed to be reused/overwritten on any function call.
Both x86 and arm have UnwindAssembly implementations (e.g. source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp) - the UnwindAssembly class looks at the assembly instructions of a function and creates an UnwindPlan based on them. It is done statically so flow control is ignored. It's not ideal but the unwind instructions in the eh_frame section are not necessary valid at non-call sites in a program, and we found that we can get more accurate debugger behavior by inspecting the instructions manually than by following eh_frame.
The UnwindAssembly-generated UnwindPlan is used when unwinding the current frame (frame 0) in a program.
Above frame 0, we are guaranteed to be at a call site and so we will prefer to use eh_frame instructions if they are available.
For you, starting with the CreateDefaultUnwindPlan and CreateFunctionEntryUnwindPlan should be enough to bootstrap. If your environment has eh_frame, using that would be a good idea. Implementing a UnwindAssembly for ppc may be some real work - I would not take that on initially.
On Aug 22, 2013, at 3:35 PM, Félix Cloutier <felixcca at yahoo.ca> wrote:
> I'm making a stub for an emulator that executes PPC code.
> Le 2013-08-22 à 18:30:09, Jason Molenda <jmolenda at apple.com> a écrit :
>> On Aug 22, 2013, at 3:27 PM, Jason Molenda <jmolenda at apple.com> wrote:
>>> On Aug 22, 2013, at 1:26 PM, Félix Cloutier <felixcca at yahoo.ca> wrote:
>>>> #5 lldb_private::Mutex::Locker::Locker(lldb_private::Mutex&) at lldb/source/Host/common/Mutex.cpp:113
>>>> #6 lldb_private::Unwind::GetFrameCount() at lldb/include/lldb/Target/Unwind.h:51
>>>> #7 UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(unsigned int, unsigned long long&, unsigned long long&) at lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp:59
>>>> #8 lldb_private::Unwind::GetFrameInfoAtIndex(unsigned int, unsigned long long&, unsigned long long&) at lldb/include/lldb/Target/Unwind.h:78
>>>> #9 lldb_private::StackFrameList::GetFramesUpTo(unsigned int) at lldb/source/Target/StackFrameList.cpp:304
>>> I'll look at this a bit.
>>> The fact that you're picking up the UnwindMacOSXFrameBackchain is probably the source of the problem. This was an early unwinder written by Greg back before we had UnwindLLDB and RegisterContextLLDB - it hasn't been modified in a couple of years except for mechanical changes made across the source base.
>> What architecture are you debugging? Thread::GetUnwinder() should use UnwindLLDB for x86_64, i386, arm and thumb. It will use UnwindMacOSXFrameBackchain for any other architectures .... but it should probably just fail instead.
More information about the lldb-dev