mirror of
https://github.com/intel/llvm.git
synced 2026-01-23 07:58:23 +08:00
Now that we are using the Unwinder (or Jason's new unwinder when that comes about) all the plugin-specific details of getting stack frames
should be hidden behind that, and the "GetStackFrameAtIndex" and "GetStackFrameCount" algorithms become generic. So I moved them to Thread.cpp. llvm-svn: 110899
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "lldb/Core/UserID.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
#include "lldb/Target/StackFrameList.h"
|
||||
#include "libunwind/include/libunwind.h"
|
||||
|
||||
#define LLDB_THREAD_MAX_STOP_EXC_DATA 8
|
||||
|
||||
@@ -298,10 +299,10 @@ public:
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetStackFrameCount() = 0;
|
||||
GetStackFrameCount();
|
||||
|
||||
virtual lldb::StackFrameSP
|
||||
GetStackFrameAtIndex (uint32_t idx) = 0;
|
||||
GetStackFrameAtIndex (uint32_t idx);
|
||||
|
||||
lldb::StackFrameSP
|
||||
GetCurrentFrame ();
|
||||
@@ -661,6 +662,9 @@ protected:
|
||||
|
||||
typedef std::vector<lldb::ThreadPlanSP> plan_stack;
|
||||
|
||||
virtual lldb_private::Unwind *
|
||||
GetUnwinder () = 0;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from Process can see and modify these
|
||||
//------------------------------------------------------------------
|
||||
@@ -679,6 +683,7 @@ protected:
|
||||
uint32_t m_current_frame_idx;///< The current frame for this thread
|
||||
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;
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
// For Thread only
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Breakpoint/WatchpointLocation.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Target/Unwind.h"
|
||||
#include "LibUnwindRegisterContext.h"
|
||||
#include "UnwindLibUnwind.h"
|
||||
#include "UnwindMacOSXFrameBackchain.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
@@ -203,53 +207,27 @@ ThreadMacOSX::RefreshStateAfterStop()
|
||||
m_basic_info_string.clear();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ThreadMacOSX::GetStackFrameCount()
|
||||
Unwind *
|
||||
ThreadMacOSX::GetUnwinder ()
|
||||
{
|
||||
if (m_fp_pc_pairs.empty())
|
||||
GetStackFrameData(m_fp_pc_pairs);
|
||||
return m_fp_pc_pairs.size();
|
||||
if (m_unwinder_ap.get() == NULL)
|
||||
{
|
||||
const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
|
||||
#if 0 // Not sure this is the right thing to do for native, but this will all go away with Jason's new
|
||||
// unwinder anyway...
|
||||
if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386"))
|
||||
{
|
||||
m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace()));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
|
||||
}
|
||||
}
|
||||
return m_unwinder_ap.get();
|
||||
}
|
||||
|
||||
// Make sure that GetStackFrameAtIndex() does NOT call GetStackFrameCount() when
|
||||
// getting the stack frame at index zero! This way GetStackFrameCount() (via
|
||||
// GetStackFRameData()) can call this function to get the first frame in order
|
||||
// to provide the first frame to a lower call for efficiency sake (avoid
|
||||
// redundant lookups in the frame symbol context).
|
||||
lldb::StackFrameSP
|
||||
ThreadMacOSX::GetStackFrameAtIndex (uint32_t idx)
|
||||
{
|
||||
StackFrameSP frame_sp(m_frames.GetFrameAtIndex(idx));
|
||||
|
||||
if (frame_sp)
|
||||
return frame_sp;
|
||||
|
||||
// Don't try and fetch a frame while process is running
|
||||
// Calling IsRunning isn't right here, because IsRunning reads the Public
|
||||
// state but we need to be able to read the stack frames in the ShouldStop
|
||||
// methods, which happen before the Public state has been updated.
|
||||
// if (m_process.IsRunning())
|
||||
// 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.
|
||||
GetRegisterContext();
|
||||
assert (m_reg_context_sp.get());
|
||||
frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetFP(), m_reg_context_sp->GetPC()));
|
||||
}
|
||||
else if (idx < GetStackFrameCount())
|
||||
{
|
||||
assert (idx < m_fp_pc_pairs.size());
|
||||
frame_sp.reset (new StackFrame (idx, *this, m_fp_pc_pairs[idx].first, m_fp_pc_pairs[idx].second));
|
||||
}
|
||||
m_frames.SetFrameAtIndex(idx, frame_sp);
|
||||
return frame_sp;
|
||||
}
|
||||
|
||||
void
|
||||
ThreadMacOSX::ClearStackFrames ()
|
||||
|
||||
@@ -51,12 +51,6 @@ public:
|
||||
virtual bool
|
||||
RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint);
|
||||
|
||||
virtual uint32_t
|
||||
GetStackFrameCount();
|
||||
|
||||
virtual lldb::StackFrameSP
|
||||
GetStackFrameAtIndex (uint32_t idx);
|
||||
|
||||
virtual void
|
||||
ClearStackFrames ();
|
||||
|
||||
@@ -139,6 +133,9 @@ protected:
|
||||
static bool
|
||||
GetBasicInfo (lldb::tid_t threadID, struct thread_basic_info *basic_info);
|
||||
|
||||
virtual lldb_private::Unwind *
|
||||
GetUnwinder ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
@@ -38,8 +38,7 @@ ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) :
|
||||
Thread(process, tid),
|
||||
m_thread_name (),
|
||||
m_dispatch_queue_name (),
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
|
||||
m_unwinder_ap ()
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
// ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID());
|
||||
ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
|
||||
@@ -136,61 +135,6 @@ ThreadGDBRemote::GetUnwinder ()
|
||||
return m_unwinder_ap.get();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ThreadGDBRemote::GetStackFrameCount()
|
||||
{
|
||||
Unwind *unwinder = GetUnwinder ();
|
||||
if (unwinder)
|
||||
return unwinder->GetFrameCount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make sure that GetStackFrameAtIndex() does NOT call GetStackFrameCount() when
|
||||
// getting the stack frame at index zero! This way GetStackFrameCount() (via
|
||||
// GetStackFRameData()) can call this function to get the first frame in order
|
||||
// to provide the first frame to a lower call for efficiency sake (avoid
|
||||
// redundant lookups in the frame symbol context).
|
||||
lldb::StackFrameSP
|
||||
ThreadGDBRemote::GetStackFrameAtIndex (uint32_t idx)
|
||||
{
|
||||
|
||||
StackFrameSP frame_sp (m_frames.GetFrameAtIndex(idx));
|
||||
|
||||
if (frame_sp.get())
|
||||
return frame_sp;
|
||||
|
||||
// Don't try and fetch a frame while process is running
|
||||
// FIXME: This check isn't right because IsRunning checks the Public state, but this
|
||||
// is work you need to do - for instance in ShouldStop & friends - before the public
|
||||
// state has been changed.
|
||||
// if (m_process.IsRunning())
|
||||
// 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.
|
||||
GetRegisterContext();
|
||||
assert (m_reg_context_sp.get());
|
||||
frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), m_reg_context_sp->GetPC()));
|
||||
}
|
||||
else if (idx < GetStackFrameCount())
|
||||
{
|
||||
Unwind *unwinder = GetUnwinder ();
|
||||
if (unwinder)
|
||||
{
|
||||
addr_t pc, cfa;
|
||||
if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
|
||||
frame_sp.reset (new StackFrame (idx, *this, cfa, pc));
|
||||
}
|
||||
}
|
||||
m_frames.SetFrameAtIndex(idx, frame_sp);
|
||||
return frame_sp;
|
||||
}
|
||||
|
||||
void
|
||||
ThreadGDBRemote::ClearStackFrames ()
|
||||
{
|
||||
|
||||
@@ -54,12 +54,6 @@ public:
|
||||
virtual bool
|
||||
RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint);
|
||||
|
||||
virtual uint32_t
|
||||
GetStackFrameCount();
|
||||
|
||||
virtual lldb::StackFrameSP
|
||||
GetStackFrameAtIndex (uint32_t idx);
|
||||
|
||||
virtual void
|
||||
ClearStackFrames ();
|
||||
|
||||
@@ -121,12 +115,11 @@ protected:
|
||||
std::string m_thread_name;
|
||||
std::string m_dispatch_queue_name;
|
||||
lldb::addr_t m_thread_dispatch_qaddr;
|
||||
std::auto_ptr<lldb_private::Unwind> m_unwinder_ap;
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
lldb_private::Unwind *
|
||||
virtual lldb_private::Unwind *
|
||||
GetUnwinder ();
|
||||
|
||||
void
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "lldb/Target/ThreadPlanRunToAddress.h"
|
||||
#include "lldb/Target/ThreadPlanStepUntil.h"
|
||||
#include "lldb/Target/ThreadSpec.h"
|
||||
#include "lldb/Target/Unwind.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
@@ -51,7 +52,9 @@ Thread::Thread (Process &process, lldb::tid_t tid) :
|
||||
m_frames (),
|
||||
m_current_frame_idx (0),
|
||||
m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
|
||||
m_resume_state (eStateRunning)
|
||||
m_resume_state (eStateRunning),
|
||||
m_unwinder_ap ()
|
||||
|
||||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
|
||||
if (log)
|
||||
@@ -790,6 +793,56 @@ Thread::Calculate (ExecutionContext &exe_ctx)
|
||||
exe_ctx.frame = NULL;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Thread::GetStackFrameCount()
|
||||
{
|
||||
Unwind *unwinder = GetUnwinder ();
|
||||
if (unwinder)
|
||||
return unwinder->GetFrameCount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
lldb::StackFrameSP
|
||||
Thread::GetStackFrameAtIndex (uint32_t idx)
|
||||
{
|
||||
|
||||
StackFrameSP frame_sp (m_frames.GetFrameAtIndex(idx));
|
||||
|
||||
if (frame_sp.get())
|
||||
return frame_sp;
|
||||
|
||||
// Don't try and fetch a frame while process is running
|
||||
// FIXME: This check isn't right because IsRunning checks the Public state, but this
|
||||
// is work you need to do - for instance in ShouldStop & friends - before the public
|
||||
// state has been changed.
|
||||
// if (m_process.IsRunning())
|
||||
// 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.
|
||||
GetRegisterContext();
|
||||
assert (m_reg_context_sp.get());
|
||||
frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), m_reg_context_sp->GetPC()));
|
||||
}
|
||||
else if (idx < GetStackFrameCount())
|
||||
{
|
||||
Unwind *unwinder = GetUnwinder ();
|
||||
if (unwinder)
|
||||
{
|
||||
addr_t pc, cfa;
|
||||
if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
|
||||
frame_sp.reset (new StackFrame (idx, *this, cfa, pc));
|
||||
}
|
||||
}
|
||||
m_frames.SetFrameAtIndex(idx, frame_sp);
|
||||
return frame_sp;
|
||||
}
|
||||
|
||||
lldb::StackFrameSP
|
||||
Thread::GetCurrentFrame ()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user