From d98c3abf9fb4278d37e89ec267f132aa85c12423 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 4 Nov 2014 02:31:50 +0000 Subject: [PATCH] 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. llvm-svn: 221229 --- .../Plugins/Process/Utility/RegisterContextLLDB.cpp | 18 +++++++++++++++++- .../Plugins/Process/Utility/RegisterContextLLDB.h | 7 +++++++ lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp | 3 ++- 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 5071b1a..88bb608 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 ff0b774..d272073 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 37fd4f4..b61819af 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); } -- 2.7.4