summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Core/Address.cpp18
-rw-r--r--lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp4
-rw-r--r--lldb/source/Plugins/Process/Utility/HistoryUnwind.h3
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp105
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp21
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.h3
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp6
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h3
-rw-r--r--lldb/source/Target/StackFrame.cpp30
-rw-r--r--lldb/source/Target/StackFrameList.cpp34
11 files changed, 151 insertions, 80 deletions
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index 0da83eb98ed..84ff4ec5b07 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -261,6 +261,24 @@ bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
return false; // Failed to resolve this address to a section offset value
}
+/// if "addr_range_ptr" is not NULL, then fill in with the address range of the function.
+bool Address::ResolveFunctionScope(SymbolContext &sym_ctx,
+ AddressRange *addr_range_ptr) {
+ constexpr SymbolContextItem resolve_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+
+ if (!(CalculateSymbolContext(&sym_ctx, resolve_scope) & resolve_scope)) {
+ if (addr_range_ptr)
+ addr_range_ptr->Clear();
+ return false;
+ }
+
+ if (!addr_range_ptr)
+ return true;
+
+ return sym_ctx.GetAddressRange(resolve_scope, 0, false, *addr_range_ptr);
+}
+
ModuleSP Address::GetModule() const {
lldb::ModuleSP module_sp;
SectionSP section_sp(GetSection());
diff --git a/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 7d473bff820..83fdb011f5a 100644
--- a/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -51,13 +51,15 @@ HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
}
bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) {
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) {
// FIXME do not throw away the lock after we acquire it..
std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
guard.unlock();
if (frame_idx < m_pcs.size()) {
cfa = frame_idx;
pc = m_pcs[frame_idx];
+ behaves_like_zeroth_frame = (frame_idx == 0);
return true;
}
return false;
diff --git a/lldb/source/Plugins/Process/Utility/HistoryUnwind.h b/lldb/source/Plugins/Process/Utility/HistoryUnwind.h
index 6c4522e6b35..4d16608bd8c 100644
--- a/lldb/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/lldb/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -29,7 +29,8 @@ protected:
DoCreateRegisterContextForFrame(StackFrame *frame) override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) override;
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) override;
uint32_t DoGetFrameCount() override;
private:
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 62f38dcd85a..27341267a8a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -150,15 +150,8 @@ void RegisterContextLLDB::InitializeZerothFrame() {
UnwindLogMsg("using architectural default unwind method");
}
- // We require either a symbol or function in the symbols context to be
- // successfully filled in or this context is of no use to us.
- const SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
- if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress(
- m_current_pc, resolve_scope, m_sym_ctx) &
- resolve_scope)) {
- m_sym_ctx_valid = true;
- }
+ AddressRange addr_range;
+ m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
if (m_sym_ctx.symbol) {
UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
@@ -172,9 +165,6 @@ void RegisterContextLLDB::InitializeZerothFrame() {
current_pc);
}
- AddressRange addr_range;
- m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range);
-
if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
m_frame_type = eTrapHandlerFrame;
} else {
@@ -436,24 +426,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
return;
}
- bool resolve_tail_call_address = false; // m_current_pc can be one past the
- // address range of the function...
- // If the saved pc does not point to a function/symbol because it is beyond
- // the bounds of the correct function and there's no symbol there, we do
- // *not* want ResolveSymbolContextForAddress to back up the pc by 1, because
- // then we might not find the correct unwind information later. Instead, let
- // ResolveSymbolContextForAddress fail, and handle the case via
- // decr_pc_and_recompute_addr_range below.
- const SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
- uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress(
- m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address);
-
- // We require either a symbol or function in the symbols context to be
- // successfully filled in or this context is of no use to us.
- if (resolve_scope & resolved_scope) {
- m_sym_ctx_valid = true;
- }
+ AddressRange addr_range;
+ m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
if (m_sym_ctx.symbol) {
UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc,
@@ -467,11 +441,6 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
pc);
}
- AddressRange addr_range;
- if (!m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range)) {
- m_sym_ctx_valid = false;
- }
-
bool decr_pc_and_recompute_addr_range;
if (!m_sym_ctx_valid) {
@@ -512,18 +481,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
Address temporary_pc;
temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
m_sym_ctx.Clear(false);
- m_sym_ctx_valid = false;
- SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
-
- ModuleSP temporary_module_sp = temporary_pc.GetModule();
- if (temporary_module_sp &&
- temporary_module_sp->ResolveSymbolContextForAddress(
- temporary_pc, resolve_scope, m_sym_ctx) &
- resolve_scope) {
- if (m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range))
- m_sym_ctx_valid = true;
- }
+ m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
+
UnwindLogMsg("Symbol is now %s",
GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
}
@@ -573,6 +532,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
active_row =
m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
+ PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp);
if (active_row.get() && log) {
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
@@ -585,6 +545,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) {
active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
+ PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
if (active_row.get() && log) {
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
@@ -1708,6 +1669,7 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
// We've copied the fallback unwind plan into the full - now clear the
// fallback.
m_fallback_unwind_plan_sp.reset();
+ PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
}
return true;
@@ -1751,6 +1713,8 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
m_cfa = new_cfa;
+ PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
+
UnwindLogMsg("switched unconditionally to the fallback unwindplan %s",
m_full_unwind_plan_sp->GetSourceName().GetCString());
return true;
@@ -1758,6 +1722,53 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
return false;
}
+void RegisterContextLLDB::PropagateTrapHandlerFlagFromUnwindPlan(
+ lldb::UnwindPlanSP unwind_plan) {
+ if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
+ // Unwind plan does not indicate trap handler. Do nothing. We may
+ // already be flagged as trap handler flag due to the symbol being
+ // in the trap handler symbol list, and that should take precedence.
+ return;
+ } else if (m_frame_type != eNormalFrame) {
+ // If this is already a trap handler frame, nothing to do.
+ // If this is a skip or debug or invalid frame, don't override that.
+ return;
+ }
+
+ m_frame_type = eTrapHandlerFrame;
+
+ if (m_current_offset_backed_up_one != m_current_offset) {
+ // We backed up the pc by 1 to compute the symbol context, but
+ // now need to undo that because the pc of the trap handler
+ // frame may in fact be the first instruction of a signal return
+ // trampoline, rather than the instruction after a call. This
+ // happens on systems where the signal handler dispatch code, rather
+ // than calling the handler and being returned to, jumps to the
+ // handler after pushing the address of a return trampoline on the
+ // stack -- on these systems, when the handler returns, control will
+ // be transferred to the return trampoline, so that's the best
+ // symbol we can present in the callstack.
+ UnwindLogMsg("Resetting current offset and re-doing symbol lookup; "
+ "old symbol was %s",
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ m_current_offset_backed_up_one = m_current_offset;
+
+ AddressRange addr_range;
+ m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
+
+ UnwindLogMsg("Symbol is now %s",
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ Target *target = &process->GetTarget();
+
+ m_start_pc = addr_range.GetBaseAddress();
+ m_current_offset =
+ m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target);
+ }
+}
+
bool RegisterContextLLDB::ReadFrameAddress(
lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa,
addr_t &address) {
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
index 64dd394d233..1ca663906ed 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -120,6 +120,10 @@ private:
bool IsTrapHandlerSymbol(lldb_private::Process *process,
const lldb_private::SymbolContext &m_sym_ctx) const;
+ /// Check if the given unwind plan indicates a signal trap handler, and
+ /// update frame type and symbol context if so.
+ void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan);
+
// Provide a location for where THIS function saved the CALLER's register
// value
// Or a frame "below" this one saved it, i.e. a function called by this one,
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 4b135351593..74fc90e8854 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -390,7 +390,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
return true;
}
-bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
+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;
@@ -405,6 +406,24 @@ bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
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;
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
index c512929c185..ff5db39730b 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -73,7 +73,8 @@ protected:
uint32_t DoGetFrameCount() override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &start_pc) override;
+ lldb::addr_t &start_pc,
+ bool &behaves_like_zeroth_frame) override;
lldb::RegisterContextSP
DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index 7dc5a5f5fdd..558edeec1a3 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -43,9 +43,8 @@ uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() {
return m_cursors.size();
}
-bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
- addr_t &cfa,
- addr_t &pc) {
+bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(
+ uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) {
const uint32_t frame_count = GetFrameCount();
if (idx < frame_count) {
if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
@@ -55,6 +54,7 @@ bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
pc = m_cursors[idx].pc;
cfa = m_cursors[idx].fp;
+ behaves_like_zeroth_frame = (idx == 0);
return true;
}
diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
index 2208bcc2f2e..f0bde90a53b 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
@@ -26,7 +26,8 @@ protected:
uint32_t DoGetFrameCount() override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) override;
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) override;
lldb::RegisterContextSP
DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 1bc8165d76b..5e5a596e471 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -51,14 +51,16 @@ using namespace lldb_private;
StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
user_id_t unwind_frame_index, addr_t cfa,
bool cfa_is_valid, addr_t pc, StackFrame::Kind kind,
+ bool behaves_like_zeroth_frame,
const SymbolContext *sc_ptr)
: m_thread_wp(thread_sp), m_frame_index(frame_idx),
m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(),
m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
- m_stack_frame_kind(kind), m_variable_list_sp(),
- m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(),
- m_mutex() {
+ m_stack_frame_kind(kind),
+ m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
+ m_variable_list_sp(), m_variable_list_value_objects(),
+ m_recognized_frame_sp(), m_disassembly(), m_mutex() {
// If we don't have a CFA value, use the frame index for our StackID so that
// recursive functions properly aren't confused with one another on a history
// stack.
@@ -75,15 +77,17 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
user_id_t unwind_frame_index,
const RegisterContextSP &reg_context_sp, addr_t cfa,
- addr_t pc, const SymbolContext *sc_ptr)
+ addr_t pc, bool behaves_like_zeroth_frame,
+ const SymbolContext *sc_ptr)
: m_thread_wp(thread_sp), m_frame_index(frame_idx),
m_concrete_frame_index(unwind_frame_index),
m_reg_context_sp(reg_context_sp), m_id(pc, cfa, nullptr),
m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(),
m_frame_base_error(), m_cfa_is_valid(true),
- m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(),
- m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(),
- m_mutex() {
+ m_stack_frame_kind(StackFrame::Kind::Regular),
+ m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
+ m_variable_list_sp(), m_variable_list_value_objects(),
+ m_recognized_frame_sp(), m_disassembly(), m_mutex() {
if (sc_ptr != nullptr) {
m_sc = *sc_ptr;
m_flags.Set(m_sc.GetResolvedMask());
@@ -99,7 +103,8 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
user_id_t unwind_frame_index,
const RegisterContextSP &reg_context_sp, addr_t cfa,
- const Address &pc_addr, const SymbolContext *sc_ptr)
+ const Address &pc_addr, bool behaves_like_zeroth_frame,
+ const SymbolContext *sc_ptr)
: m_thread_wp(thread_sp), m_frame_index(frame_idx),
m_concrete_frame_index(unwind_frame_index),
m_reg_context_sp(reg_context_sp),
@@ -107,9 +112,10 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
nullptr),
m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
m_frame_base_error(), m_cfa_is_valid(true),
- m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(),
- m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(),
- m_mutex() {
+ m_stack_frame_kind(StackFrame::Kind::Regular),
+ m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
+ m_variable_list_sp(), m_variable_list_value_objects(),
+ m_recognized_frame_sp(), m_disassembly(), m_mutex() {
if (sc_ptr != nullptr) {
m_sc = *sc_ptr;
m_flags.Set(m_sc.GetResolvedMask());
@@ -289,7 +295,7 @@ StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
// following the function call instruction...
Address lookup_addr(GetFrameCodeAddress());
- if (m_frame_index > 0 && lookup_addr.IsValid()) {
+ if (!m_behaves_like_zeroth_frame && lookup_addr.IsValid()) {
addr_t offset = lookup_addr.GetOffset();
if (offset > 0) {
lookup_addr.SetOffset(offset - 1);
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index 0723ed0b5a2..69445624a53 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -397,11 +397,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());
}
@@ -451,6 +453,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.
@@ -458,8 +461,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.
@@ -470,7 +474,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 {
@@ -478,8 +482,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();
@@ -488,7 +493,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,
@@ -530,10 +535,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;
@@ -664,11 +670,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;
OpenPOWER on IntegriCloud