Cleaned up the inline stack frame code one more time to prepare for inlined

code stepping. Also we now store the stack frames for the current and previous
stops in the thread in std::auto_ptr objects. When we create a thread stack
frame list we pass the previous frame into it so it can re-use the frames
and maintain will allow for variable changes to be detected. I will implement
the stack frame reuse next.

llvm-svn: 112152
This commit is contained in:
Greg Clayton 2010-08-26 02:28:22 +00:00
parent e5334b484a
commit 0445d8f498
8 changed files with 245 additions and 244 deletions

View File

@ -33,9 +33,9 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, lldb::addr_t cfa, uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr);
StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP &reg_context_sp, lldb::addr_t cfa, uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr);
StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP &reg_context_sp, lldb::addr_t cfa, uint32_t inline_height, const Address& pc, const SymbolContext *sc_ptr);
StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr);
StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP &reg_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr);
StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP &reg_context_sp, lldb::addr_t cfa, const Address& pc, const SymbolContext *sc_ptr);
virtual ~StackFrame ();
Thread &
@ -97,9 +97,6 @@ public:
return m_concrete_frame_index;
}
bool
IsConcrete () const;
//------------------------------------------------------------------
// lldb::ExecutionContextScope pure virtual functions
//------------------------------------------------------------------
@ -119,10 +116,16 @@ public:
Calculate (ExecutionContext &exe_ctx);
protected:
friend class StackFrameList;
//------------------------------------------------------------------
// Classes that inherit from StackFrame can see and modify these
//------------------------------------------------------------------
void
SetInlineBlockID (lldb::user_id_t inline_block_id)
{
m_id.SetInlineBlockID(inline_block_id);
}
private:
//------------------------------------------------------------------

View File

@ -27,7 +27,9 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
StackFrameList (Thread &thread, bool show_inline_frames);
StackFrameList (Thread &thread,
StackFrameList *prev_frames,
bool show_inline_frames);
~StackFrameList();
@ -56,22 +58,21 @@ public:
protected:
bool
SetActualFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp);
SetUnwindFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp);
bool
SetInlineFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp);
lldb::StackFrameSP
GetActualFrameAtIndex (uint32_t idx) const;
GetUnwindFrameAtIndex (uint32_t idx) const;
lldb::StackFrameSP
GetInlineFrameAtIndex (uint32_t idx) const;
typedef struct InlinedFrameInfo
{
uint32_t concrete_frame_index;
uint32_t inline_height;
uint32_t unwind_frame_index;
Block *block;
} InlinedFrameInfo;
typedef std::vector<InlinedFrameInfo> InlinedFrameInfoCollection;
@ -84,10 +85,11 @@ protected:
typedef collection::const_iterator const_iterator;
Thread &m_thread;
std::auto_ptr<StackFrameList> m_prev_frames_ap;
mutable Mutex m_mutex;
collection m_actual_frames;
collection m_unwind_frames;
collection m_inline_frames;
InlinedFrameInfoCollection m_inlined_frame_info;
InlinedFrameInfoCollection m_inlined_info;
uint32_t m_current_frame_idx;
bool m_show_inlined_frames;

View File

@ -25,11 +25,38 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
StackID ();
explicit StackID (lldb::addr_t cfa, uint32_t inline_id);
StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_id);
StackID (const StackID& rhs);
virtual ~StackID();
StackID () :
m_start_address(),
m_cfa (0),
m_inline_block_id (0)
{
}
explicit
StackID (lldb::addr_t cfa, lldb::user_id_t inline_block_id) :
m_start_address (),
m_cfa (cfa),
m_inline_block_id (inline_block_id)
{
}
StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_block_id) :
m_start_address (start_address),
m_cfa (cfa),
m_inline_block_id (inline_block_id)
{
}
StackID (const StackID& rhs) :
m_start_address (rhs.m_start_address),
m_cfa (rhs.m_cfa),
m_inline_block_id (rhs.m_inline_block_id)
{
}
~StackID()
{
}
const Address&
GetStartAddress() const
@ -49,28 +76,44 @@ public:
return m_cfa;
}
uint32_t
GetInlineHeight () const
lldb::user_id_t
GetInlineBlockID () const
{
return m_inline_height;
return m_inline_block_id;
}
void
SetInlineBlockID (lldb::user_id_t inline_block_id)
{
m_inline_block_id = inline_block_id;
}
//------------------------------------------------------------------
// Operators
//------------------------------------------------------------------
const StackID&
operator=(const StackID& rhs);
operator=(const StackID& rhs)
{
if (this != &rhs)
{
m_start_address = rhs.m_start_address;
m_cfa = rhs.m_cfa;
m_inline_block_id = rhs.m_inline_block_id;
}
return *this;
}
protected:
//------------------------------------------------------------------
// Classes that inherit from StackID can see and modify these
//------------------------------------------------------------------
Address m_start_address; // The address range for the function for this frame
lldb::addr_t m_cfa; // The call frame address (stack pointer) value
// at the beginning of the function that uniquely
// identifies this frame (along with m_inline_height below)
uint32_t m_inline_height; // The inline height of a stack frame. Zero is the actual
// value for the place where a thread stops, 1 and above
// are for the inlined frames above the concrete base frame.
Address m_start_address; // The address range for the function for this frame
lldb::addr_t m_cfa; // The call frame address (stack pointer) value
// at the beginning of the function that uniquely
// identifies this frame (along with m_inline_block_id below)
lldb::user_id_t m_inline_block_id; // The inline height of a stack frame. Zero is the actual
// value for the place where a thread stops, 1 and above
// are for the inlined frames above the concrete base frame.
};
bool operator== (const StackID& lhs, const StackID& rhs);

View File

@ -555,7 +555,8 @@ protected:
plan_stack m_immediate_plan_stack; ///< The plans that need to get executed before any other work gets done.
plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes.
plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes.
lldb::StackFrameListSP m_frames_sp; ///< The stack frames that get lazily populated after a thread stops.
std::auto_ptr<StackFrameList> m_curr_frames_ap; ///< The stack frames that get lazily populated after a thread stops.
std::auto_ptr<StackFrameList> m_prev_frames_ap; ///< The previous stack frames from the last time this thread stopped.
int m_resume_signal; ///< The signal that should be used when continuing this thread.
lldb::StateType m_resume_state; ///< The state that indicates what this thread should do when the process is resumed.
std::auto_ptr<lldb_private::Unwind> m_unwinder_ap;

View File

@ -41,7 +41,6 @@ StackFrame::StackFrame
lldb::user_id_t concrete_frame_index,
Thread &thread,
lldb::addr_t cfa,
uint32_t inline_height,
lldb::addr_t pc,
const SymbolContext *sc_ptr
) :
@ -49,7 +48,7 @@ StackFrame::StackFrame
m_concrete_frame_index (concrete_frame_index),
m_thread (thread),
m_reg_context_sp (),
m_id (cfa, inline_height),
m_id (cfa, 0),
m_pc (NULL, pc),
m_sc (),
m_flags (),
@ -72,7 +71,6 @@ StackFrame::StackFrame
Thread &thread,
const RegisterContextSP &reg_context_sp,
lldb::addr_t cfa,
uint32_t inline_height,
lldb::addr_t pc,
const SymbolContext *sc_ptr
) :
@ -80,7 +78,7 @@ StackFrame::StackFrame
m_concrete_frame_index (concrete_frame_index),
m_thread (thread),
m_reg_context_sp (reg_context_sp),
m_id (cfa, inline_height),
m_id (cfa, 0),
m_pc (NULL, pc),
m_sc (),
m_flags (),
@ -109,7 +107,6 @@ StackFrame::StackFrame
Thread &thread,
const RegisterContextSP &reg_context_sp,
lldb::addr_t cfa,
uint32_t inline_height,
const Address& pc_addr,
const SymbolContext *sc_ptr
) :
@ -117,7 +114,7 @@ StackFrame::StackFrame
m_concrete_frame_index (concrete_frame_index),
m_thread (thread),
m_reg_context_sp (reg_context_sp),
m_id (cfa, inline_height),
m_id (cfa, 0),
m_pc (pc_addr),
m_sc (),
m_flags (),
@ -473,12 +470,6 @@ StackFrame::GetValueObjectList()
return m_value_object_list;
}
bool
StackFrame::IsConcrete () const
{
return m_id.GetInlineHeight () == 0;
}
Target *
StackFrame::CalculateTarget ()
{

View File

@ -26,11 +26,12 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// StackFrameList constructor
//----------------------------------------------------------------------
StackFrameList::StackFrameList(Thread &thread, bool show_inline_frames) :
StackFrameList::StackFrameList(Thread &thread, StackFrameList *prev_frames, bool show_inline_frames) :
m_thread (thread),
m_prev_frames_ap (prev_frames),
m_show_inlined_frames (show_inline_frames),
m_mutex (Mutex::eMutexTypeRecursive),
m_actual_frames (),
m_unwind_frames (),
m_inline_frames (),
m_current_frame_idx (0)
{
@ -51,13 +52,13 @@ StackFrameList::GetNumFrames()
if (m_show_inlined_frames)
{
if (m_inlined_frame_info.empty())
if (m_inlined_info.empty())
{
Unwind *unwinder = m_thread.GetUnwinder ();
// If we are going to show inlined stack frames as actual frames,
// we need to calculate all concrete frames first, then iterate
// through all of them and count up how many inlined functions are
// in each frame. We can then fill in m_inlined_frame_info with
// in each frame. We can then fill in m_inlined_info with
// the concrete frame index and inlined depth
const uint32_t concrete_frame_count = unwinder->GetFrameCount();
@ -75,7 +76,6 @@ StackFrameList::GetNumFrames()
m_thread,
m_thread.m_reg_context_sp,
m_thread.m_reg_context_sp->GetSP(),
0,
m_thread.m_reg_context_sp->GetPC(),
NULL));
}
@ -83,52 +83,51 @@ StackFrameList::GetNumFrames()
{
const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
assert (success);
frame_sp.reset (new StackFrame (m_inlined_frame_info.size(), idx, m_thread, cfa, 0, pc, NULL));
frame_sp.reset (new StackFrame (m_inlined_info.size(), idx, m_thread, cfa, pc, NULL));
}
SetActualFrameAtIndex (idx, frame_sp);
SetUnwindFrameAtIndex (idx, frame_sp);
Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block;
inlined_frame_info.concrete_frame_index = idx;
inlined_frame_info.inline_height = 0;
inlined_frame_info.block = block;
m_inlined_frame_info.push_back (inlined_frame_info);
inlined_frame_info.unwind_frame_index = idx;
inlined_frame_info.block = NULL;
m_inlined_info.push_back (inlined_frame_info);
if (block)
{
Block *inlined_block;
if (block->InlinedFunctionInfo())
inlined_block = block;
else
inlined_block = block->GetInlinedParent ();
while (inlined_block)
Block *inlined_block = block->GetContainingInlinedBlock();
if (inlined_block)
{
inlined_frame_info.block = inlined_block;
inlined_frame_info.inline_height++;
m_inlined_frame_info.push_back (inlined_frame_info);
inlined_block = inlined_block->GetInlinedParent ();
frame_sp->SetInlineBlockID (inlined_block->GetID());
while (inlined_block)
{
inlined_frame_info.block = inlined_block;
m_inlined_info.push_back (inlined_frame_info);
inlined_block = inlined_block->GetInlinedParent ();
}
}
}
}
}
return m_inlined_frame_info.size();
return m_inlined_info.size();
}
else
{
if (m_actual_frames.empty())
m_actual_frames.resize(m_thread.GetUnwinder()->GetFrameCount());
if (m_unwind_frames.empty())
m_unwind_frames.resize(m_thread.GetUnwinder()->GetFrameCount());
return m_actual_frames.size();
return m_unwind_frames.size();
}
return 0;
}
lldb::StackFrameSP
StackFrameList::GetActualFrameAtIndex (uint32_t idx) const
StackFrameList::GetUnwindFrameAtIndex (uint32_t idx) const
{
StackFrameSP frame_sp;
if (idx < m_actual_frames.size())
frame_sp = m_actual_frames[idx];
if (idx < m_unwind_frames.size())
frame_sp = m_unwind_frames[idx];
return frame_sp;
}
@ -155,118 +154,138 @@ StackFrameList::GetFrameAtIndex (uint32_t idx)
}
else
{
frame_sp = GetActualFrameAtIndex (idx);
frame_sp = GetUnwindFrameAtIndex (idx);
}
if (frame_sp.get())
return frame_sp;
return frame_sp;
// Special case the first frame (idx == 0) so that we don't need to
// know how many stack frames there are to get it. If we need any other
// frames, then we do need to know if "idx" is a valid index.
if (idx == 0)
{
// If this is the first frame, we want to share the thread register
// context with the stack frame at index zero.
m_thread.GetRegisterContext();
assert (m_thread.m_reg_context_sp.get());
frame_sp.reset (new StackFrame (0,
0,
m_thread,
m_thread.m_reg_context_sp,
m_thread.m_reg_context_sp->GetSP(),
0,
m_thread.m_reg_context_sp->GetPC(),
NULL));
}
else if (idx < GetNumFrames())
{
// Special case the first frame (idx == 0) so that we don't need to
// know how many stack frames there are to get it. If we need any other
// frames, then we do need to know if "idx" is a valid index.
if (idx == 0)
{
// If this is the first frame, we want to share the thread register
// context with the stack frame at index zero.
m_thread.GetRegisterContext();
assert (m_thread.m_reg_context_sp.get());
frame_sp.reset (new StackFrame (0,
0,
m_thread,
m_thread.m_reg_context_sp,
m_thread.m_reg_context_sp->GetSP(),
m_thread.m_reg_context_sp->GetPC(),
NULL));
if (m_show_inlined_frames && idx + 1 < m_inlined_info.size())
{
if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index)
frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID());
}
}
else if (idx < GetNumFrames())
{
if (m_show_inlined_frames)
{
if (m_inlined_info[idx].block == NULL)
{
// Same as the concrete stack frame if block is NULL
assert (m_inlined_info[idx].unwind_frame_index < m_unwind_frames.size());
frame_sp = GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index);
if (idx + 1 < m_inlined_info.size())
{
if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index)
frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID());
}
}
else
{
// We have blocks that were above an inlined function. Inlined
// functions are represented as blocks with non-NULL inline
// function info. Here we must reconstruct a frame by looking
// at the block
StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1));
SymbolContext inline_sc;
Block *inlined_parent_block = m_inlined_info[idx].block->GetInlinedParent();
if (inlined_parent_block)
inlined_parent_block->CalculateSymbolContext (&inline_sc);
else
{
Block *parent_block = m_inlined_info[idx].block->GetParent();
parent_block->CalculateSymbolContext(&inline_sc);
}
Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress());
if (previous_frame_sp->GetFrameIndex() > 0 && m_inlined_info[idx-1].block == NULL)
previous_frame_lookup_addr.Slide (-1);
AddressRange range;
m_inlined_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range);
const InlineFunctionInfo* inline_info = m_inlined_info[idx].block->InlinedFunctionInfo();
assert (inline_info);
inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress();
inline_sc.line_entry.file = inline_info->GetCallSite().GetFile();
inline_sc.line_entry.line = inline_info->GetCallSite().GetLine();
inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
StackFrameSP concrete_frame_sp (GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index));
assert (previous_frame_sp.get());
frame_sp.reset (new StackFrame (idx,
m_inlined_info[idx].unwind_frame_index,
m_thread,
concrete_frame_sp->GetRegisterContextSP (),
concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA
range.GetBaseAddress(),
&inline_sc)); // The symbol context for this inline frame
if (idx + 1 < m_inlined_info.size())
{
if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index)
frame_sp->SetInlineBlockID (m_inlined_info[idx].block->GetID());
}
}
}
else
{
Unwind *unwinder = m_thread.GetUnwinder ();
if (unwinder)
{
addr_t pc, cfa;
if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL));
}
}
}
if (m_show_inlined_frames)
{
if (m_inlined_frame_info[idx].inline_height == 0)
{
// Same as the concrete stack frame if block is NULL
assert (m_inlined_frame_info[idx].concrete_frame_index < m_actual_frames.size());
frame_sp = GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index);
}
else
{
// We have blocks that were above an inlined function. Inlined
// functions are represented as blocks with non-NULL inline
// function info. Here we must reconstruct a frame by looking
// at the block
StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1));
SymbolContext inline_sc;
Block *inlined_parent_block = m_inlined_frame_info[idx].block->GetInlinedParent();
if (inlined_parent_block)
inlined_parent_block->CalculateSymbolContext (&inline_sc);
else
{
Block *parent_block = m_inlined_frame_info[idx].block->GetParent();
parent_block->CalculateSymbolContext(&inline_sc);
}
Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress());
if (previous_frame_sp->IsConcrete () && previous_frame_sp->GetFrameIndex() > 0)
previous_frame_lookup_addr.Slide (-1);
AddressRange range;
m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range);
const InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo();
assert (inline_info);
inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress();
inline_sc.line_entry.file = inline_info->GetCallSite().GetFile();
inline_sc.line_entry.line = inline_info->GetCallSite().GetLine();
inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
StackFrameSP concrete_frame_sp (GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index));
assert (previous_frame_sp.get());
frame_sp.reset (new StackFrame (idx,
m_inlined_frame_info[idx].concrete_frame_index,
m_thread,
concrete_frame_sp->GetRegisterContextSP (),
concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA
m_inlined_frame_info[idx].inline_height, // Inline height
range.GetBaseAddress(),
&inline_sc)); // The symbol context for this inline frame
}
SetInlineFrameAtIndex(idx, frame_sp);
}
else
{
Unwind *unwinder = m_thread.GetUnwinder ();
if (unwinder)
{
addr_t pc, cfa;
if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, 0, pc, NULL));
}
SetUnwindFrameAtIndex(idx, frame_sp);
}
}
if (m_show_inlined_frames)
SetInlineFrameAtIndex(idx, frame_sp);
else
SetActualFrameAtIndex(idx, frame_sp);
return frame_sp;
return frame_sp;
}
return frame_sp;
}
bool
StackFrameList::SetActualFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
StackFrameList::SetUnwindFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
{
if (idx >= m_actual_frames.size())
m_actual_frames.resize(idx + 1);
if (idx >= m_unwind_frames.size())
m_unwind_frames.resize(idx + 1);
// Make sure allocation succeeded by checking bounds again
if (idx < m_actual_frames.size())
if (idx < m_unwind_frames.size())
{
m_actual_frames[idx] = frame_sp;
m_unwind_frames[idx] = frame_sp;
return true;
}
return false; // resize failed, out of memory?
@ -299,8 +318,8 @@ StackFrameList::SetCurrentFrame (lldb_private::StackFrame *frame)
{
Mutex::Locker locker (m_mutex);
const_iterator pos;
const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_actual_frames.begin();
const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_actual_frames.end();
const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_unwind_frames.begin();
const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_unwind_frames.end();
for (pos = begin; pos != end; ++pos)
{
if (pos->get() == frame)
@ -327,9 +346,9 @@ void
StackFrameList::Clear ()
{
Mutex::Locker locker (m_mutex);
m_actual_frames.clear();
m_unwind_frames.clear();
m_inline_frames.clear();
m_inlined_frame_info.clear();
m_inlined_info.clear();
}
void
@ -342,10 +361,10 @@ StackFrameList::InvalidateFrames (uint32_t start_idx)
}
else
{
const size_t num_frames = m_actual_frames.size();
const size_t num_frames = m_unwind_frames.size();
while (start_idx < num_frames)
{
m_actual_frames[start_idx].reset();
m_unwind_frames[start_idx].reset();
++start_idx;
}
}

View File

@ -16,84 +16,27 @@
using namespace lldb_private;
//----------------------------------------------------------------------
// StackID constructor
//----------------------------------------------------------------------
StackID::StackID() :
m_start_address(),
m_cfa (0),
m_inline_height (0)
{
}
//----------------------------------------------------------------------
// StackID constructor with args
//----------------------------------------------------------------------
StackID::StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_id) :
m_start_address (start_address),
m_cfa (cfa),
m_inline_height (inline_id)
{
}
StackID::StackID (lldb::addr_t cfa, uint32_t inline_id) :
m_start_address (),
m_cfa (cfa),
m_inline_height (inline_id)
{
}
//----------------------------------------------------------------------
// StackID copy constructor
//----------------------------------------------------------------------
StackID::StackID(const StackID& rhs) :
m_start_address (rhs.m_start_address),
m_cfa (rhs.m_cfa),
m_inline_height (rhs.m_inline_height)
{
}
//----------------------------------------------------------------------
// StackID assignment operator
//----------------------------------------------------------------------
const StackID&
StackID::operator=(const StackID& rhs)
{
if (this != &rhs)
{
m_start_address = rhs.m_start_address;
m_cfa = rhs.m_cfa;
m_inline_height = rhs.m_inline_height;
}
return *this;
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
StackID::~StackID()
{
}
bool
lldb_private::operator== (const StackID& lhs, const StackID& rhs)
{
return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() &&
lhs.GetInlineHeight() == rhs.GetInlineHeight() &&
lhs.GetStartAddress() == rhs.GetStartAddress();
return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() &&
lhs.GetInlineBlockID() == rhs.GetInlineBlockID() &&
lhs.GetStartAddress() == rhs.GetStartAddress();
}
bool
lldb_private::operator!= (const StackID& lhs, const StackID& rhs)
{
return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() ||
lhs.GetInlineHeight() != rhs.GetInlineHeight() ||
lhs.GetStartAddress() != rhs.GetStartAddress();
return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() ||
lhs.GetInlineBlockID() != rhs.GetInlineBlockID() ||
lhs.GetStartAddress() != rhs.GetStartAddress();
}
bool
lldb_private::operator< (const StackID& lhs, const StackID& rhs)
{
return lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress();
if (lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress())
return true;
return lhs.GetInlineBlockID() < rhs.GetInlineBlockID();
}

View File

@ -49,7 +49,7 @@ Thread::Thread (Process &process, lldb::tid_t tid) :
m_plan_stack (),
m_immediate_plan_stack(),
m_completed_plan_stack(),
m_frames_sp (),
m_curr_frames_ap (),
m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
m_resume_state (eStateRunning),
m_unwinder_ap ()
@ -796,9 +796,9 @@ Thread::Calculate (ExecutionContext &exe_ctx)
StackFrameList &
Thread::GetStackFrameList ()
{
if (m_frames_sp.get() == NULL)
m_frames_sp.reset (new StackFrameList (*this, true));
return *m_frames_sp;
if (m_curr_frames_ap.get() == NULL)
m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_ap.release(), true));
return *m_curr_frames_ap;
}
@ -813,8 +813,7 @@ Thread::GetStackFrameCount()
void
Thread::ClearStackFrames ()
{
if (m_frames_sp)
m_frames_sp->Clear();
m_prev_frames_ap = m_curr_frames_ap;
}
lldb::StackFrameSP