summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2014-11-04 02:31:50 +0000
committerJason Molenda <jmolenda@apple.com>2014-11-04 02:31:50 +0000
commitd98c3abf9fb4278d37e89ec267f132aa85c12423 (patch)
treed6a0ef55b14a6f178e92a0c252b984d7b15983ff
parent8d8f396d86741bdf99e7a47173bc87b526729092 (diff)
downloadbcm5719-llvm-d98c3abf9fb4278d37e89ec267f132aa85c12423.tar.gz
bcm5719-llvm-d98c3abf9fb4278d37e89ec267f132aa85c12423.zip
After we've completed a full backtrace, we'll have one frame which
is "invalid" -- it is past the end of the stack trace. Add a new method IsCompletedStackWalk() so we can tell if an invalid stack frame is from a complete backtrace or if it might be worth re-trying the last unwind with a different method. This fixes the unwinder problems Ryan Brown was having with go programs. The unwinder can (under the right circumstances) still destructively replace unwind plans permanently - I'll work on that in a different patch. <rdar://problem/18683658> llvm-svn: 221229
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp18
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h7
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp3
3 files changed, 26 insertions, 2 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 5071b1aa578..88bb608ea9e 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -62,7 +62,8 @@ RegisterContextLLDB::RegisterContextLLDB
m_sym_ctx_valid (false),
m_frame_number (frame_number),
m_registers(),
- m_parent_unwind (unwind_lldb)
+ m_parent_unwind (unwind_lldb),
+ m_completed_stack_walk (false)
{
m_sym_ctx.Clear(false);
m_sym_ctx_valid = false;
@@ -306,6 +307,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
if (pc == 0)
{
m_frame_type = eNotAValidFrame;
+ m_completed_stack_walk = true;
UnwindLogMsg ("this frame has a pc of 0x0");
return;
}
@@ -386,6 +388,10 @@ RegisterContextLLDB::InitializeNonZerothFrame()
{
UnwindLogMsg ("could not find a valid cfa address");
m_frame_type = eNotAValidFrame;
+ if (cfa_regval == 0 || cfa_regval == 1)
+ {
+ m_completed_stack_walk = true;
+ }
return;
}
@@ -582,6 +588,10 @@ RegisterContextLLDB::InitializeNonZerothFrame()
{
UnwindLogMsg ("could not find a valid cfa address");
m_frame_type = eNotAValidFrame;
+ if (cfa_regval == 0 || cfa_regval == 1)
+ {
+ m_completed_stack_walk = true;
+ }
return;
}
@@ -1031,6 +1041,12 @@ RegisterContextLLDB::IsValid () const
}
bool
+RegisterContextLLDB::IsCompletedStackWalk () const
+{
+ return m_completed_stack_walk;
+}
+
+bool
RegisterContextLLDB::IsTrapHandlerFrame () const
{
return m_frame_type == eTrapHandlerFrame;
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
index ff0b77488eb..d272073de55 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -73,6 +73,9 @@ public:
IsValid () const;
bool
+ IsCompletedStackWalk () const;
+
+ bool
IsTrapHandlerFrame () const;
bool
@@ -240,6 +243,10 @@ private:
lldb_private::UnwindLLDB& m_parent_unwind; // The UnwindLLDB that is creating this RegisterContextLLDB
+ bool m_completed_stack_walk; // indicates that we completed a full stack walk
+ // (this frame is likely eNotAValidFrame aka !IsValid())
+ // and we should not continue trying to unwind
+
//------------------------------------------------------------------
// For RegisterContextLLDB only
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 37fd4f48955..b61819af0d8 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -174,7 +174,8 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
{
// 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())
+ if (reg_ctx_sp->IsCompletedStackWalk() == false
+ && m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
{
return AddOneMoreFrame (abi);
}
OpenPOWER on IntegriCloud