1*5ffd83dbSDimitry Andric //===-- UnwindLLDB.cpp ----------------------------------------------------===// 2*5ffd83dbSDimitry Andric // 3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5ffd83dbSDimitry Andric // 7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 8*5ffd83dbSDimitry Andric 9*5ffd83dbSDimitry Andric #include "lldb/Target/UnwindLLDB.h" 10*5ffd83dbSDimitry Andric #include "lldb/Core/Module.h" 11*5ffd83dbSDimitry Andric #include "lldb/Symbol/FuncUnwinders.h" 12*5ffd83dbSDimitry Andric #include "lldb/Symbol/Function.h" 13*5ffd83dbSDimitry Andric #include "lldb/Symbol/UnwindPlan.h" 14*5ffd83dbSDimitry Andric #include "lldb/Target/ABI.h" 15*5ffd83dbSDimitry Andric #include "lldb/Target/Process.h" 16*5ffd83dbSDimitry Andric #include "lldb/Target/RegisterContext.h" 17*5ffd83dbSDimitry Andric #include "lldb/Target/RegisterContextUnwind.h" 18*5ffd83dbSDimitry Andric #include "lldb/Target/Target.h" 19*5ffd83dbSDimitry Andric #include "lldb/Target/Thread.h" 20*5ffd83dbSDimitry Andric #include "lldb/Utility/Log.h" 21*5ffd83dbSDimitry Andric 22*5ffd83dbSDimitry Andric using namespace lldb; 23*5ffd83dbSDimitry Andric using namespace lldb_private; 24*5ffd83dbSDimitry Andric 25*5ffd83dbSDimitry Andric UnwindLLDB::UnwindLLDB(Thread &thread) 26*5ffd83dbSDimitry Andric : Unwind(thread), m_frames(), m_unwind_complete(false), 27*5ffd83dbSDimitry Andric m_user_supplied_trap_handler_functions() { 28*5ffd83dbSDimitry Andric ProcessSP process_sp(thread.GetProcess()); 29*5ffd83dbSDimitry Andric if (process_sp) { 30*5ffd83dbSDimitry Andric Args args; 31*5ffd83dbSDimitry Andric process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args); 32*5ffd83dbSDimitry Andric size_t count = args.GetArgumentCount(); 33*5ffd83dbSDimitry Andric for (size_t i = 0; i < count; i++) { 34*5ffd83dbSDimitry Andric const char *func_name = args.GetArgumentAtIndex(i); 35*5ffd83dbSDimitry Andric m_user_supplied_trap_handler_functions.push_back(ConstString(func_name)); 36*5ffd83dbSDimitry Andric } 37*5ffd83dbSDimitry Andric } 38*5ffd83dbSDimitry Andric } 39*5ffd83dbSDimitry Andric 40*5ffd83dbSDimitry Andric uint32_t UnwindLLDB::DoGetFrameCount() { 41*5ffd83dbSDimitry Andric if (!m_unwind_complete) { 42*5ffd83dbSDimitry Andric //#define DEBUG_FRAME_SPEED 1 43*5ffd83dbSDimitry Andric #if DEBUG_FRAME_SPEED 44*5ffd83dbSDimitry Andric #define FRAME_COUNT 10000 45*5ffd83dbSDimitry Andric using namespace std::chrono; 46*5ffd83dbSDimitry Andric auto time_value = steady_clock::now(); 47*5ffd83dbSDimitry Andric #endif 48*5ffd83dbSDimitry Andric if (!AddFirstFrame()) 49*5ffd83dbSDimitry Andric return 0; 50*5ffd83dbSDimitry Andric 51*5ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 52*5ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 53*5ffd83dbSDimitry Andric 54*5ffd83dbSDimitry Andric while (AddOneMoreFrame(abi)) { 55*5ffd83dbSDimitry Andric #if DEBUG_FRAME_SPEED 56*5ffd83dbSDimitry Andric if ((m_frames.size() % FRAME_COUNT) == 0) { 57*5ffd83dbSDimitry Andric const auto now = steady_clock::now(); 58*5ffd83dbSDimitry Andric const auto delta_t = now - time_value; 59*5ffd83dbSDimitry Andric printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT, 60*5ffd83dbSDimitry Andric duration<double, std::milli>(delta_t).count(), 61*5ffd83dbSDimitry Andric (float)FRAME_COUNT / duration<double>(delta_t).count()); 62*5ffd83dbSDimitry Andric time_value = now; 63*5ffd83dbSDimitry Andric } 64*5ffd83dbSDimitry Andric #endif 65*5ffd83dbSDimitry Andric } 66*5ffd83dbSDimitry Andric } 67*5ffd83dbSDimitry Andric return m_frames.size(); 68*5ffd83dbSDimitry Andric } 69*5ffd83dbSDimitry Andric 70*5ffd83dbSDimitry Andric bool UnwindLLDB::AddFirstFrame() { 71*5ffd83dbSDimitry Andric if (m_frames.size() > 0) 72*5ffd83dbSDimitry Andric return true; 73*5ffd83dbSDimitry Andric 74*5ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 75*5ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 76*5ffd83dbSDimitry Andric 77*5ffd83dbSDimitry Andric // First, set up the 0th (initial) frame 78*5ffd83dbSDimitry Andric CursorSP first_cursor_sp(new Cursor()); 79*5ffd83dbSDimitry Andric RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( 80*5ffd83dbSDimitry Andric m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this)); 81*5ffd83dbSDimitry Andric if (reg_ctx_sp.get() == nullptr) 82*5ffd83dbSDimitry Andric goto unwind_done; 83*5ffd83dbSDimitry Andric 84*5ffd83dbSDimitry Andric if (!reg_ctx_sp->IsValid()) 85*5ffd83dbSDimitry Andric goto unwind_done; 86*5ffd83dbSDimitry Andric 87*5ffd83dbSDimitry Andric if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa)) 88*5ffd83dbSDimitry Andric goto unwind_done; 89*5ffd83dbSDimitry Andric 90*5ffd83dbSDimitry Andric if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc)) 91*5ffd83dbSDimitry Andric goto unwind_done; 92*5ffd83dbSDimitry Andric 93*5ffd83dbSDimitry Andric // Everything checks out, so release the auto pointer value and let the 94*5ffd83dbSDimitry Andric // cursor own it in its shared pointer 95*5ffd83dbSDimitry Andric first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 96*5ffd83dbSDimitry Andric m_frames.push_back(first_cursor_sp); 97*5ffd83dbSDimitry Andric 98*5ffd83dbSDimitry Andric // Update the Full Unwind Plan for this frame if not valid 99*5ffd83dbSDimitry Andric UpdateUnwindPlanForFirstFrameIfInvalid(abi); 100*5ffd83dbSDimitry Andric 101*5ffd83dbSDimitry Andric return true; 102*5ffd83dbSDimitry Andric 103*5ffd83dbSDimitry Andric unwind_done: 104*5ffd83dbSDimitry Andric Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 105*5ffd83dbSDimitry Andric if (log) { 106*5ffd83dbSDimitry Andric LLDB_LOGF(log, "th%d Unwind of this thread is complete.", 107*5ffd83dbSDimitry Andric m_thread.GetIndexID()); 108*5ffd83dbSDimitry Andric } 109*5ffd83dbSDimitry Andric m_unwind_complete = true; 110*5ffd83dbSDimitry Andric return false; 111*5ffd83dbSDimitry Andric } 112*5ffd83dbSDimitry Andric 113*5ffd83dbSDimitry Andric UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { 114*5ffd83dbSDimitry Andric assert(m_frames.size() != 0 && 115*5ffd83dbSDimitry Andric "Get one more frame called with empty frame list"); 116*5ffd83dbSDimitry Andric 117*5ffd83dbSDimitry Andric // If we've already gotten to the end of the stack, don't bother to try 118*5ffd83dbSDimitry Andric // again... 119*5ffd83dbSDimitry Andric if (m_unwind_complete) 120*5ffd83dbSDimitry Andric return nullptr; 121*5ffd83dbSDimitry Andric 122*5ffd83dbSDimitry Andric Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 123*5ffd83dbSDimitry Andric 124*5ffd83dbSDimitry Andric CursorSP prev_frame = m_frames.back(); 125*5ffd83dbSDimitry Andric uint32_t cur_idx = m_frames.size(); 126*5ffd83dbSDimitry Andric 127*5ffd83dbSDimitry Andric CursorSP cursor_sp(new Cursor()); 128*5ffd83dbSDimitry Andric RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( 129*5ffd83dbSDimitry Andric m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); 130*5ffd83dbSDimitry Andric 131*5ffd83dbSDimitry Andric uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth(); 132*5ffd83dbSDimitry Andric 133*5ffd83dbSDimitry Andric // We want to detect an unwind that cycles erroneously and stop backtracing. 134*5ffd83dbSDimitry Andric // Don't want this maximum unwind limit to be too low -- if you have a 135*5ffd83dbSDimitry Andric // backtrace with an "infinitely recursing" bug, it will crash when the stack 136*5ffd83dbSDimitry Andric // blows out and the first 35,000 frames are uninteresting - it's the top 137*5ffd83dbSDimitry Andric // most 5 frames that you actually care about. So you can't just cap the 138*5ffd83dbSDimitry Andric // unwind at 10,000 or something. Realistically anything over around 200,000 139*5ffd83dbSDimitry Andric // is going to blow out the stack space. If we're still unwinding at that 140*5ffd83dbSDimitry Andric // point, we're probably never going to finish. 141*5ffd83dbSDimitry Andric if (cur_idx >= max_stack_depth) { 142*5ffd83dbSDimitry Andric LLDB_LOGF(log, 143*5ffd83dbSDimitry Andric "%*sFrame %d unwound too many frames, assuming unwind has " 144*5ffd83dbSDimitry Andric "gone astray, stopping.", 145*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 146*5ffd83dbSDimitry Andric return nullptr; 147*5ffd83dbSDimitry Andric } 148*5ffd83dbSDimitry Andric 149*5ffd83dbSDimitry Andric if (reg_ctx_sp.get() == nullptr) { 150*5ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 151*5ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 152*5ffd83dbSDimitry Andric // return false. 153*5ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 154*5ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 155*5ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 156*5ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 157*5ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 158*5ffd83dbSDimitry Andric return nullptr; 159*5ffd83dbSDimitry Andric 160*5ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 161*5ffd83dbSDimitry Andric } 162*5ffd83dbSDimitry Andric 163*5ffd83dbSDimitry Andric LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.", 164*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 165*5ffd83dbSDimitry Andric return nullptr; 166*5ffd83dbSDimitry Andric } 167*5ffd83dbSDimitry Andric 168*5ffd83dbSDimitry Andric if (!reg_ctx_sp->IsValid()) { 169*5ffd83dbSDimitry Andric // We failed to get a valid RegisterContext. See if the regctx below this 170*5ffd83dbSDimitry Andric // on the stack has a fallback unwind plan it can use. Subsequent calls to 171*5ffd83dbSDimitry Andric // TryFallbackUnwindPlan() will return false. 172*5ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 173*5ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 174*5ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 175*5ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 176*5ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 177*5ffd83dbSDimitry Andric return nullptr; 178*5ffd83dbSDimitry Andric 179*5ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 180*5ffd83dbSDimitry Andric } 181*5ffd83dbSDimitry Andric 182*5ffd83dbSDimitry Andric LLDB_LOGF(log, 183*5ffd83dbSDimitry Andric "%*sFrame %d invalid RegisterContext for this frame, " 184*5ffd83dbSDimitry Andric "stopping stack walk", 185*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 186*5ffd83dbSDimitry Andric return nullptr; 187*5ffd83dbSDimitry Andric } 188*5ffd83dbSDimitry Andric if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { 189*5ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 190*5ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 191*5ffd83dbSDimitry Andric // return false. 192*5ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 193*5ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 194*5ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 195*5ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 196*5ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 197*5ffd83dbSDimitry Andric return nullptr; 198*5ffd83dbSDimitry Andric 199*5ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 200*5ffd83dbSDimitry Andric } 201*5ffd83dbSDimitry Andric 202*5ffd83dbSDimitry Andric LLDB_LOGF(log, 203*5ffd83dbSDimitry Andric "%*sFrame %d did not get CFA for this frame, stopping stack walk", 204*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 205*5ffd83dbSDimitry Andric return nullptr; 206*5ffd83dbSDimitry Andric } 207*5ffd83dbSDimitry Andric if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { 208*5ffd83dbSDimitry Andric // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not 209*5ffd83dbSDimitry Andric // have its (constructed) CFA aligned correctly -- don't do the abi 210*5ffd83dbSDimitry Andric // alignment check for these. 211*5ffd83dbSDimitry Andric if (!reg_ctx_sp->IsTrapHandlerFrame()) { 212*5ffd83dbSDimitry Andric // See if we can find a fallback unwind plan for THIS frame. It may be 213*5ffd83dbSDimitry Andric // that the UnwindPlan we're using for THIS frame was bad and gave us a 214*5ffd83dbSDimitry Andric // bad CFA. If that's not it, then see if we can change the UnwindPlan 215*5ffd83dbSDimitry Andric // for the frame below us ("NEXT") -- see if using that other UnwindPlan 216*5ffd83dbSDimitry Andric // gets us a better unwind state. 217*5ffd83dbSDimitry Andric if (!reg_ctx_sp->TryFallbackUnwindPlan() || 218*5ffd83dbSDimitry Andric !reg_ctx_sp->GetCFA(cursor_sp->cfa) || 219*5ffd83dbSDimitry Andric !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { 220*5ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 221*5ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 222*5ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of 223*5ffd83dbSDimitry Andric // prev_frame still needs to be updated. Hence updating it. 224*5ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 225*5ffd83dbSDimitry Andric return nullptr; 226*5ffd83dbSDimitry Andric 227*5ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 228*5ffd83dbSDimitry Andric } 229*5ffd83dbSDimitry Andric 230*5ffd83dbSDimitry Andric LLDB_LOGF(log, 231*5ffd83dbSDimitry Andric "%*sFrame %d did not get a valid CFA for this frame, " 232*5ffd83dbSDimitry Andric "stopping stack walk", 233*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 234*5ffd83dbSDimitry Andric return nullptr; 235*5ffd83dbSDimitry Andric } else { 236*5ffd83dbSDimitry Andric LLDB_LOGF(log, 237*5ffd83dbSDimitry Andric "%*sFrame %d had a bad CFA value but we switched the " 238*5ffd83dbSDimitry Andric "UnwindPlan being used and got one that looks more " 239*5ffd83dbSDimitry Andric "realistic.", 240*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 241*5ffd83dbSDimitry Andric } 242*5ffd83dbSDimitry Andric } 243*5ffd83dbSDimitry Andric } 244*5ffd83dbSDimitry Andric if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) { 245*5ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 246*5ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 247*5ffd83dbSDimitry Andric // return false. 248*5ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 249*5ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 250*5ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 251*5ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 252*5ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 253*5ffd83dbSDimitry Andric return nullptr; 254*5ffd83dbSDimitry Andric 255*5ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 256*5ffd83dbSDimitry Andric } 257*5ffd83dbSDimitry Andric 258*5ffd83dbSDimitry Andric LLDB_LOGF(log, 259*5ffd83dbSDimitry Andric "%*sFrame %d did not get PC for this frame, stopping stack walk", 260*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 261*5ffd83dbSDimitry Andric return nullptr; 262*5ffd83dbSDimitry Andric } 263*5ffd83dbSDimitry Andric if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { 264*5ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 265*5ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 266*5ffd83dbSDimitry Andric // return false. 267*5ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 268*5ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 269*5ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 270*5ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 271*5ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 272*5ffd83dbSDimitry Andric return nullptr; 273*5ffd83dbSDimitry Andric 274*5ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 275*5ffd83dbSDimitry Andric } 276*5ffd83dbSDimitry Andric 277*5ffd83dbSDimitry Andric LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk", 278*5ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 279*5ffd83dbSDimitry Andric return nullptr; 280*5ffd83dbSDimitry Andric } 281*5ffd83dbSDimitry Andric // Infinite loop where the current cursor is the same as the previous one... 282*5ffd83dbSDimitry Andric if (prev_frame->start_pc == cursor_sp->start_pc && 283*5ffd83dbSDimitry Andric prev_frame->cfa == cursor_sp->cfa) { 284*5ffd83dbSDimitry Andric LLDB_LOGF(log, 285*5ffd83dbSDimitry Andric "th%d pc of this frame is the same as the previous frame and " 286*5ffd83dbSDimitry Andric "CFAs for both frames are identical -- stopping unwind", 287*5ffd83dbSDimitry Andric m_thread.GetIndexID()); 288*5ffd83dbSDimitry Andric return nullptr; 289*5ffd83dbSDimitry Andric } 290*5ffd83dbSDimitry Andric 291*5ffd83dbSDimitry Andric cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 292*5ffd83dbSDimitry Andric return cursor_sp; 293*5ffd83dbSDimitry Andric } 294*5ffd83dbSDimitry Andric 295*5ffd83dbSDimitry Andric void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { 296*5ffd83dbSDimitry Andric // This function is called for First Frame only. 297*5ffd83dbSDimitry Andric assert(m_frames.size() == 1 && "No. of cursor frames are not 1"); 298*5ffd83dbSDimitry Andric 299*5ffd83dbSDimitry Andric bool old_m_unwind_complete = m_unwind_complete; 300*5ffd83dbSDimitry Andric CursorSP old_m_candidate_frame = m_candidate_frame; 301*5ffd83dbSDimitry Andric 302*5ffd83dbSDimitry Andric // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan 303*5ffd83dbSDimitry Andric // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update 304*5ffd83dbSDimitry Andric // the cfa of Frame 0 (if required). 305*5ffd83dbSDimitry Andric AddOneMoreFrame(abi); 306*5ffd83dbSDimitry Andric 307*5ffd83dbSDimitry Andric // Remove all the frames added by above function as the purpose of using 308*5ffd83dbSDimitry Andric // above function was just to check whether Unwinder of Frame 0 works or not. 309*5ffd83dbSDimitry Andric for (uint32_t i = 1; i < m_frames.size(); i++) 310*5ffd83dbSDimitry Andric m_frames.pop_back(); 311*5ffd83dbSDimitry Andric 312*5ffd83dbSDimitry Andric // Restore status after calling AddOneMoreFrame 313*5ffd83dbSDimitry Andric m_unwind_complete = old_m_unwind_complete; 314*5ffd83dbSDimitry Andric m_candidate_frame = old_m_candidate_frame; 315*5ffd83dbSDimitry Andric return; 316*5ffd83dbSDimitry Andric } 317*5ffd83dbSDimitry Andric 318*5ffd83dbSDimitry Andric bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { 319*5ffd83dbSDimitry Andric Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); 320*5ffd83dbSDimitry Andric 321*5ffd83dbSDimitry Andric // Frame zero is a little different 322*5ffd83dbSDimitry Andric if (m_frames.empty()) 323*5ffd83dbSDimitry Andric return false; 324*5ffd83dbSDimitry Andric 325*5ffd83dbSDimitry Andric // If we've already gotten to the end of the stack, don't bother to try 326*5ffd83dbSDimitry Andric // again... 327*5ffd83dbSDimitry Andric if (m_unwind_complete) 328*5ffd83dbSDimitry Andric return false; 329*5ffd83dbSDimitry Andric 330*5ffd83dbSDimitry Andric CursorSP new_frame = m_candidate_frame; 331*5ffd83dbSDimitry Andric if (new_frame == nullptr) 332*5ffd83dbSDimitry Andric new_frame = GetOneMoreFrame(abi); 333*5ffd83dbSDimitry Andric 334*5ffd83dbSDimitry Andric if (new_frame == nullptr) { 335*5ffd83dbSDimitry Andric LLDB_LOGF(log, "th%d Unwind of this thread is complete.", 336*5ffd83dbSDimitry Andric m_thread.GetIndexID()); 337*5ffd83dbSDimitry Andric m_unwind_complete = true; 338*5ffd83dbSDimitry Andric return false; 339*5ffd83dbSDimitry Andric } 340*5ffd83dbSDimitry Andric 341*5ffd83dbSDimitry Andric m_frames.push_back(new_frame); 342*5ffd83dbSDimitry Andric 343*5ffd83dbSDimitry Andric // If we can get one more frame further then accept that we get back a 344*5ffd83dbSDimitry Andric // correct frame. 345*5ffd83dbSDimitry Andric m_candidate_frame = GetOneMoreFrame(abi); 346*5ffd83dbSDimitry Andric if (m_candidate_frame) 347*5ffd83dbSDimitry Andric return true; 348*5ffd83dbSDimitry Andric 349*5ffd83dbSDimitry Andric // We can't go further from the frame returned by GetOneMore frame. Lets try 350*5ffd83dbSDimitry Andric // to get a different frame with using the fallback unwind plan. 351*5ffd83dbSDimitry Andric if (!m_frames[m_frames.size() - 2] 352*5ffd83dbSDimitry Andric ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 353*5ffd83dbSDimitry Andric // We don't have a valid fallback unwind plan. Accept the frame as it is. 354*5ffd83dbSDimitry Andric // This is a valid situation when we are at the bottom of the stack. 355*5ffd83dbSDimitry Andric return true; 356*5ffd83dbSDimitry Andric } 357*5ffd83dbSDimitry Andric 358*5ffd83dbSDimitry Andric // Remove the possibly incorrect frame from the frame list and try to add a 359*5ffd83dbSDimitry Andric // different one with the newly selected fallback unwind plan. 360*5ffd83dbSDimitry Andric m_frames.pop_back(); 361*5ffd83dbSDimitry Andric CursorSP new_frame_v2 = GetOneMoreFrame(abi); 362*5ffd83dbSDimitry Andric if (new_frame_v2 == nullptr) { 363*5ffd83dbSDimitry Andric // We haven't got a new frame from the fallback unwind plan. Accept the 364*5ffd83dbSDimitry Andric // frame from the original unwind plan. This is a valid situation when we 365*5ffd83dbSDimitry Andric // are at the bottom of the stack. 366*5ffd83dbSDimitry Andric m_frames.push_back(new_frame); 367*5ffd83dbSDimitry Andric return true; 368*5ffd83dbSDimitry Andric } 369*5ffd83dbSDimitry Andric 370*5ffd83dbSDimitry Andric // Push the new frame to the list and try to continue from this frame. If we 371*5ffd83dbSDimitry Andric // can get a new frame then accept it as the correct one. 372*5ffd83dbSDimitry Andric m_frames.push_back(new_frame_v2); 373*5ffd83dbSDimitry Andric m_candidate_frame = GetOneMoreFrame(abi); 374*5ffd83dbSDimitry Andric if (m_candidate_frame) { 375*5ffd83dbSDimitry Andric // If control reached here then TryFallbackUnwindPlan had succeeded for 376*5ffd83dbSDimitry Andric // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next 377*5ffd83dbSDimitry Andric // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For 378*5ffd83dbSDimitry Andric // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already 379*5ffd83dbSDimitry Andric // updated during TryFallbackUnwindPlan call above. However, cfa field 380*5ffd83dbSDimitry Andric // still needs to be updated. Hence updating it here and then returning. 381*5ffd83dbSDimitry Andric return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( 382*5ffd83dbSDimitry Andric m_frames[m_frames.size() - 2]->cfa); 383*5ffd83dbSDimitry Andric } 384*5ffd83dbSDimitry Andric 385*5ffd83dbSDimitry Andric // The new frame hasn't helped in unwinding. Fall back to the original one as 386*5ffd83dbSDimitry Andric // the default unwind plan is usually more reliable then the fallback one. 387*5ffd83dbSDimitry Andric m_frames.pop_back(); 388*5ffd83dbSDimitry Andric m_frames.push_back(new_frame); 389*5ffd83dbSDimitry Andric return true; 390*5ffd83dbSDimitry Andric } 391*5ffd83dbSDimitry Andric 392*5ffd83dbSDimitry Andric bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, 393*5ffd83dbSDimitry Andric bool &behaves_like_zeroth_frame) { 394*5ffd83dbSDimitry Andric if (m_frames.size() == 0) { 395*5ffd83dbSDimitry Andric if (!AddFirstFrame()) 396*5ffd83dbSDimitry Andric return false; 397*5ffd83dbSDimitry Andric } 398*5ffd83dbSDimitry Andric 399*5ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 400*5ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 401*5ffd83dbSDimitry Andric 402*5ffd83dbSDimitry Andric while (idx >= m_frames.size() && AddOneMoreFrame(abi)) 403*5ffd83dbSDimitry Andric ; 404*5ffd83dbSDimitry Andric 405*5ffd83dbSDimitry Andric if (idx < m_frames.size()) { 406*5ffd83dbSDimitry Andric cfa = m_frames[idx]->cfa; 407*5ffd83dbSDimitry Andric pc = m_frames[idx]->start_pc; 408*5ffd83dbSDimitry Andric if (idx == 0) { 409*5ffd83dbSDimitry Andric // Frame zero always behaves like it. 410*5ffd83dbSDimitry Andric behaves_like_zeroth_frame = true; 411*5ffd83dbSDimitry Andric } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { 412*5ffd83dbSDimitry Andric // This could be an asynchronous signal, thus the 413*5ffd83dbSDimitry Andric // pc might point to the interrupted instruction rather 414*5ffd83dbSDimitry Andric // than a post-call instruction 415*5ffd83dbSDimitry Andric behaves_like_zeroth_frame = true; 416*5ffd83dbSDimitry Andric } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { 417*5ffd83dbSDimitry Andric // This frame may result from signal processing installing 418*5ffd83dbSDimitry Andric // a pointer to the first byte of a signal-return trampoline 419*5ffd83dbSDimitry Andric // in the return address slot of the frame below, so this 420*5ffd83dbSDimitry Andric // too behaves like the zeroth frame (i.e. the pc might not 421*5ffd83dbSDimitry Andric // be pointing just past a call in it) 422*5ffd83dbSDimitry Andric behaves_like_zeroth_frame = true; 423*5ffd83dbSDimitry Andric } else { 424*5ffd83dbSDimitry Andric behaves_like_zeroth_frame = false; 425*5ffd83dbSDimitry Andric } 426*5ffd83dbSDimitry Andric return true; 427*5ffd83dbSDimitry Andric } 428*5ffd83dbSDimitry Andric return false; 429*5ffd83dbSDimitry Andric } 430*5ffd83dbSDimitry Andric 431*5ffd83dbSDimitry Andric lldb::RegisterContextSP 432*5ffd83dbSDimitry Andric UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) { 433*5ffd83dbSDimitry Andric lldb::RegisterContextSP reg_ctx_sp; 434*5ffd83dbSDimitry Andric uint32_t idx = frame->GetConcreteFrameIndex(); 435*5ffd83dbSDimitry Andric 436*5ffd83dbSDimitry Andric if (idx == 0) { 437*5ffd83dbSDimitry Andric return m_thread.GetRegisterContext(); 438*5ffd83dbSDimitry Andric } 439*5ffd83dbSDimitry Andric 440*5ffd83dbSDimitry Andric if (m_frames.size() == 0) { 441*5ffd83dbSDimitry Andric if (!AddFirstFrame()) 442*5ffd83dbSDimitry Andric return reg_ctx_sp; 443*5ffd83dbSDimitry Andric } 444*5ffd83dbSDimitry Andric 445*5ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 446*5ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 447*5ffd83dbSDimitry Andric 448*5ffd83dbSDimitry Andric while (idx >= m_frames.size()) { 449*5ffd83dbSDimitry Andric if (!AddOneMoreFrame(abi)) 450*5ffd83dbSDimitry Andric break; 451*5ffd83dbSDimitry Andric } 452*5ffd83dbSDimitry Andric 453*5ffd83dbSDimitry Andric const uint32_t num_frames = m_frames.size(); 454*5ffd83dbSDimitry Andric if (idx < num_frames) { 455*5ffd83dbSDimitry Andric Cursor *frame_cursor = m_frames[idx].get(); 456*5ffd83dbSDimitry Andric reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; 457*5ffd83dbSDimitry Andric } 458*5ffd83dbSDimitry Andric return reg_ctx_sp; 459*5ffd83dbSDimitry Andric } 460*5ffd83dbSDimitry Andric 461*5ffd83dbSDimitry Andric UnwindLLDB::RegisterContextLLDBSP 462*5ffd83dbSDimitry Andric UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) { 463*5ffd83dbSDimitry Andric RegisterContextLLDBSP reg_ctx_sp; 464*5ffd83dbSDimitry Andric if (frame_num < m_frames.size()) 465*5ffd83dbSDimitry Andric reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; 466*5ffd83dbSDimitry Andric return reg_ctx_sp; 467*5ffd83dbSDimitry Andric } 468*5ffd83dbSDimitry Andric 469*5ffd83dbSDimitry Andric bool UnwindLLDB::SearchForSavedLocationForRegister( 470*5ffd83dbSDimitry Andric uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, 471*5ffd83dbSDimitry Andric uint32_t starting_frame_num, bool pc_reg) { 472*5ffd83dbSDimitry Andric int64_t frame_num = starting_frame_num; 473*5ffd83dbSDimitry Andric if (static_cast<size_t>(frame_num) >= m_frames.size()) 474*5ffd83dbSDimitry Andric return false; 475*5ffd83dbSDimitry Andric 476*5ffd83dbSDimitry Andric // Never interrogate more than one level while looking for the saved pc 477*5ffd83dbSDimitry Andric // value. If the value isn't saved by frame_num, none of the frames lower on 478*5ffd83dbSDimitry Andric // the stack will have a useful value. 479*5ffd83dbSDimitry Andric if (pc_reg) { 480*5ffd83dbSDimitry Andric UnwindLLDB::RegisterSearchResult result; 481*5ffd83dbSDimitry Andric result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 482*5ffd83dbSDimitry Andric lldb_regnum, regloc); 483*5ffd83dbSDimitry Andric return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; 484*5ffd83dbSDimitry Andric } 485*5ffd83dbSDimitry Andric while (frame_num >= 0) { 486*5ffd83dbSDimitry Andric UnwindLLDB::RegisterSearchResult result; 487*5ffd83dbSDimitry Andric result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 488*5ffd83dbSDimitry Andric lldb_regnum, regloc); 489*5ffd83dbSDimitry Andric 490*5ffd83dbSDimitry Andric // We descended down to the live register context aka stack frame 0 and are 491*5ffd83dbSDimitry Andric // reading the value out of a live register. 492*5ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 493*5ffd83dbSDimitry Andric regloc.type == 494*5ffd83dbSDimitry Andric UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) { 495*5ffd83dbSDimitry Andric return true; 496*5ffd83dbSDimitry Andric } 497*5ffd83dbSDimitry Andric 498*5ffd83dbSDimitry Andric // If we have unwind instructions saying that register N is saved in 499*5ffd83dbSDimitry Andric // register M in the middle of the stack (and N can equal M here, meaning 500*5ffd83dbSDimitry Andric // the register was not used in this function), then change the register 501*5ffd83dbSDimitry Andric // number we're looking for to M and keep looking for a concrete location 502*5ffd83dbSDimitry Andric // down the stack, or an actual value from a live RegisterContext at frame 503*5ffd83dbSDimitry Andric // 0. 504*5ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 505*5ffd83dbSDimitry Andric regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister && 506*5ffd83dbSDimitry Andric frame_num > 0) { 507*5ffd83dbSDimitry Andric result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 508*5ffd83dbSDimitry Andric lldb_regnum = regloc.location.register_number; 509*5ffd83dbSDimitry Andric } 510*5ffd83dbSDimitry Andric 511*5ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) 512*5ffd83dbSDimitry Andric return true; 513*5ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile) 514*5ffd83dbSDimitry Andric return false; 515*5ffd83dbSDimitry Andric frame_num--; 516*5ffd83dbSDimitry Andric } 517*5ffd83dbSDimitry Andric return false; 518*5ffd83dbSDimitry Andric } 519