summaryrefslogtreecommitdiff
path: root/source/Target/StackFrameList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Target/StackFrameList.cpp')
-rw-r--r--source/Target/StackFrameList.cpp78
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;