diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp | 90 |
1 files changed, 85 insertions, 5 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index 552ae50..5db08e5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -26,8 +26,21 @@ using namespace lldb_private; UnwindLLDB::UnwindLLDB (Thread &thread) : Unwind (thread), m_frames(), - m_unwind_complete(false) + m_unwind_complete(false), + m_user_supplied_trap_handler_functions() { + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) + { + Args args; + process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames (args); + size_t count = args.GetArgumentCount(); + for (size_t i = 0; i < count; i++) + { + const char *func_name = args.GetArgumentAtIndex(i); + m_user_supplied_trap_handler_functions.push_back (ConstString (func_name)); + } + } } uint32_t @@ -95,7 +108,13 @@ UnwindLLDB::AddFirstFrame () first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; m_frames.push_back (first_cursor_sp); return true; + unwind_done: + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); + if (log) + { + log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); + } m_unwind_complete = true; return false; } @@ -138,10 +157,27 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) } if (reg_ctx_sp.get() == NULL) + { + // 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()) + { + return AddOneMoreFrame (abi); + } + if (log) + log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); goto unwind_done; + } 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. + if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + return AddOneMoreFrame (abi); + } if (log) { log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk", @@ -151,6 +187,12 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) } if (!reg_ctx_sp->GetCFA (cursor_sp->cfa)) { + // 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()) + { + return AddOneMoreFrame (abi); + } if (log) { log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk", @@ -160,15 +202,33 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) } if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { - if (log) + // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not have + // its (constructed) CFA aligned correctly -- don't do the abi alignment check for + // these. + if (reg_ctx_sp->IsTrapHandlerFrame() == false) { - 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 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()) + { + 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; } - goto unwind_done; } if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc)) { + // 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()) + { + return AddOneMoreFrame (abi); + } if (log) { log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk", @@ -178,6 +238,12 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) } if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc)) { + // 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()) + { + return AddOneMoreFrame (abi); + } if (log) { log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk", @@ -185,12 +251,26 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) } goto unwind_done; } + if (!m_frames.empty()) + { + // Infinite loop where the current cursor is the same as the previous one... + if (m_frames.back()->start_pc == cursor_sp->start_pc && m_frames.back()->cfa == cursor_sp->cfa) + { + if (log) + log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID()); + goto unwind_done; + } + } cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; m_frames.push_back (cursor_sp); return true; unwind_done: + if (log) + { + log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); + } m_unwind_complete = true; return false; } |