//===-- UnwindLLDB.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "lldb/Target/UnwindLLDB.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/ABI.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/RegisterContextUnwind.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; UnwindLLDB::UnwindLLDB(Thread &thread) : Unwind(thread), m_frames(), 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 UnwindLLDB::DoGetFrameCount() { if (!m_unwind_complete) { //#define DEBUG_FRAME_SPEED 1 #if DEBUG_FRAME_SPEED #define FRAME_COUNT 10000 using namespace std::chrono; auto time_value = steady_clock::now(); #endif if (!AddFirstFrame()) return 0; ProcessSP process_sp(m_thread.GetProcess()); ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; while (AddOneMoreFrame(abi)) { #if DEBUG_FRAME_SPEED if ((m_frames.size() % FRAME_COUNT) == 0) { const auto now = steady_clock::now(); const auto delta_t = now - time_value; printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT, duration(delta_t).count(), (float)FRAME_COUNT / duration(delta_t).count()); time_value = now; } #endif } } return m_frames.size(); } bool UnwindLLDB::AddFirstFrame() { if (m_frames.size() > 0) return true; ProcessSP process_sp(m_thread.GetProcess()); ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; // First, set up the 0th (initial) frame CursorSP first_cursor_sp(new Cursor()); RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this)); if (reg_ctx_sp.get() == nullptr) goto unwind_done; if (!reg_ctx_sp->IsValid()) goto unwind_done; if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa)) goto unwind_done; if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc)) goto unwind_done; // Everything checks out, so release the auto pointer value and let the // cursor own it in its shared pointer first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; m_frames.push_back(first_cursor_sp); // Update the Full Unwind Plan for this frame if not valid UpdateUnwindPlanForFirstFrameIfInvalid(abi); return true; unwind_done: Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); if (log) { LLDB_LOGF(log, "th%d Unwind of this thread is complete.", m_thread.GetIndexID()); } m_unwind_complete = true; return false; } UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { assert(m_frames.size() != 0 && "Get one more frame called with empty frame list"); // If we've already gotten to the end of the stack, don't bother to try // again... if (m_unwind_complete) return nullptr; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); CursorSP prev_frame = m_frames.back(); uint32_t cur_idx = m_frames.size(); CursorSP cursor_sp(new Cursor()); RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth(); // We want to detect an unwind that cycles erroneously and stop backtracing. // Don't want this maximum unwind limit to be too low -- if you have a // backtrace with an "infinitely recursing" bug, it will crash when the stack // blows out and the first 35,000 frames are uninteresting - it's the top // most 5 frames that you actually care about. So you can't just cap the // unwind at 10,000 or something. Realistically anything over around 200,000 // is going to blow out the stack space. If we're still unwinding at that // point, we're probably never going to finish. if (cur_idx >= max_stack_depth) { LLDB_LOGF(log, "%*sFrame %d unwound too many frames, assuming unwind has " "gone astray, stopping.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (reg_ctx_sp.get() == nullptr) { // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to // that and return true. Subsequent calls to TryFallbackUnwindPlan() will // return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // TryFallbackUnwindPlan for prev_frame succeeded and updated // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame // still needs to be updated. Hence updating it. if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) return nullptr; return GetOneMoreFrame(abi); } LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (!reg_ctx_sp->IsValid()) { // 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 (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // TryFallbackUnwindPlan for prev_frame succeeded and updated // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame // still needs to be updated. Hence updating it. if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) return nullptr; return GetOneMoreFrame(abi); } LLDB_LOGF(log, "%*sFrame %d invalid RegisterContext for this frame, " "stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to // that and return true. Subsequent calls to TryFallbackUnwindPlan() will // return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // TryFallbackUnwindPlan for prev_frame succeeded and updated // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame // still needs to be updated. Hence updating it. if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) return nullptr; return GetOneMoreFrame(abi); } LLDB_LOGF(log, "%*sFrame %d did not get CFA for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { // 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()) { // 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() || !reg_ctx_sp->GetCFA(cursor_sp->cfa) || !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // TryFallbackUnwindPlan for prev_frame succeeded and updated // reg_ctx_lldb_sp field of prev_frame. However, cfa field of // prev_frame still needs to be updated. Hence updating it. if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) return nullptr; return GetOneMoreFrame(abi); } LLDB_LOGF(log, "%*sFrame %d did not get a valid CFA for this frame, " "stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } else { LLDB_LOGF(log, "%*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); } } } if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) { // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to // that and return true. Subsequent calls to TryFallbackUnwindPlan() will // return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // TryFallbackUnwindPlan for prev_frame succeeded and updated // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame // still needs to be updated. Hence updating it. if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) return nullptr; return GetOneMoreFrame(abi); } LLDB_LOGF(log, "%*sFrame %d did not get PC for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to // that and return true. Subsequent calls to TryFallbackUnwindPlan() will // return false. if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // TryFallbackUnwindPlan for prev_frame succeeded and updated // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame // still needs to be updated. Hence updating it. if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) return nullptr; return GetOneMoreFrame(abi); } LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); return nullptr; } // Infinite loop where the current cursor is the same as the previous one... if (prev_frame->start_pc == cursor_sp->start_pc && prev_frame->cfa == cursor_sp->cfa) { LLDB_LOGF(log, "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()); return nullptr; } cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; return cursor_sp; } void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { // This function is called for First Frame only. assert(m_frames.size() == 1 && "No. of cursor frames are not 1"); bool old_m_unwind_complete = m_unwind_complete; CursorSP old_m_candidate_frame = m_candidate_frame; // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update // the cfa of Frame 0 (if required). AddOneMoreFrame(abi); // Remove all the frames added by above function as the purpose of using // above function was just to check whether Unwinder of Frame 0 works or not. for (uint32_t i = 1; i < m_frames.size(); i++) m_frames.pop_back(); // Restore status after calling AddOneMoreFrame m_unwind_complete = old_m_unwind_complete; m_candidate_frame = old_m_candidate_frame; return; } bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); // Frame zero is a little different if (m_frames.empty()) return false; // If we've already gotten to the end of the stack, don't bother to try // again... if (m_unwind_complete) return false; CursorSP new_frame = m_candidate_frame; if (new_frame == nullptr) new_frame = GetOneMoreFrame(abi); if (new_frame == nullptr) { LLDB_LOGF(log, "th%d Unwind of this thread is complete.", m_thread.GetIndexID()); m_unwind_complete = true; return false; } m_frames.push_back(new_frame); // If we can get one more frame further then accept that we get back a // correct frame. m_candidate_frame = GetOneMoreFrame(abi); if (m_candidate_frame) return true; // We can't go further from the frame returned by GetOneMore frame. Lets try // to get a different frame with using the fallback unwind plan. if (!m_frames[m_frames.size() - 2] ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // We don't have a valid fallback unwind plan. Accept the frame as it is. // This is a valid situation when we are at the bottom of the stack. return true; } // Remove the possibly incorrect frame from the frame list and try to add a // different one with the newly selected fallback unwind plan. m_frames.pop_back(); CursorSP new_frame_v2 = GetOneMoreFrame(abi); if (new_frame_v2 == nullptr) { // We haven't got a new frame from the fallback unwind plan. Accept the // frame from the original unwind plan. This is a valid situation when we // are at the bottom of the stack. m_frames.push_back(new_frame); return true; } // Push the new frame to the list and try to continue from this frame. If we // can get a new frame then accept it as the correct one. m_frames.push_back(new_frame_v2); m_candidate_frame = GetOneMoreFrame(abi); if (m_candidate_frame) { // If control reached here then TryFallbackUnwindPlan had succeeded for // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already // updated during TryFallbackUnwindPlan call above. However, cfa field // still needs to be updated. Hence updating it here and then returning. return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( m_frames[m_frames.size() - 2]->cfa); } // The new frame hasn't helped in unwinding. Fall back to the original one as // the default unwind plan is usually more reliable then the fallback one. m_frames.pop_back(); m_frames.push_back(new_frame); return true; } bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) { if (m_frames.size() == 0) { if (!AddFirstFrame()) return false; } ProcessSP process_sp(m_thread.GetProcess()); ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; while (idx >= m_frames.size() && AddOneMoreFrame(abi)) ; if (idx < m_frames.size()) { cfa = m_frames[idx]->cfa; pc = m_frames[idx]->start_pc; if (idx == 0) { // Frame zero always behaves like it. behaves_like_zeroth_frame = true; } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { // This could be an asynchronous signal, thus the // pc might point to the interrupted instruction rather // than a post-call instruction behaves_like_zeroth_frame = true; } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { // This frame may result from signal processing installing // a pointer to the first byte of a signal-return trampoline // in the return address slot of the frame below, so this // too behaves like the zeroth frame (i.e. the pc might not // be pointing just past a call in it) behaves_like_zeroth_frame = true; } else { behaves_like_zeroth_frame = false; } return true; } return false; } lldb::RegisterContextSP UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) { lldb::RegisterContextSP reg_ctx_sp; uint32_t idx = frame->GetConcreteFrameIndex(); if (idx == 0) { return m_thread.GetRegisterContext(); } if (m_frames.size() == 0) { if (!AddFirstFrame()) return reg_ctx_sp; } ProcessSP process_sp(m_thread.GetProcess()); ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; while (idx >= m_frames.size()) { if (!AddOneMoreFrame(abi)) break; } const uint32_t num_frames = m_frames.size(); if (idx < num_frames) { Cursor *frame_cursor = m_frames[idx].get(); reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; } return reg_ctx_sp; } UnwindLLDB::RegisterContextLLDBSP UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) { RegisterContextLLDBSP reg_ctx_sp; if (frame_num < m_frames.size()) reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; return reg_ctx_sp; } bool UnwindLLDB::SearchForSavedLocationForRegister( uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num, bool pc_reg) { int64_t frame_num = starting_frame_num; if (static_cast(frame_num) >= m_frames.size()) return false; // Never interrogate more than one level while looking for the saved pc // value. If the value isn't saved by frame_num, none of the frames lower on // the stack will have a useful value. if (pc_reg) { UnwindLLDB::RegisterSearchResult result; result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( lldb_regnum, regloc); return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; } while (frame_num >= 0) { 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 // down the stack, or an actual value from a live RegisterContext at frame // 0. if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister && frame_num > 0) { result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound; lldb_regnum = regloc.location.register_number; } if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) return true; if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile) return false; frame_num--; } return false; }