2010-06-09 00:52:24 +08:00
|
|
|
//===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-09 15:44:37 +08:00
|
|
|
#include "lldb/API/SBThread.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
#include "lldb/API/SBSymbolContext.h"
|
|
|
|
#include "lldb/API/SBFileSpec.h"
|
2010-09-20 13:20:02 +08:00
|
|
|
#include "lldb/API/SBStream.h"
|
2010-06-23 09:19:29 +08:00
|
|
|
#include "lldb/Core/Debugger.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/Stream.h"
|
|
|
|
#include "lldb/Core/StreamFile.h"
|
2010-06-23 09:19:29 +08:00
|
|
|
#include "lldb/Interpreter/CommandInterpreter.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Target/Thread.h"
|
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
#include "lldb/Symbol/SymbolContext.h"
|
|
|
|
#include "lldb/Symbol/CompileUnit.h"
|
2010-08-04 09:40:35 +08:00
|
|
|
#include "lldb/Target/StopInfo.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Target/Target.h"
|
|
|
|
#include "lldb/Target/ThreadPlan.h"
|
|
|
|
#include "lldb/Target/ThreadPlanStepInstruction.h"
|
|
|
|
#include "lldb/Target/ThreadPlanStepOut.h"
|
|
|
|
#include "lldb/Target/ThreadPlanStepRange.h"
|
|
|
|
#include "lldb/Target/ThreadPlanStepInRange.h"
|
|
|
|
|
|
|
|
|
2010-06-09 15:44:37 +08:00
|
|
|
#include "lldb/API/SBAddress.h"
|
|
|
|
#include "lldb/API/SBFrame.h"
|
|
|
|
#include "lldb/API/SBSourceManager.h"
|
|
|
|
#include "lldb/API/SBDebugger.h"
|
|
|
|
#include "lldb/API/SBProcess.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
SBThread::SBThread () :
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp ()
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::SBThread () ==> this = %p", this);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Thread constructor
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
SBThread::SBThread (const ThreadSP& lldb_object_sp) :
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp (lldb_object_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::SBThread (const ThreadSP &lldb_object_sp) lldb_object_sp.get() = %p ==> this = %p",
|
|
|
|
lldb_object_sp.get(), this);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SBThread::SBThread (const SBThread &rhs)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::SBThread (const SBThread &rhs) rhs.m_opaque_sp.get() = %p ==> this = %p",
|
|
|
|
rhs.m_opaque_sp.get(), this);
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp = rhs.m_opaque_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Destructor
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
SBThread::~SBThread()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBThread::IsValid() const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp != NULL;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2010-07-31 04:12:55 +08:00
|
|
|
void
|
|
|
|
SBThread::Clear ()
|
|
|
|
{
|
|
|
|
m_opaque_sp.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
StopReason
|
|
|
|
SBThread::GetStopReason()
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetStopReason ()");
|
|
|
|
|
|
|
|
StopReason reason = eStopReasonInvalid;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-20 08:39:53 +08:00
|
|
|
StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
|
|
|
|
if (stop_info_sp)
|
2010-10-26 11:11:13 +08:00
|
|
|
reason = stop_info_sp->GetStopReason();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2010-10-26 11:11:13 +08:00
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetStopReason ==> %s", Thread::StopReasonAsCString (reason));
|
|
|
|
|
|
|
|
return reason;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
SBThread::GetStopDescription (char *dst, size_t dst_len)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetStopDescription (char *dst, size_t dst_len)");
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-20 08:39:53 +08:00
|
|
|
StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
|
|
|
|
if (stop_info_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-20 08:39:53 +08:00
|
|
|
const char *stop_desc = stop_info_sp->GetDescription();
|
2010-06-09 00:52:24 +08:00
|
|
|
if (stop_desc)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetStopDescription ==> %s", stop_desc);
|
2010-06-09 00:52:24 +08:00
|
|
|
if (dst)
|
|
|
|
return ::snprintf (dst, dst_len, "%s", stop_desc);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// NULL dst passed in, return the length needed to contain the description
|
|
|
|
return ::strlen (stop_desc) + 1; // Include the NULL byte for size
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_t stop_desc_len = 0;
|
2010-10-20 08:39:53 +08:00
|
|
|
switch (stop_info_sp->GetStopReason())
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
case eStopReasonTrace:
|
|
|
|
case eStopReasonPlanComplete:
|
|
|
|
{
|
|
|
|
static char trace_desc[] = "step";
|
|
|
|
stop_desc = trace_desc;
|
|
|
|
stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eStopReasonBreakpoint:
|
|
|
|
{
|
|
|
|
static char bp_desc[] = "breakpoint hit";
|
|
|
|
stop_desc = bp_desc;
|
|
|
|
stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eStopReasonWatchpoint:
|
|
|
|
{
|
|
|
|
static char wp_desc[] = "watchpoint hit";
|
|
|
|
stop_desc = wp_desc;
|
|
|
|
stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eStopReasonSignal:
|
|
|
|
{
|
2010-10-20 08:39:53 +08:00
|
|
|
stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
|
2010-06-09 00:52:24 +08:00
|
|
|
if (stop_desc == NULL || stop_desc[0] == '\0')
|
|
|
|
{
|
|
|
|
static char signal_desc[] = "signal";
|
|
|
|
stop_desc = signal_desc;
|
|
|
|
stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eStopReasonException:
|
|
|
|
{
|
|
|
|
char exc_desc[] = "exception";
|
|
|
|
stop_desc = exc_desc;
|
|
|
|
stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
|
|
|
|
}
|
2010-07-10 04:39:50 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (stop_desc && stop_desc[0])
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetStopDescription ==> %s", stop_desc);
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (dst)
|
|
|
|
return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
|
|
|
|
|
|
|
|
if (stop_desc_len == 0)
|
|
|
|
stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
|
|
|
|
|
|
|
|
return stop_desc_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (dst)
|
|
|
|
*dst = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SBThread::SetThread (const ThreadSP& lldb_object_sp)
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp = lldb_object_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lldb::tid_t
|
|
|
|
SBThread::GetThreadID () const
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetThreadID()");
|
|
|
|
|
|
|
|
lldb::tid_t id = LLDB_INVALID_THREAD_ID;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-10-26 11:11:13 +08:00
|
|
|
id = m_opaque_sp->GetID();
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetThreadID ==> %d", id);
|
|
|
|
|
|
|
|
return id;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
SBThread::GetIndexID () const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
return m_opaque_sp->GetIndexID();
|
2010-06-09 00:52:24 +08:00
|
|
|
return LLDB_INVALID_INDEX32;
|
|
|
|
}
|
|
|
|
const char *
|
|
|
|
SBThread::GetName () const
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetName ()");
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-10-26 11:11:13 +08:00
|
|
|
{
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetName ==> %s", m_opaque_sp->GetName());
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp->GetName();
|
2010-10-26 11:11:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetName ==> NULL");
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
SBThread::GetQueueName () const
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetQueueName ()");
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-10-26 11:11:13 +08:00
|
|
|
{
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetQueueName ==> %s", m_opaque_sp->GetQueueName());
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp->GetQueueName();
|
2010-10-26 11:11:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetQueueName ==> NULL");
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
SBThread::StepOver (lldb::RunMode stop_other_threads)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::StepOver (lldb::RunMode stop_other_threads) stop_other_threads = %s)",
|
|
|
|
Thread::RunModeAsCString (stop_other_threads));
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
bool abort_other_plans = true;
|
2010-06-23 09:19:29 +08:00
|
|
|
StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
if (frame_sp)
|
|
|
|
{
|
|
|
|
if (frame_sp->HasDebugInformation ())
|
|
|
|
{
|
|
|
|
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
|
2010-10-06 11:53:16 +08:00
|
|
|
eStepTypeOver,
|
|
|
|
sc.line_entry.range,
|
|
|
|
sc,
|
|
|
|
stop_other_threads,
|
|
|
|
false);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true,
|
2010-10-06 11:53:16 +08:00
|
|
|
abort_other_plans,
|
|
|
|
stop_other_threads);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
Process &process = m_opaque_sp->GetProcess();
|
2010-06-09 00:52:24 +08:00
|
|
|
// Why do we need to set the current thread by ID here???
|
2010-08-27 05:32:51 +08:00
|
|
|
process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
|
2010-10-06 11:53:16 +08:00
|
|
|
Error error (process.Resume());
|
|
|
|
if (error.Success())
|
|
|
|
{
|
|
|
|
// If we are doing synchronous mode, then wait for the
|
|
|
|
// process to stop yet again!
|
|
|
|
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
|
|
|
process.WaitForProcessToStop (NULL);
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SBThread::StepInto (lldb::RunMode stop_other_threads)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::StepInto (lldb::RunMode stop_other_threads) stop_other_threads =%s",
|
|
|
|
Thread::RunModeAsCString (stop_other_threads));
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
bool abort_other_plans = true;
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
if (frame_sp && frame_sp->HasDebugInformation ())
|
|
|
|
{
|
2010-06-13 02:59:55 +08:00
|
|
|
bool avoid_code_without_debug_info = true;
|
2010-06-09 00:52:24 +08:00
|
|
|
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
|
2010-10-06 11:53:16 +08:00
|
|
|
eStepTypeInto,
|
|
|
|
sc.line_entry.range,
|
|
|
|
sc,
|
|
|
|
stop_other_threads,
|
|
|
|
avoid_code_without_debug_info);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
|
2010-10-06 11:53:16 +08:00
|
|
|
abort_other_plans,
|
|
|
|
stop_other_threads);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
Process &process = m_opaque_sp->GetProcess();
|
2010-06-09 00:52:24 +08:00
|
|
|
// Why do we need to set the current thread by ID here???
|
2010-08-27 05:32:51 +08:00
|
|
|
process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
|
2010-10-06 11:53:16 +08:00
|
|
|
Error error (process.Resume());
|
|
|
|
if (error.Success())
|
|
|
|
{
|
|
|
|
// If we are doing synchronous mode, then wait for the
|
|
|
|
// process to stop yet again!
|
|
|
|
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
|
|
|
process.WaitForProcessToStop (NULL);
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SBThread::StepOut ()
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::StepOut ()");
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
bool abort_other_plans = true;
|
|
|
|
bool stop_other_threads = true;
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
Process &process = m_opaque_sp->GetProcess();
|
2010-08-27 05:32:51 +08:00
|
|
|
process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
|
2010-10-06 11:53:16 +08:00
|
|
|
Error error (process.Resume());
|
|
|
|
if (error.Success())
|
|
|
|
{
|
|
|
|
// If we are doing synchronous mode, then wait for the
|
|
|
|
// process to stop yet again!
|
|
|
|
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
|
|
|
process.WaitForProcessToStop (NULL);
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SBThread::StepInstruction (bool step_over)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::StepInstruction (bool step_over) step_over = %s", (step_over ? "true" : "false"));
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
|
|
|
|
Process &process = m_opaque_sp->GetProcess();
|
2010-08-27 05:32:51 +08:00
|
|
|
process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
|
2010-10-06 11:53:16 +08:00
|
|
|
Error error (process.Resume());
|
|
|
|
if (error.Success())
|
|
|
|
{
|
|
|
|
// If we are doing synchronous mode, then wait for the
|
|
|
|
// process to stop yet again!
|
|
|
|
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
|
|
|
process.WaitForProcessToStop (NULL);
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SBThread::RunToAddress (lldb::addr_t addr)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::RunToAddress (lldb:;addr_t addr) addr = %p", addr);
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
bool abort_other_plans = true;
|
|
|
|
bool stop_other_threads = true;
|
|
|
|
|
|
|
|
Address target_addr (NULL, addr);
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
|
|
|
|
Process &process = m_opaque_sp->GetProcess();
|
2010-08-27 05:32:51 +08:00
|
|
|
process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
|
2010-10-06 11:53:16 +08:00
|
|
|
Error error (process.Resume());
|
|
|
|
if (error.Success())
|
|
|
|
{
|
|
|
|
// If we are doing synchronous mode, then wait for the
|
|
|
|
// process to stop yet again!
|
|
|
|
if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
|
|
|
|
process.WaitForProcessToStop (NULL);
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SBProcess
|
|
|
|
SBThread::GetProcess ()
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetProcess ()");
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
SBProcess process;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
// Have to go up to the target so we can get a shared pointer to our process...
|
2010-06-23 09:19:29 +08:00
|
|
|
process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2010-10-26 11:11:13 +08:00
|
|
|
|
|
|
|
if (log)
|
|
|
|
{
|
|
|
|
SBStream sstr;
|
|
|
|
process.GetDescription (sstr);
|
|
|
|
log->Printf ("SBThread::GetProcess ==> SBProcess (this = %p, '%s')", &process, sstr.GetData());
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
return process;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
SBThread::GetNumFrames ()
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetNumFrames ()");
|
|
|
|
|
|
|
|
uint32_t num_frames = 0;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-10-26 11:11:13 +08:00
|
|
|
num_frames = m_opaque_sp->GetStackFrameCount();
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetNumFrames ==> %d", num_frames);
|
|
|
|
|
|
|
|
return num_frames;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SBFrame
|
|
|
|
SBThread::GetFrameAtIndex (uint32_t idx)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::GetFrameAtIndex (uint32_t idx) idx = %d", idx);
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
SBFrame sb_frame;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
|
2010-10-26 11:11:13 +08:00
|
|
|
|
|
|
|
if (log)
|
|
|
|
{
|
|
|
|
SBStream sstr;
|
|
|
|
sb_frame.GetDescription (sstr);
|
|
|
|
log->Printf ("SBThread::GetFrameAtIndex ==> SBFrame (this = %p, '%s')", &sb_frame, sstr.GetData());
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
return sb_frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
const lldb::SBThread &
|
|
|
|
SBThread::operator = (const lldb::SBThread &rhs)
|
|
|
|
{
|
2010-10-26 11:11:13 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf ("SBThread::operator= (const lldb::SBThread &rhs) rhs.m_opaque_sp.get() = %p ==> this = %p",
|
|
|
|
rhs.m_opaque_sp.get(), this);
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp = rhs.m_opaque_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBThread::operator == (const SBThread &rhs) const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get() == rhs.m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBThread::operator != (const SBThread &rhs) const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get() != rhs.m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
lldb_private::Thread *
|
|
|
|
SBThread::GetLLDBObjectPtr ()
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const lldb_private::Thread *
|
|
|
|
SBThread::operator->() const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const lldb_private::Thread &
|
|
|
|
SBThread::operator*() const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return *m_opaque_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
lldb_private::Thread *
|
|
|
|
SBThread::operator->()
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
lldb_private::Thread &
|
|
|
|
SBThread::operator*()
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return *m_opaque_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2010-09-20 13:20:02 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
SBThread::GetDescription (SBStream &description)
|
|
|
|
{
|
|
|
|
if (m_opaque_sp)
|
2010-10-07 12:19:01 +08:00
|
|
|
{
|
|
|
|
StreamString strm;
|
|
|
|
description.Printf("SBThread: tid = 0x%4.4x", m_opaque_sp->GetID());
|
|
|
|
}
|
2010-09-20 13:20:02 +08:00
|
|
|
else
|
|
|
|
description.Printf ("No value");
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2010-10-26 11:11:13 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
SBThread::GetDescription (SBStream &description) const
|
|
|
|
{
|
|
|
|
if (m_opaque_sp)
|
|
|
|
{
|
|
|
|
StreamString strm;
|
|
|
|
description.Printf("SBThread: tid = 0x%4.4x", m_opaque_sp->GetID());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
description.Printf ("No value");
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|