15ffd83dbSDimitry Andric //===-- UnwindLLDB.cpp ----------------------------------------------------===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric 95ffd83dbSDimitry Andric #include "lldb/Target/UnwindLLDB.h" 105ffd83dbSDimitry Andric #include "lldb/Core/Module.h" 115ffd83dbSDimitry Andric #include "lldb/Symbol/FuncUnwinders.h" 125ffd83dbSDimitry Andric #include "lldb/Symbol/Function.h" 135ffd83dbSDimitry Andric #include "lldb/Symbol/UnwindPlan.h" 145ffd83dbSDimitry Andric #include "lldb/Target/ABI.h" 155ffd83dbSDimitry Andric #include "lldb/Target/Process.h" 165ffd83dbSDimitry Andric #include "lldb/Target/RegisterContext.h" 175ffd83dbSDimitry Andric #include "lldb/Target/RegisterContextUnwind.h" 185ffd83dbSDimitry Andric #include "lldb/Target/Target.h" 195ffd83dbSDimitry Andric #include "lldb/Target/Thread.h" 2081ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 215ffd83dbSDimitry Andric #include "lldb/Utility/Log.h" 225ffd83dbSDimitry Andric 235ffd83dbSDimitry Andric using namespace lldb; 245ffd83dbSDimitry Andric using namespace lldb_private; 255ffd83dbSDimitry Andric 265ffd83dbSDimitry Andric UnwindLLDB::UnwindLLDB(Thread &thread) 275ffd83dbSDimitry Andric : Unwind(thread), m_frames(), m_unwind_complete(false), 285ffd83dbSDimitry Andric m_user_supplied_trap_handler_functions() { 295ffd83dbSDimitry Andric ProcessSP process_sp(thread.GetProcess()); 305ffd83dbSDimitry Andric if (process_sp) { 315ffd83dbSDimitry Andric Args args; 325ffd83dbSDimitry Andric process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args); 335ffd83dbSDimitry Andric size_t count = args.GetArgumentCount(); 345ffd83dbSDimitry Andric for (size_t i = 0; i < count; i++) { 355ffd83dbSDimitry Andric const char *func_name = args.GetArgumentAtIndex(i); 365ffd83dbSDimitry Andric m_user_supplied_trap_handler_functions.push_back(ConstString(func_name)); 375ffd83dbSDimitry Andric } 385ffd83dbSDimitry Andric } 395ffd83dbSDimitry Andric } 405ffd83dbSDimitry Andric 415ffd83dbSDimitry Andric uint32_t UnwindLLDB::DoGetFrameCount() { 425ffd83dbSDimitry Andric if (!m_unwind_complete) { 435ffd83dbSDimitry Andric //#define DEBUG_FRAME_SPEED 1 445ffd83dbSDimitry Andric #if DEBUG_FRAME_SPEED 455ffd83dbSDimitry Andric #define FRAME_COUNT 10000 465ffd83dbSDimitry Andric using namespace std::chrono; 475ffd83dbSDimitry Andric auto time_value = steady_clock::now(); 485ffd83dbSDimitry Andric #endif 495ffd83dbSDimitry Andric if (!AddFirstFrame()) 505ffd83dbSDimitry Andric return 0; 515ffd83dbSDimitry Andric 525ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 535ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 545ffd83dbSDimitry Andric 555ffd83dbSDimitry Andric while (AddOneMoreFrame(abi)) { 565ffd83dbSDimitry Andric #if DEBUG_FRAME_SPEED 575ffd83dbSDimitry Andric if ((m_frames.size() % FRAME_COUNT) == 0) { 585ffd83dbSDimitry Andric const auto now = steady_clock::now(); 595ffd83dbSDimitry Andric const auto delta_t = now - time_value; 605ffd83dbSDimitry Andric printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT, 615ffd83dbSDimitry Andric duration<double, std::milli>(delta_t).count(), 625ffd83dbSDimitry Andric (float)FRAME_COUNT / duration<double>(delta_t).count()); 635ffd83dbSDimitry Andric time_value = now; 645ffd83dbSDimitry Andric } 655ffd83dbSDimitry Andric #endif 665ffd83dbSDimitry Andric } 675ffd83dbSDimitry Andric } 685ffd83dbSDimitry Andric return m_frames.size(); 695ffd83dbSDimitry Andric } 705ffd83dbSDimitry Andric 715ffd83dbSDimitry Andric bool UnwindLLDB::AddFirstFrame() { 725ffd83dbSDimitry Andric if (m_frames.size() > 0) 735ffd83dbSDimitry Andric return true; 745ffd83dbSDimitry Andric 755ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 765ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 775ffd83dbSDimitry Andric 785ffd83dbSDimitry Andric // First, set up the 0th (initial) frame 795ffd83dbSDimitry Andric CursorSP first_cursor_sp(new Cursor()); 805ffd83dbSDimitry Andric RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( 815ffd83dbSDimitry Andric m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this)); 825ffd83dbSDimitry Andric if (reg_ctx_sp.get() == nullptr) 835ffd83dbSDimitry Andric goto unwind_done; 845ffd83dbSDimitry Andric 855ffd83dbSDimitry Andric if (!reg_ctx_sp->IsValid()) 865ffd83dbSDimitry Andric goto unwind_done; 875ffd83dbSDimitry Andric 885ffd83dbSDimitry Andric if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa)) 895ffd83dbSDimitry Andric goto unwind_done; 905ffd83dbSDimitry Andric 915ffd83dbSDimitry Andric if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc)) 925ffd83dbSDimitry Andric goto unwind_done; 935ffd83dbSDimitry Andric 945ffd83dbSDimitry Andric // Everything checks out, so release the auto pointer value and let the 955ffd83dbSDimitry Andric // cursor own it in its shared pointer 965ffd83dbSDimitry Andric first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 975ffd83dbSDimitry Andric m_frames.push_back(first_cursor_sp); 985ffd83dbSDimitry Andric 995ffd83dbSDimitry Andric // Update the Full Unwind Plan for this frame if not valid 1005ffd83dbSDimitry Andric UpdateUnwindPlanForFirstFrameIfInvalid(abi); 1015ffd83dbSDimitry Andric 1025ffd83dbSDimitry Andric return true; 1035ffd83dbSDimitry Andric 1045ffd83dbSDimitry Andric unwind_done: 10581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Unwind); 1065ffd83dbSDimitry Andric if (log) { 1075ffd83dbSDimitry Andric LLDB_LOGF(log, "th%d Unwind of this thread is complete.", 1085ffd83dbSDimitry Andric m_thread.GetIndexID()); 1095ffd83dbSDimitry Andric } 1105ffd83dbSDimitry Andric m_unwind_complete = true; 1115ffd83dbSDimitry Andric return false; 1125ffd83dbSDimitry Andric } 1135ffd83dbSDimitry Andric 1145ffd83dbSDimitry Andric UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { 1155ffd83dbSDimitry Andric assert(m_frames.size() != 0 && 1165ffd83dbSDimitry Andric "Get one more frame called with empty frame list"); 1175ffd83dbSDimitry Andric 1185ffd83dbSDimitry Andric // If we've already gotten to the end of the stack, don't bother to try 1195ffd83dbSDimitry Andric // again... 1205ffd83dbSDimitry Andric if (m_unwind_complete) 1215ffd83dbSDimitry Andric return nullptr; 1225ffd83dbSDimitry Andric 12381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Unwind); 1245ffd83dbSDimitry Andric 1255ffd83dbSDimitry Andric CursorSP prev_frame = m_frames.back(); 1265ffd83dbSDimitry Andric uint32_t cur_idx = m_frames.size(); 1275ffd83dbSDimitry Andric 1285ffd83dbSDimitry Andric CursorSP cursor_sp(new Cursor()); 1295ffd83dbSDimitry Andric RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( 1305ffd83dbSDimitry Andric m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); 1315ffd83dbSDimitry Andric 1325ffd83dbSDimitry Andric uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth(); 1335ffd83dbSDimitry Andric 1345ffd83dbSDimitry Andric // We want to detect an unwind that cycles erroneously and stop backtracing. 1355ffd83dbSDimitry Andric // Don't want this maximum unwind limit to be too low -- if you have a 1365ffd83dbSDimitry Andric // backtrace with an "infinitely recursing" bug, it will crash when the stack 1375ffd83dbSDimitry Andric // blows out and the first 35,000 frames are uninteresting - it's the top 1385ffd83dbSDimitry Andric // most 5 frames that you actually care about. So you can't just cap the 1395ffd83dbSDimitry Andric // unwind at 10,000 or something. Realistically anything over around 200,000 1405ffd83dbSDimitry Andric // is going to blow out the stack space. If we're still unwinding at that 1415ffd83dbSDimitry Andric // point, we're probably never going to finish. 1425ffd83dbSDimitry Andric if (cur_idx >= max_stack_depth) { 1435ffd83dbSDimitry Andric LLDB_LOGF(log, 1445ffd83dbSDimitry Andric "%*sFrame %d unwound too many frames, assuming unwind has " 1455ffd83dbSDimitry Andric "gone astray, stopping.", 1465ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 1475ffd83dbSDimitry Andric return nullptr; 1485ffd83dbSDimitry Andric } 1495ffd83dbSDimitry Andric 1505ffd83dbSDimitry Andric if (reg_ctx_sp.get() == nullptr) { 1515ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 1525ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 1535ffd83dbSDimitry Andric // return false. 1545ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 1555ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 1565ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 1575ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 1585ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 1595ffd83dbSDimitry Andric return nullptr; 1605ffd83dbSDimitry Andric 1615ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 1625ffd83dbSDimitry Andric } 1635ffd83dbSDimitry Andric 1645ffd83dbSDimitry Andric LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.", 1655ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 1665ffd83dbSDimitry Andric return nullptr; 1675ffd83dbSDimitry Andric } 1685ffd83dbSDimitry Andric 1695ffd83dbSDimitry Andric if (!reg_ctx_sp->IsValid()) { 1705ffd83dbSDimitry Andric // We failed to get a valid RegisterContext. See if the regctx below this 1715ffd83dbSDimitry Andric // on the stack has a fallback unwind plan it can use. Subsequent calls to 1725ffd83dbSDimitry Andric // TryFallbackUnwindPlan() will return false. 1735ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 1745ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 1755ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 1765ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 1775ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 1785ffd83dbSDimitry Andric return nullptr; 1795ffd83dbSDimitry Andric 1805ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 1815ffd83dbSDimitry Andric } 1825ffd83dbSDimitry Andric 1835ffd83dbSDimitry Andric LLDB_LOGF(log, 1845ffd83dbSDimitry Andric "%*sFrame %d invalid RegisterContext for this frame, " 1855ffd83dbSDimitry Andric "stopping stack walk", 1865ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 1875ffd83dbSDimitry Andric return nullptr; 1885ffd83dbSDimitry Andric } 1895ffd83dbSDimitry Andric if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { 1905ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 1915ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 1925ffd83dbSDimitry Andric // return false. 1935ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 1945ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 1955ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 1965ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 1975ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 1985ffd83dbSDimitry Andric return nullptr; 1995ffd83dbSDimitry Andric 2005ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 2015ffd83dbSDimitry Andric } 2025ffd83dbSDimitry Andric 2035ffd83dbSDimitry Andric LLDB_LOGF(log, 2045ffd83dbSDimitry Andric "%*sFrame %d did not get CFA for this frame, stopping stack walk", 2055ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 2065ffd83dbSDimitry Andric return nullptr; 2075ffd83dbSDimitry Andric } 2085ffd83dbSDimitry Andric if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { 2095ffd83dbSDimitry Andric // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not 2105ffd83dbSDimitry Andric // have its (constructed) CFA aligned correctly -- don't do the abi 2115ffd83dbSDimitry Andric // alignment check for these. 2125ffd83dbSDimitry Andric if (!reg_ctx_sp->IsTrapHandlerFrame()) { 2135ffd83dbSDimitry Andric // See if we can find a fallback unwind plan for THIS frame. It may be 2145ffd83dbSDimitry Andric // that the UnwindPlan we're using for THIS frame was bad and gave us a 2155ffd83dbSDimitry Andric // bad CFA. If that's not it, then see if we can change the UnwindPlan 2165ffd83dbSDimitry Andric // for the frame below us ("NEXT") -- see if using that other UnwindPlan 2175ffd83dbSDimitry Andric // gets us a better unwind state. 2185ffd83dbSDimitry Andric if (!reg_ctx_sp->TryFallbackUnwindPlan() || 2195ffd83dbSDimitry Andric !reg_ctx_sp->GetCFA(cursor_sp->cfa) || 2205ffd83dbSDimitry Andric !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { 2215ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 2225ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 2235ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of 2245ffd83dbSDimitry Andric // prev_frame still needs to be updated. Hence updating it. 2255ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 2265ffd83dbSDimitry Andric return nullptr; 2275ffd83dbSDimitry Andric 2285ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 2295ffd83dbSDimitry Andric } 2305ffd83dbSDimitry Andric 2315ffd83dbSDimitry Andric LLDB_LOGF(log, 2325ffd83dbSDimitry Andric "%*sFrame %d did not get a valid CFA for this frame, " 2335ffd83dbSDimitry Andric "stopping stack walk", 2345ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 2355ffd83dbSDimitry Andric return nullptr; 2365ffd83dbSDimitry Andric } else { 2375ffd83dbSDimitry Andric LLDB_LOGF(log, 2385ffd83dbSDimitry Andric "%*sFrame %d had a bad CFA value but we switched the " 2395ffd83dbSDimitry Andric "UnwindPlan being used and got one that looks more " 2405ffd83dbSDimitry Andric "realistic.", 2415ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 2425ffd83dbSDimitry Andric } 2435ffd83dbSDimitry Andric } 2445ffd83dbSDimitry Andric } 2455ffd83dbSDimitry Andric if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) { 2465ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 2475ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 2485ffd83dbSDimitry Andric // return false. 2495ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 2505ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 2515ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 2525ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 2535ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 2545ffd83dbSDimitry Andric return nullptr; 2555ffd83dbSDimitry Andric 2565ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 2575ffd83dbSDimitry Andric } 2585ffd83dbSDimitry Andric 2595ffd83dbSDimitry Andric LLDB_LOGF(log, 2605ffd83dbSDimitry Andric "%*sFrame %d did not get PC for this frame, stopping stack walk", 2615ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 2625ffd83dbSDimitry Andric return nullptr; 2635ffd83dbSDimitry Andric } 264*0fca6ea1SDimitry Andric 265*0fca6ea1SDimitry Andric // Invalid code addresses should not appear on the stack *unless* we're 266*0fca6ea1SDimitry Andric // directly below a trap handler frame (in this case, the invalid address is 267*0fca6ea1SDimitry Andric // likely the cause of the trap). 268*0fca6ea1SDimitry Andric if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc) && 269*0fca6ea1SDimitry Andric !prev_frame->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { 2705ffd83dbSDimitry Andric // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to 2715ffd83dbSDimitry Andric // that and return true. Subsequent calls to TryFallbackUnwindPlan() will 2725ffd83dbSDimitry Andric // return false. 2735ffd83dbSDimitry Andric if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 2745ffd83dbSDimitry Andric // TryFallbackUnwindPlan for prev_frame succeeded and updated 2755ffd83dbSDimitry Andric // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame 2765ffd83dbSDimitry Andric // still needs to be updated. Hence updating it. 2775ffd83dbSDimitry Andric if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) 2785ffd83dbSDimitry Andric return nullptr; 2795ffd83dbSDimitry Andric 2805ffd83dbSDimitry Andric return GetOneMoreFrame(abi); 2815ffd83dbSDimitry Andric } 2825ffd83dbSDimitry Andric 2835ffd83dbSDimitry Andric LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk", 2845ffd83dbSDimitry Andric cur_idx < 100 ? cur_idx : 100, "", cur_idx); 2855ffd83dbSDimitry Andric return nullptr; 2865ffd83dbSDimitry Andric } 2875ffd83dbSDimitry Andric // Infinite loop where the current cursor is the same as the previous one... 2885ffd83dbSDimitry Andric if (prev_frame->start_pc == cursor_sp->start_pc && 2895ffd83dbSDimitry Andric prev_frame->cfa == cursor_sp->cfa) { 2905ffd83dbSDimitry Andric LLDB_LOGF(log, 2915ffd83dbSDimitry Andric "th%d pc of this frame is the same as the previous frame and " 2925ffd83dbSDimitry Andric "CFAs for both frames are identical -- stopping unwind", 2935ffd83dbSDimitry Andric m_thread.GetIndexID()); 2945ffd83dbSDimitry Andric return nullptr; 2955ffd83dbSDimitry Andric } 2965ffd83dbSDimitry Andric 2975ffd83dbSDimitry Andric cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; 2985ffd83dbSDimitry Andric return cursor_sp; 2995ffd83dbSDimitry Andric } 3005ffd83dbSDimitry Andric 3015ffd83dbSDimitry Andric void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { 3025ffd83dbSDimitry Andric // This function is called for First Frame only. 3035ffd83dbSDimitry Andric assert(m_frames.size() == 1 && "No. of cursor frames are not 1"); 3045ffd83dbSDimitry Andric 3055ffd83dbSDimitry Andric bool old_m_unwind_complete = m_unwind_complete; 3065ffd83dbSDimitry Andric CursorSP old_m_candidate_frame = m_candidate_frame; 3075ffd83dbSDimitry Andric 3085ffd83dbSDimitry Andric // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan 3095ffd83dbSDimitry Andric // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update 3105ffd83dbSDimitry Andric // the cfa of Frame 0 (if required). 3115ffd83dbSDimitry Andric AddOneMoreFrame(abi); 3125ffd83dbSDimitry Andric 3135ffd83dbSDimitry Andric // Remove all the frames added by above function as the purpose of using 3145ffd83dbSDimitry Andric // above function was just to check whether Unwinder of Frame 0 works or not. 3155ffd83dbSDimitry Andric for (uint32_t i = 1; i < m_frames.size(); i++) 3165ffd83dbSDimitry Andric m_frames.pop_back(); 3175ffd83dbSDimitry Andric 3185ffd83dbSDimitry Andric // Restore status after calling AddOneMoreFrame 3195ffd83dbSDimitry Andric m_unwind_complete = old_m_unwind_complete; 3205ffd83dbSDimitry Andric m_candidate_frame = old_m_candidate_frame; 3215ffd83dbSDimitry Andric } 3225ffd83dbSDimitry Andric 3235ffd83dbSDimitry Andric bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { 32481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Unwind); 3255ffd83dbSDimitry Andric 3265ffd83dbSDimitry Andric // Frame zero is a little different 3275ffd83dbSDimitry Andric if (m_frames.empty()) 3285ffd83dbSDimitry Andric return false; 3295ffd83dbSDimitry Andric 3305ffd83dbSDimitry Andric // If we've already gotten to the end of the stack, don't bother to try 3315ffd83dbSDimitry Andric // again... 3325ffd83dbSDimitry Andric if (m_unwind_complete) 3335ffd83dbSDimitry Andric return false; 3345ffd83dbSDimitry Andric 3355ffd83dbSDimitry Andric CursorSP new_frame = m_candidate_frame; 3365ffd83dbSDimitry Andric if (new_frame == nullptr) 3375ffd83dbSDimitry Andric new_frame = GetOneMoreFrame(abi); 3385ffd83dbSDimitry Andric 3395ffd83dbSDimitry Andric if (new_frame == nullptr) { 3405ffd83dbSDimitry Andric LLDB_LOGF(log, "th%d Unwind of this thread is complete.", 3415ffd83dbSDimitry Andric m_thread.GetIndexID()); 3425ffd83dbSDimitry Andric m_unwind_complete = true; 3435ffd83dbSDimitry Andric return false; 3445ffd83dbSDimitry Andric } 3455ffd83dbSDimitry Andric 3465ffd83dbSDimitry Andric m_frames.push_back(new_frame); 3475ffd83dbSDimitry Andric 3485ffd83dbSDimitry Andric // If we can get one more frame further then accept that we get back a 3495ffd83dbSDimitry Andric // correct frame. 3505ffd83dbSDimitry Andric m_candidate_frame = GetOneMoreFrame(abi); 3515ffd83dbSDimitry Andric if (m_candidate_frame) 3525ffd83dbSDimitry Andric return true; 3535ffd83dbSDimitry Andric 3545ffd83dbSDimitry Andric // We can't go further from the frame returned by GetOneMore frame. Lets try 3555ffd83dbSDimitry Andric // to get a different frame with using the fallback unwind plan. 3565ffd83dbSDimitry Andric if (!m_frames[m_frames.size() - 2] 3575ffd83dbSDimitry Andric ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { 3585ffd83dbSDimitry Andric // We don't have a valid fallback unwind plan. Accept the frame as it is. 3595ffd83dbSDimitry Andric // This is a valid situation when we are at the bottom of the stack. 3605ffd83dbSDimitry Andric return true; 3615ffd83dbSDimitry Andric } 3625ffd83dbSDimitry Andric 3635ffd83dbSDimitry Andric // Remove the possibly incorrect frame from the frame list and try to add a 3645ffd83dbSDimitry Andric // different one with the newly selected fallback unwind plan. 3655ffd83dbSDimitry Andric m_frames.pop_back(); 3665ffd83dbSDimitry Andric CursorSP new_frame_v2 = GetOneMoreFrame(abi); 3675ffd83dbSDimitry Andric if (new_frame_v2 == nullptr) { 3685ffd83dbSDimitry Andric // We haven't got a new frame from the fallback unwind plan. Accept the 3695ffd83dbSDimitry Andric // frame from the original unwind plan. This is a valid situation when we 3705ffd83dbSDimitry Andric // are at the bottom of the stack. 3715ffd83dbSDimitry Andric m_frames.push_back(new_frame); 3725ffd83dbSDimitry Andric return true; 3735ffd83dbSDimitry Andric } 3745ffd83dbSDimitry Andric 3755ffd83dbSDimitry Andric // Push the new frame to the list and try to continue from this frame. If we 3765ffd83dbSDimitry Andric // can get a new frame then accept it as the correct one. 3775ffd83dbSDimitry Andric m_frames.push_back(new_frame_v2); 3785ffd83dbSDimitry Andric m_candidate_frame = GetOneMoreFrame(abi); 3795ffd83dbSDimitry Andric if (m_candidate_frame) { 3805ffd83dbSDimitry Andric // If control reached here then TryFallbackUnwindPlan had succeeded for 3815ffd83dbSDimitry Andric // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next 3825ffd83dbSDimitry Andric // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For 3835ffd83dbSDimitry Andric // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already 3845ffd83dbSDimitry Andric // updated during TryFallbackUnwindPlan call above. However, cfa field 3855ffd83dbSDimitry Andric // still needs to be updated. Hence updating it here and then returning. 3865ffd83dbSDimitry Andric return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( 3875ffd83dbSDimitry Andric m_frames[m_frames.size() - 2]->cfa); 3885ffd83dbSDimitry Andric } 3895ffd83dbSDimitry Andric 3905ffd83dbSDimitry Andric // The new frame hasn't helped in unwinding. Fall back to the original one as 3915ffd83dbSDimitry Andric // the default unwind plan is usually more reliable then the fallback one. 3925ffd83dbSDimitry Andric m_frames.pop_back(); 3935ffd83dbSDimitry Andric m_frames.push_back(new_frame); 3945ffd83dbSDimitry Andric return true; 3955ffd83dbSDimitry Andric } 3965ffd83dbSDimitry Andric 3975ffd83dbSDimitry Andric bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, 3985ffd83dbSDimitry Andric bool &behaves_like_zeroth_frame) { 3995ffd83dbSDimitry Andric if (m_frames.size() == 0) { 4005ffd83dbSDimitry Andric if (!AddFirstFrame()) 4015ffd83dbSDimitry Andric return false; 4025ffd83dbSDimitry Andric } 4035ffd83dbSDimitry Andric 4045ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 4055ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 4065ffd83dbSDimitry Andric 4075ffd83dbSDimitry Andric while (idx >= m_frames.size() && AddOneMoreFrame(abi)) 4085ffd83dbSDimitry Andric ; 4095ffd83dbSDimitry Andric 4105ffd83dbSDimitry Andric if (idx < m_frames.size()) { 4115ffd83dbSDimitry Andric cfa = m_frames[idx]->cfa; 4125ffd83dbSDimitry Andric pc = m_frames[idx]->start_pc; 4135ffd83dbSDimitry Andric if (idx == 0) { 4145ffd83dbSDimitry Andric // Frame zero always behaves like it. 4155ffd83dbSDimitry Andric behaves_like_zeroth_frame = true; 4165ffd83dbSDimitry Andric } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { 4175ffd83dbSDimitry Andric // This could be an asynchronous signal, thus the 4185ffd83dbSDimitry Andric // pc might point to the interrupted instruction rather 4195ffd83dbSDimitry Andric // than a post-call instruction 4205ffd83dbSDimitry Andric behaves_like_zeroth_frame = true; 4215ffd83dbSDimitry Andric } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { 4225ffd83dbSDimitry Andric // This frame may result from signal processing installing 4235ffd83dbSDimitry Andric // a pointer to the first byte of a signal-return trampoline 4245ffd83dbSDimitry Andric // in the return address slot of the frame below, so this 4255ffd83dbSDimitry Andric // too behaves like the zeroth frame (i.e. the pc might not 4265ffd83dbSDimitry Andric // be pointing just past a call in it) 4275ffd83dbSDimitry Andric behaves_like_zeroth_frame = true; 428fe6060f1SDimitry Andric } else if (m_frames[idx]->reg_ctx_lldb_sp->BehavesLikeZerothFrame()) { 429fe6060f1SDimitry Andric behaves_like_zeroth_frame = true; 4305ffd83dbSDimitry Andric } else { 4315ffd83dbSDimitry Andric behaves_like_zeroth_frame = false; 4325ffd83dbSDimitry Andric } 4335ffd83dbSDimitry Andric return true; 4345ffd83dbSDimitry Andric } 4355ffd83dbSDimitry Andric return false; 4365ffd83dbSDimitry Andric } 4375ffd83dbSDimitry Andric 4385ffd83dbSDimitry Andric lldb::RegisterContextSP 4395ffd83dbSDimitry Andric UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) { 4405ffd83dbSDimitry Andric lldb::RegisterContextSP reg_ctx_sp; 4415ffd83dbSDimitry Andric uint32_t idx = frame->GetConcreteFrameIndex(); 4425ffd83dbSDimitry Andric 4435ffd83dbSDimitry Andric if (idx == 0) { 4445ffd83dbSDimitry Andric return m_thread.GetRegisterContext(); 4455ffd83dbSDimitry Andric } 4465ffd83dbSDimitry Andric 4475ffd83dbSDimitry Andric if (m_frames.size() == 0) { 4485ffd83dbSDimitry Andric if (!AddFirstFrame()) 4495ffd83dbSDimitry Andric return reg_ctx_sp; 4505ffd83dbSDimitry Andric } 4515ffd83dbSDimitry Andric 4525ffd83dbSDimitry Andric ProcessSP process_sp(m_thread.GetProcess()); 4535ffd83dbSDimitry Andric ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 4545ffd83dbSDimitry Andric 4555ffd83dbSDimitry Andric while (idx >= m_frames.size()) { 4565ffd83dbSDimitry Andric if (!AddOneMoreFrame(abi)) 4575ffd83dbSDimitry Andric break; 4585ffd83dbSDimitry Andric } 4595ffd83dbSDimitry Andric 4605ffd83dbSDimitry Andric const uint32_t num_frames = m_frames.size(); 4615ffd83dbSDimitry Andric if (idx < num_frames) { 4625ffd83dbSDimitry Andric Cursor *frame_cursor = m_frames[idx].get(); 4635ffd83dbSDimitry Andric reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; 4645ffd83dbSDimitry Andric } 4655ffd83dbSDimitry Andric return reg_ctx_sp; 4665ffd83dbSDimitry Andric } 4675ffd83dbSDimitry Andric 4685ffd83dbSDimitry Andric UnwindLLDB::RegisterContextLLDBSP 4695ffd83dbSDimitry Andric UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) { 4705ffd83dbSDimitry Andric RegisterContextLLDBSP reg_ctx_sp; 4715ffd83dbSDimitry Andric if (frame_num < m_frames.size()) 4725ffd83dbSDimitry Andric reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; 4735ffd83dbSDimitry Andric return reg_ctx_sp; 4745ffd83dbSDimitry Andric } 4755ffd83dbSDimitry Andric 4765ffd83dbSDimitry Andric bool UnwindLLDB::SearchForSavedLocationForRegister( 4775ffd83dbSDimitry Andric uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, 4785ffd83dbSDimitry Andric uint32_t starting_frame_num, bool pc_reg) { 4795ffd83dbSDimitry Andric int64_t frame_num = starting_frame_num; 4805ffd83dbSDimitry Andric if (static_cast<size_t>(frame_num) >= m_frames.size()) 4815ffd83dbSDimitry Andric return false; 4825ffd83dbSDimitry Andric 4835ffd83dbSDimitry Andric // Never interrogate more than one level while looking for the saved pc 4845ffd83dbSDimitry Andric // value. If the value isn't saved by frame_num, none of the frames lower on 4855ffd83dbSDimitry Andric // the stack will have a useful value. 4865ffd83dbSDimitry Andric if (pc_reg) { 4875ffd83dbSDimitry Andric UnwindLLDB::RegisterSearchResult result; 4885ffd83dbSDimitry Andric result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 4895ffd83dbSDimitry Andric lldb_regnum, regloc); 4905ffd83dbSDimitry Andric return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; 4915ffd83dbSDimitry Andric } 4925ffd83dbSDimitry Andric while (frame_num >= 0) { 4935ffd83dbSDimitry Andric UnwindLLDB::RegisterSearchResult result; 4945ffd83dbSDimitry Andric result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( 4955ffd83dbSDimitry Andric lldb_regnum, regloc); 4965ffd83dbSDimitry Andric 4975ffd83dbSDimitry Andric // We descended down to the live register context aka stack frame 0 and are 4985ffd83dbSDimitry Andric // reading the value out of a live register. 4995ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 5005ffd83dbSDimitry Andric regloc.type == 5015ffd83dbSDimitry Andric UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) { 5025ffd83dbSDimitry Andric return true; 5035ffd83dbSDimitry Andric } 5045ffd83dbSDimitry Andric 5055ffd83dbSDimitry Andric // If we have unwind instructions saying that register N is saved in 5065ffd83dbSDimitry Andric // register M in the middle of the stack (and N can equal M here, meaning 5075ffd83dbSDimitry Andric // the register was not used in this function), then change the register 5085ffd83dbSDimitry Andric // number we're looking for to M and keep looking for a concrete location 5095ffd83dbSDimitry Andric // down the stack, or an actual value from a live RegisterContext at frame 5105ffd83dbSDimitry Andric // 0. 5115ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && 5125ffd83dbSDimitry Andric regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister && 5135ffd83dbSDimitry Andric frame_num > 0) { 5145ffd83dbSDimitry Andric result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound; 5155ffd83dbSDimitry Andric lldb_regnum = regloc.location.register_number; 5165ffd83dbSDimitry Andric } 5175ffd83dbSDimitry Andric 5185ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) 5195ffd83dbSDimitry Andric return true; 5205ffd83dbSDimitry Andric if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile) 5215ffd83dbSDimitry Andric return false; 5225ffd83dbSDimitry Andric frame_num--; 5235ffd83dbSDimitry Andric } 5245ffd83dbSDimitry Andric return false; 5255ffd83dbSDimitry Andric } 526