diff options
Diffstat (limited to 'source/Target/StackFrameList.cpp')
-rw-r--r-- | source/Target/StackFrameList.cpp | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp index 5492dda46402d..6d0c46259c20f 100644 --- a/source/Target/StackFrameList.cpp +++ b/source/Target/StackFrameList.cpp @@ -67,7 +67,8 @@ uint32_t StackFrameList::GetCurrentInlinedDepth() { m_current_inlined_depth = UINT32_MAX; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log && log->GetVerbose()) - log->Printf( + LLDB_LOGF( + log, "GetCurrentInlinedDepth: invalidating current inlined depth.\n"); } return m_current_inlined_depth; @@ -90,7 +91,8 @@ void StackFrameList::ResetCurrentInlinedDepth() { m_current_inlined_pc = LLDB_INVALID_ADDRESS; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log && log->GetVerbose()) - log->Printf( + LLDB_LOGF( + log, "ResetCurrentInlinedDepth: Invalidating current inlined depth.\n"); return; } @@ -184,9 +186,10 @@ void StackFrameList::ResetCurrentInlinedDepth() { m_current_inlined_depth = num_inlined_functions + 1; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log && log->GetVerbose()) - log->Printf("ResetCurrentInlinedDepth: setting inlined " - "depth: %d 0x%" PRIx64 ".\n", - m_current_inlined_depth, curr_pc); + LLDB_LOGF(log, + "ResetCurrentInlinedDepth: setting inlined " + "depth: %d 0x%" PRIx64 ".\n", + m_current_inlined_depth, curr_pc); break; } @@ -247,26 +250,19 @@ static void FindInterveningFrames(Function &begin, Function &end, begin.GetDisplayName(), end.GetDisplayName(), return_pc); // Find a non-tail calling edge with the correct return PC. - auto first_level_edges = begin.GetCallEdges(); if (log) - for (const CallEdge &edge : first_level_edges) + for (const CallEdge &edge : begin.GetCallEdges()) LLDB_LOG(log, "FindInterveningFrames: found call with retn-PC = {0:x}", edge.GetReturnPCAddress(begin, target)); - auto first_edge_it = std::lower_bound( - first_level_edges.begin(), first_level_edges.end(), return_pc, - [&](const CallEdge &edge, addr_t target_pc) { - return edge.GetReturnPCAddress(begin, target) < target_pc; - }); - if (first_edge_it == first_level_edges.end() || - first_edge_it->GetReturnPCAddress(begin, target) != return_pc) { + CallEdge *first_edge = begin.GetCallEdgeForReturnAddress(return_pc, target); + if (!first_edge) { LLDB_LOG(log, "No call edge outgoing from {0} with retn-PC == {1:x}", begin.GetDisplayName(), return_pc); return; } - CallEdge &first_edge = const_cast<CallEdge &>(*first_edge_it); // The first callee may not be resolved, or there may be nothing to fill in. - Function *first_callee = first_edge.GetCallee(images); + Function *first_callee = first_edge->GetCallee(images); if (!first_callee) { LLDB_LOG(log, "Could not resolve callee"); return; @@ -290,15 +286,15 @@ static void FindInterveningFrames(Function &begin, Function &end, DFS(Function *end, ModuleList &images) : end(end), images(images) {} - void search(Function *first_callee, std::vector<Function *> &path) { + void search(Function &first_callee, std::vector<Function *> &path) { dfs(first_callee); if (!ambiguous) path = std::move(solution_path); } - void dfs(Function *callee) { + void dfs(Function &callee) { // Found a path to the target function. - if (callee == end) { + if (&callee == end) { if (solution_path.empty()) solution_path = active_path; else @@ -310,19 +306,19 @@ static void FindInterveningFrames(Function &begin, Function &end, // there's more than one way to reach a target. This errs on the side of // caution: it conservatively stops searching when some solutions are // still possible to save time in the average case. - if (!visited_nodes.insert(callee).second) { + if (!visited_nodes.insert(&callee).second) { ambiguous = true; return; } // Search the calls made from this callee. - active_path.push_back(callee); - for (CallEdge &edge : callee->GetTailCallingEdges()) { + active_path.push_back(&callee); + for (CallEdge &edge : callee.GetTailCallingEdges()) { Function *next_callee = edge.GetCallee(images); if (!next_callee) continue; - dfs(next_callee); + dfs(*next_callee); if (ambiguous) return; } @@ -330,7 +326,7 @@ static void FindInterveningFrames(Function &begin, Function &end, } }; - DFS(&end, images).search(first_callee, path); + DFS(&end, images).search(*first_callee, path); } /// Given that \p next_frame will be appended to the frame list, synthesize @@ -394,11 +390,13 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { bool cfa_is_valid = false; addr_t pc = callee->GetAddressRange().GetBaseAddress().GetLoadAddress(&target); + constexpr bool behaves_like_zeroth_frame = false; SymbolContext sc; callee->CalculateSymbolContext(&sc); auto synth_frame = std::make_shared<StackFrame>( m_thread.shared_from_this(), frame_idx, concrete_frame_idx, cfa, - cfa_is_valid, pc, StackFrame::Kind::Artificial, &sc); + cfa_is_valid, pc, StackFrame::Kind::Artificial, + behaves_like_zeroth_frame, &sc); m_frames.push_back(synth_frame); LLDB_LOG(log, "Pushed frame {0}", callee->GetDisplayName()); } @@ -448,6 +446,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { uint32_t idx = m_concrete_frames_fetched++; lldb::addr_t pc = LLDB_INVALID_ADDRESS; lldb::addr_t cfa = LLDB_INVALID_ADDRESS; + bool behaves_like_zeroth_frame = (idx == 0); if (idx == 0) { // We might have already created frame zero, only create it if we need // to. @@ -455,8 +454,9 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext()); if (reg_ctx_sp) { - const bool success = - unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + const bool success = unwinder && + unwinder->GetFrameInfoAtIndex( + idx, cfa, pc, behaves_like_zeroth_frame); // There shouldn't be any way not to get the frame info for frame // 0. But if the unwinder can't make one, lets make one by hand // with the SP as the CFA and see if that gets any further. @@ -467,7 +467,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { unwind_frame_sp = std::make_shared<StackFrame>( m_thread.shared_from_this(), m_frames.size(), idx, reg_ctx_sp, - cfa, pc, nullptr); + cfa, pc, behaves_like_zeroth_frame, nullptr); m_frames.push_back(unwind_frame_sp); } } else { @@ -475,8 +475,9 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); } } else { - const bool success = - unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + const bool success = unwinder && + unwinder->GetFrameInfoAtIndex( + idx, cfa, pc, behaves_like_zeroth_frame); if (!success) { // We've gotten to the end of the stack. SetAllFramesFetched(); @@ -485,7 +486,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { const bool cfa_is_valid = true; unwind_frame_sp = std::make_shared<StackFrame>( m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, - pc, StackFrame::Kind::Regular, nullptr); + pc, StackFrame::Kind::Regular, behaves_like_zeroth_frame, nullptr); // Create synthetic tail call frames between the previous frame and the // newly-found frame. The new frame's index may change after this call, @@ -527,10 +528,11 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { while (unwind_sc.GetParentOfInlinedScope( curr_frame_address, next_frame_sc, next_frame_address)) { next_frame_sc.line_entry.ApplyFileMappings(target_sp); - StackFrameSP frame_sp( - new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, - unwind_frame_sp->GetRegisterContextSP(), cfa, - next_frame_address, &next_frame_sc)); + behaves_like_zeroth_frame = false; + StackFrameSP frame_sp(new StackFrame( + m_thread.shared_from_this(), m_frames.size(), idx, + unwind_frame_sp->GetRegisterContextSP(), cfa, next_frame_address, + behaves_like_zeroth_frame, &next_frame_sc)); m_frames.push_back(frame_sp); unwind_sc = next_frame_sc; @@ -661,11 +663,13 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) { Unwind *unwinder = m_thread.GetUnwinder(); if (unwinder) { addr_t pc, cfa; - if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) { + bool behaves_like_zeroth_frame = (idx == 0); + if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc, + behaves_like_zeroth_frame)) { const bool cfa_is_valid = true; frame_sp = std::make_shared<StackFrame>( m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, - StackFrame::Kind::Regular, nullptr); + StackFrame::Kind::Regular, behaves_like_zeroth_frame, nullptr); Function *function = frame_sp->GetSymbolContext(eSymbolContextFunction).function; |