aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/Utility/UnwindLLDB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/Utility/UnwindLLDB.cpp')
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp46
1 files changed, 36 insertions, 10 deletions
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 37fd4f489552..fc592e60d86d 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -172,8 +172,9 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
if (!reg_ctx_sp->IsValid())
{
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ // We failed to get a valid RegisterContext.
+ // See if the regctx below this on the stack has a fallback unwind plan it can use.
+ // Subsequent calls to TryFallbackUnwindPlan() will return false.
if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
{
return AddOneMoreFrame (abi);
@@ -207,18 +208,35 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
// these.
if (reg_ctx_sp->IsTrapHandlerFrame() == false)
{
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
+ // See if we can find a fallback unwind plan for THIS frame. It may be
+ // that the UnwindPlan we're using for THIS frame was bad and gave us a
+ // bad CFA.
+ // If that's not it, then see if we can change the UnwindPlan for the frame
+ // below us ("NEXT") -- see if using that other UnwindPlan gets us a better
+ // unwind state.
+ if (reg_ctx_sp->TryFallbackUnwindPlan() == false
+ || reg_ctx_sp->GetCFA (cursor_sp->cfa) == false
+ || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false)
{
- return AddOneMoreFrame (abi);
+ if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
+ {
+ return AddOneMoreFrame (abi);
+ }
+ if (log)
+ {
+ log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ }
+ goto unwind_done;
}
- if (log)
+ else
{
- log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ if (log)
+ {
+ log->Printf("%*sFrame %d had a bad CFA value but we switched the UnwindPlan being used and got one that looks more realistic.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ }
}
- goto unwind_done;
}
}
if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
@@ -366,6 +384,14 @@ UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
UnwindLLDB::RegisterSearchResult result;
result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+ // We descended down to the live register context aka stack frame 0 and are reading the value
+ // out of a live register.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
+ && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext)
+ {
+ return true;
+ }
+
// If we have unwind instructions saying that register N is saved in register M in the middle of
// the stack (and N can equal M here, meaning the register was not used in this function), then
// change the register number we're looking for to M and keep looking for a concrete location