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.
//
//===----------------------------------------------------------------------===//
2012-12-05 08:20:57 +08:00
# include "lldb/lldb-python.h"
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-11-19 02:52:36 +08:00
# include "lldb/Breakpoint/BreakpointLocation.h"
2010-06-23 09:19:29 +08:00
# include "lldb/Core/Debugger.h"
2013-04-16 07:33:53 +08:00
# include "lldb/Core/State.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"
2013-11-06 08:04:44 +08:00
# include "lldb/Target/SystemRuntime.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/SBDebugger.h"
2012-10-11 02:32:14 +08:00
# include "lldb/API/SBEvent.h"
2011-12-17 09:35:57 +08:00
# include "lldb/API/SBFrame.h"
2010-06-09 15:44:37 +08:00
# include "lldb/API/SBProcess.h"
2011-12-17 09:35:57 +08:00
# include "lldb/API/SBValue.h"
2010-06-09 00:52:24 +08:00
using namespace lldb ;
using namespace lldb_private ;
2012-10-11 02:32:14 +08:00
const char *
SBThread : : GetBroadcasterClassName ( )
{
return Thread : : GetStaticBroadcasterClass ( ) . AsCString ( ) ;
}
2010-10-31 11:01:06 +08:00
//----------------------------------------------------------------------
// Constructors
//----------------------------------------------------------------------
2010-06-09 00:52:24 +08:00
SBThread : : SBThread ( ) :
2012-04-06 00:12:35 +08:00
m_opaque_sp ( new ExecutionContextRef ( ) )
2010-06-09 00:52:24 +08:00
{
}
SBThread : : SBThread ( const ThreadSP & lldb_object_sp ) :
2012-04-06 00:12:35 +08:00
m_opaque_sp ( new ExecutionContextRef ( lldb_object_sp ) )
2010-06-09 00:52:24 +08:00
{
}
2010-10-31 02:26:59 +08:00
SBThread : : SBThread ( const SBThread & rhs ) :
2012-04-06 00:12:35 +08:00
m_opaque_sp ( new ExecutionContextRef ( * rhs . m_opaque_sp ) )
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
2010-06-09 00:52:24 +08:00
}
2010-10-31 11:01:06 +08:00
//----------------------------------------------------------------------
// Assignment operator
//----------------------------------------------------------------------
const lldb : : SBThread &
SBThread : : operator = ( const SBThread & rhs )
{
if ( this ! = & rhs )
2012-04-06 00:12:35 +08:00
* m_opaque_sp = * rhs . m_opaque_sp ;
2010-10-31 11:01:06 +08:00
return * this ;
}
2010-06-09 00:52:24 +08:00
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SBThread : : ~ SBThread ( )
{
}
bool
SBThread : : IsValid ( ) const
{
2012-04-06 00:12:35 +08:00
return m_opaque_sp - > GetThreadSP ( ) . get ( ) ! = NULL ;
2010-06-09 00:52:24 +08:00
}
2010-07-31 04:12:55 +08:00
void
SBThread : : Clear ( )
{
2012-04-06 00:12:35 +08:00
m_opaque_sp - > Clear ( ) ;
2010-07-31 04:12:55 +08:00
}
2010-06-09 00:52:24 +08:00
StopReason
SBThread : : GetStopReason ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
StopReason reason = eStopReasonInvalid ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
2012-09-25 10:40:06 +08:00
return exe_ctx . GetThreadPtr ( ) - > GetStopReason ( ) ;
2012-04-06 00:12:35 +08:00
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetStopReason() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-06-09 00:52:24 +08:00
}
2010-10-26 11:11:13 +08:00
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::GetStopReason () => %s " , exe_ctx . GetThreadPtr ( ) ,
2010-10-27 07:49:36 +08:00
Thread : : StopReasonAsCString ( reason ) ) ;
2010-10-26 11:11:13 +08:00
return reason ;
2010-06-09 00:52:24 +08:00
}
2010-11-19 02:52:36 +08:00
size_t
SBThread : : GetStopReasonDataCount ( )
{
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
StopInfoSP stop_info_sp = exe_ctx . GetThreadPtr ( ) - > GetStopInfo ( ) ;
if ( stop_info_sp )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
StopReason reason = stop_info_sp - > GetStopReason ( ) ;
switch ( reason )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
case eStopReasonInvalid :
case eStopReasonNone :
case eStopReasonTrace :
2012-12-05 08:16:59 +08:00
case eStopReasonExec :
2012-04-06 00:12:35 +08:00
case eStopReasonPlanComplete :
2012-12-21 07:08:03 +08:00
case eStopReasonThreadExiting :
2012-04-06 00:12:35 +08:00
// There is no data for these stop reasons.
return 0 ;
case eStopReasonBreakpoint :
{
break_id_t site_id = stop_info_sp - > GetValue ( ) ;
lldb : : BreakpointSiteSP bp_site_sp ( exe_ctx . GetProcessPtr ( ) - > GetBreakpointSiteList ( ) . FindByID ( site_id ) ) ;
if ( bp_site_sp )
return bp_site_sp - > GetNumberOfOwners ( ) * 2 ;
else
return 0 ; // Breakpoint must have cleared itself...
}
break ;
2010-11-19 02:52:36 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonWatchpoint :
return 1 ;
2010-11-19 02:52:36 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonSignal :
return 1 ;
2010-11-19 02:52:36 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonException :
return 1 ;
}
2010-11-19 02:52:36 +08:00
}
}
2012-04-06 10:17:47 +08:00
else
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2012-04-06 10:17:47 +08:00
if ( log )
log - > Printf ( " SBThread(%p)::GetStopReasonDataCount() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-11-19 02:52:36 +08:00
}
return 0 ;
}
uint64_t
SBThread : : GetStopReasonDataAtIndex ( uint32_t idx )
{
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
StopInfoSP stop_info_sp = thread - > GetStopInfo ( ) ;
if ( stop_info_sp )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
StopReason reason = stop_info_sp - > GetStopReason ( ) ;
switch ( reason )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
case eStopReasonInvalid :
case eStopReasonNone :
case eStopReasonTrace :
2012-12-05 08:16:59 +08:00
case eStopReasonExec :
2012-04-06 00:12:35 +08:00
case eStopReasonPlanComplete :
2012-12-21 07:08:03 +08:00
case eStopReasonThreadExiting :
2012-04-06 00:12:35 +08:00
// There is no data for these stop reasons.
return 0 ;
case eStopReasonBreakpoint :
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
break_id_t site_id = stop_info_sp - > GetValue ( ) ;
lldb : : BreakpointSiteSP bp_site_sp ( exe_ctx . GetProcessPtr ( ) - > GetBreakpointSiteList ( ) . FindByID ( site_id ) ) ;
if ( bp_site_sp )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
uint32_t bp_index = idx / 2 ;
BreakpointLocationSP bp_loc_sp ( bp_site_sp - > GetOwnerAtIndex ( bp_index ) ) ;
if ( bp_loc_sp )
2010-11-19 02:52:36 +08:00
{
2012-04-06 00:12:35 +08:00
if ( bp_index & 1 )
{
// Odd idx, return the breakpoint location ID
return bp_loc_sp - > GetID ( ) ;
}
else
{
// Even idx, return the breakpoint ID
return bp_loc_sp - > GetBreakpoint ( ) . GetID ( ) ;
}
2010-11-19 02:52:36 +08:00
}
}
2012-04-06 00:12:35 +08:00
return LLDB_INVALID_BREAK_ID ;
2010-11-19 02:52:36 +08:00
}
2012-04-06 00:12:35 +08:00
break ;
2010-11-19 02:52:36 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonWatchpoint :
return stop_info_sp - > GetValue ( ) ;
2010-11-19 02:52:36 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonSignal :
return stop_info_sp - > GetValue ( ) ;
2010-11-19 02:52:36 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonException :
return stop_info_sp - > GetValue ( ) ;
}
2010-11-19 02:52:36 +08:00
}
}
2012-04-06 10:17:47 +08:00
else
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2012-04-06 10:17:47 +08:00
if ( log )
log - > Printf ( " SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-11-19 02:52:36 +08:00
}
return 0 ;
}
2010-06-09 00:52:24 +08:00
size_t
SBThread : : GetStopDescription ( char * dst , size_t dst_len )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
StopInfoSP stop_info_sp = exe_ctx . GetThreadPtr ( ) - > GetStopInfo ( ) ;
if ( stop_info_sp )
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
const char * stop_desc = stop_info_sp - > GetDescription ( ) ;
if ( stop_desc )
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
if ( log )
log - > Printf ( " SBThread(%p)::GetStopDescription (dst, dst_len) => \" %s \" " ,
exe_ctx . GetThreadPtr ( ) , stop_desc ) ;
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
}
2010-06-09 00:52:24 +08:00
}
2012-04-06 00:12:35 +08:00
else
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
size_t stop_desc_len = 0 ;
switch ( stop_info_sp - > GetStopReason ( ) )
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +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 ;
2010-06-09 00:52:24 +08:00
2012-04-06 00:12:35 +08:00
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 ;
2010-06-09 00:52:24 +08:00
2012-04-06 00:12:35 +08:00
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 ;
2010-06-09 00:52:24 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonSignal :
2010-06-09 00:52:24 +08:00
{
2012-04-06 00:12:35 +08:00
stop_desc = exe_ctx . GetProcessPtr ( ) - > GetUnixSignals ( ) . GetSignalAsCString ( stop_info_sp - > GetValue ( ) ) ;
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
}
2010-06-09 00:52:24 +08:00
}
2012-04-06 00:12:35 +08:00
break ;
2010-06-09 00:52:24 +08:00
2012-04-06 00:12:35 +08:00
case eStopReasonException :
{
char exc_desc [ ] = " exception " ;
stop_desc = exc_desc ;
stop_desc_len = sizeof ( exc_desc ) ; // Include the NULL byte for size
}
break ;
2010-07-10 04:39:50 +08:00
2012-12-05 08:16:59 +08:00
case eStopReasonExec :
{
char exc_desc [ ] = " exec " ;
stop_desc = exc_desc ;
stop_desc_len = sizeof ( exc_desc ) ; // Include the NULL byte for size
}
break ;
2012-12-21 07:08:03 +08:00
case eStopReasonThreadExiting :
{
char limbo_desc [ ] = " thread exiting " ;
stop_desc = limbo_desc ;
stop_desc_len = sizeof ( limbo_desc ) ;
}
break ;
2012-04-06 00:12:35 +08:00
default :
break ;
}
if ( stop_desc & & stop_desc [ 0 ] )
{
if ( log )
log - > Printf ( " SBThread(%p)::GetStopDescription (dst, dst_len) => '%s' " ,
exe_ctx . GetThreadPtr ( ) , stop_desc ) ;
2010-10-26 11:11:13 +08:00
2012-04-06 00:12:35 +08:00
if ( dst )
return : : snprintf ( dst , dst_len , " %s " , stop_desc ) + 1 ; // Include the NULL byte
2010-06-09 00:52:24 +08:00
2012-04-06 00:12:35 +08:00
if ( stop_desc_len = = 0 )
stop_desc_len = : : strlen ( stop_desc ) + 1 ; // Include the NULL byte
return stop_desc_len ;
}
2010-06-09 00:52:24 +08:00
}
}
}
2012-04-06 10:17:47 +08:00
else
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2012-04-06 10:17:47 +08:00
if ( log )
log - > Printf ( " SBThread(%p)::GetStopDescription() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-06-09 00:52:24 +08:00
}
if ( dst )
* dst = 0 ;
return 0 ;
}
2011-12-17 09:35:57 +08:00
SBValue
SBThread : : GetStopReturnValue ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2011-12-17 09:35:57 +08:00
ValueObjectSP return_valobj_sp ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2011-12-17 09:35:57 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
2011-12-17 09:35:57 +08:00
{
2012-04-06 00:12:35 +08:00
StopInfoSP stop_info_sp = exe_ctx . GetThreadPtr ( ) - > GetStopInfo ( ) ;
if ( stop_info_sp )
{
return_valobj_sp = StopInfo : : GetReturnValueObject ( stop_info_sp ) ;
}
2011-12-17 09:35:57 +08:00
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetStopReturnValue() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2011-12-17 09:35:57 +08:00
}
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::GetStopReturnValue () => %s " , exe_ctx . GetThreadPtr ( ) ,
2011-12-17 09:35:57 +08:00
return_valobj_sp . get ( )
? return_valobj_sp - > GetValueAsCString ( )
: " <no return value> " ) ;
return SBValue ( return_valobj_sp ) ;
}
2010-06-09 00:52:24 +08:00
void
SBThread : : SetThread ( const ThreadSP & lldb_object_sp )
{
2012-04-06 00:12:35 +08:00
m_opaque_sp - > SetThreadSP ( lldb_object_sp ) ;
2010-06-09 00:52:24 +08:00
}
lldb : : tid_t
SBThread : : GetThreadID ( ) const
{
2012-04-06 00:12:35 +08:00
ThreadSP thread_sp ( m_opaque_sp - > GetThreadSP ( ) ) ;
2012-01-30 10:53:15 +08:00
if ( thread_sp )
2012-02-21 08:09:25 +08:00
return thread_sp - > GetID ( ) ;
return LLDB_INVALID_THREAD_ID ;
2010-06-09 00:52:24 +08:00
}
uint32_t
SBThread : : GetIndexID ( ) const
{
2012-04-06 00:12:35 +08:00
ThreadSP thread_sp ( m_opaque_sp - > GetThreadSP ( ) ) ;
2012-01-30 10:53:15 +08:00
if ( thread_sp )
return thread_sp - > GetIndexID ( ) ;
2010-06-09 00:52:24 +08:00
return LLDB_INVALID_INDEX32 ;
}
2012-02-21 08:09:25 +08:00
2010-06-09 00:52:24 +08:00
const char *
SBThread : : GetName ( ) const
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-30 12:51:46 +08:00
const char * name = NULL ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-12-21 04:49:23 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
name = exe_ctx . GetThreadPtr ( ) - > GetName ( ) ;
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetName() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-12-21 04:49:23 +08:00
}
2010-10-30 12:51:46 +08:00
2010-10-26 11:11:13 +08:00
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::GetName () => %s " , exe_ctx . GetThreadPtr ( ) , name ? name : " NULL " ) ;
2010-10-26 11:11:13 +08:00
2010-10-30 12:51:46 +08:00
return name ;
2010-06-09 00:52:24 +08:00
}
const char *
SBThread : : GetQueueName ( ) const
{
2010-10-30 12:51:46 +08:00
const char * name = NULL ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-12-21 04:49:23 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
name = exe_ctx . GetThreadPtr ( ) - > GetQueueName ( ) ;
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetQueueName() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-12-21 04:49:23 +08:00
}
2010-10-30 12:51:46 +08:00
2010-10-26 11:11:13 +08:00
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::GetQueueName () => %s " , exe_ctx . GetThreadPtr ( ) , name ? name : " NULL " ) ;
2010-10-26 11:11:13 +08:00
2010-10-30 12:51:46 +08:00
return name ;
2010-06-09 00:52:24 +08:00
}
2013-10-22 07:52:54 +08:00
lldb : : queue_id_t
SBThread : : GetQueueID ( ) const
{
queue_id_t id = LLDB_INVALID_QUEUE_ID ;
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
if ( exe_ctx . HasThreadScope ( ) )
{
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
id = exe_ctx . GetThreadPtr ( ) - > GetQueueID ( ) ;
}
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetQueueID() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
}
if ( log )
log - > Printf ( " SBThread(%p)::GetQueueID () => 0x% " PRIx64 , exe_ctx . GetThreadPtr ( ) , id ) ;
return id ;
}
2012-05-04 05:19:36 +08:00
SBError
SBThread : : ResumeNewPlan ( ExecutionContext & exe_ctx , ThreadPlan * new_plan )
{
SBError sb_error ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( ! process )
{
sb_error . SetErrorString ( " No process in SBThread::ResumeNewPlan " ) ;
return sb_error ;
}
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
if ( ! thread )
{
sb_error . SetErrorString ( " No thread in SBThread::ResumeNewPlan " ) ;
return sb_error ;
}
// User level plans should be Master Plans so they can be interrupted, other plans executed, and
// then a "continue" will resume the plan.
if ( new_plan ! = NULL )
{
new_plan - > SetIsMasterPlan ( true ) ;
new_plan - > SetOkayToDiscard ( false ) ;
}
// Why do we need to set the current thread by ID here???
process - > GetThreadList ( ) . SetSelectedThreadByID ( thread - > GetID ( ) ) ;
sb_error . ref ( ) = process - > Resume ( ) ;
if ( sb_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 ) ;
}
return sb_error ;
}
2010-06-09 00:52:24 +08:00
void
SBThread : : StepOver ( lldb : : RunMode stop_other_threads )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-01-30 10:53:15 +08:00
2010-10-26 11:11:13 +08:00
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::StepOver (stop_other_threads='%s') " , exe_ctx . GetThreadPtr ( ) ,
2010-10-26 11:11:13 +08:00
Thread : : RunModeAsCString ( stop_other_threads ) ) ;
2012-01-30 10:53:15 +08:00
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-06-09 00:52:24 +08:00
{
2012-02-21 08:09:25 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2012-05-12 07:47:32 +08:00
bool abort_other_plans = false ;
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ( thread - > GetStackFrameAtIndex ( 0 ) ) ;
2010-06-09 00:52:24 +08:00
2013-07-19 05:48:26 +08:00
ThreadPlanSP new_plan_sp ;
2010-06-09 00:52:24 +08:00
if ( frame_sp )
{
if ( frame_sp - > HasDebugInformation ( ) )
{
2014-03-13 10:47:14 +08:00
const LazyBool avoid_no_debug = eLazyBoolCalculate ;
2010-06-09 00:52:24 +08:00
SymbolContext sc ( frame_sp - > GetSymbolContext ( eSymbolContextEverything ) ) ;
2013-07-19 05:48:26 +08:00
new_plan_sp = thread - > QueueThreadPlanForStepOverRange ( abort_other_plans ,
Fixed a few bugs in the "step in" thread plan logic.
Added a "step-in-target" flag to "thread step-in" so if you have something like:
Process 28464 stopped
* thread #1: tid = 0x1c03, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000e08 a.out`main at main.c:62
61
-> 62 int A6 = complex (a(4), b(5), c(6)); // Stop here to step targetting b and hitting breakpoint.
63
and you want to get into "complex" skipping a, b and c, you can do:
(lldb) step -t complex
Process 28464 stopped
* thread #1: tid = 0x1c03, function: complex , stop reason = step in
frame #0: 0x0000000100000d0d a.out`complex at main.c:44
41
42 int complex (int first, int second, int third)
43 {
-> 44 return first + second + third; // Step in targetting complex should stop here
45 }
46
47 int main (int argc, char const *argv[])
llvm-svn: 170008
2012-12-13 03:58:40 +08:00
sc . line_entry . range ,
sc ,
2014-03-13 10:47:14 +08:00
stop_other_threads ,
avoid_no_debug ) ;
2010-06-09 00:52:24 +08:00
}
else
{
2013-07-19 05:48:26 +08:00
new_plan_sp = thread - > QueueThreadPlanForStepSingleInstruction ( true ,
2012-05-04 05:19:36 +08:00
abort_other_plans ,
stop_other_threads ) ;
2010-06-09 00:52:24 +08:00
}
}
2012-05-04 05:19:36 +08:00
// This returns an error, we should use it!
2013-07-19 05:48:26 +08:00
ResumeNewPlan ( exe_ctx , new_plan_sp . get ( ) ) ;
2010-06-09 00:52:24 +08:00
}
}
void
SBThread : : StepInto ( lldb : : RunMode stop_other_threads )
Fixed a few bugs in the "step in" thread plan logic.
Added a "step-in-target" flag to "thread step-in" so if you have something like:
Process 28464 stopped
* thread #1: tid = 0x1c03, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000e08 a.out`main at main.c:62
61
-> 62 int A6 = complex (a(4), b(5), c(6)); // Stop here to step targetting b and hitting breakpoint.
63
and you want to get into "complex" skipping a, b and c, you can do:
(lldb) step -t complex
Process 28464 stopped
* thread #1: tid = 0x1c03, function: complex , stop reason = step in
frame #0: 0x0000000100000d0d a.out`complex at main.c:44
41
42 int complex (int first, int second, int third)
43 {
-> 44 return first + second + third; // Step in targetting complex should stop here
45 }
46
47 int main (int argc, char const *argv[])
llvm-svn: 170008
2012-12-13 03:58:40 +08:00
{
StepInto ( NULL , stop_other_threads ) ;
}
void
SBThread : : StepInto ( const char * target_name , lldb : : RunMode stop_other_threads )
2010-06-09 00:52:24 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-01-30 10:53:15 +08:00
2010-10-26 11:11:13 +08:00
if ( log )
Fixed a few bugs in the "step in" thread plan logic.
Added a "step-in-target" flag to "thread step-in" so if you have something like:
Process 28464 stopped
* thread #1: tid = 0x1c03, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000e08 a.out`main at main.c:62
61
-> 62 int A6 = complex (a(4), b(5), c(6)); // Stop here to step targetting b and hitting breakpoint.
63
and you want to get into "complex" skipping a, b and c, you can do:
(lldb) step -t complex
Process 28464 stopped
* thread #1: tid = 0x1c03, function: complex , stop reason = step in
frame #0: 0x0000000100000d0d a.out`complex at main.c:44
41
42 int complex (int first, int second, int third)
43 {
-> 44 return first + second + third; // Step in targetting complex should stop here
45 }
46
47 int main (int argc, char const *argv[])
llvm-svn: 170008
2012-12-13 03:58:40 +08:00
log - > Printf ( " SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s') " ,
exe_ctx . GetThreadPtr ( ) ,
target_name ? target_name : " <NULL> " ,
2010-10-26 11:11:13 +08:00
Thread : : RunModeAsCString ( stop_other_threads ) ) ;
Fixed a few bugs in the "step in" thread plan logic.
Added a "step-in-target" flag to "thread step-in" so if you have something like:
Process 28464 stopped
* thread #1: tid = 0x1c03, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000e08 a.out`main at main.c:62
61
-> 62 int A6 = complex (a(4), b(5), c(6)); // Stop here to step targetting b and hitting breakpoint.
63
and you want to get into "complex" skipping a, b and c, you can do:
(lldb) step -t complex
Process 28464 stopped
* thread #1: tid = 0x1c03, function: complex , stop reason = step in
frame #0: 0x0000000100000d0d a.out`complex at main.c:44
41
42 int complex (int first, int second, int third)
43 {
-> 44 return first + second + third; // Step in targetting complex should stop here
45 }
46
47 int main (int argc, char const *argv[])
llvm-svn: 170008
2012-12-13 03:58:40 +08:00
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-06-09 00:52:24 +08:00
{
2012-05-12 07:47:32 +08:00
bool abort_other_plans = false ;
2010-06-09 00:52:24 +08:00
2012-02-21 08:09:25 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ( thread - > GetStackFrameAtIndex ( 0 ) ) ;
2013-07-19 05:48:26 +08:00
ThreadPlanSP new_plan_sp ;
2010-06-09 00:52:24 +08:00
if ( frame_sp & & frame_sp - > HasDebugInformation ( ) )
{
2014-03-13 10:47:14 +08:00
const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate ;
const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate ;
2010-06-09 00:52:24 +08:00
SymbolContext sc ( frame_sp - > GetSymbolContext ( eSymbolContextEverything ) ) ;
2013-07-19 05:48:26 +08:00
new_plan_sp = thread - > QueueThreadPlanForStepInRange ( abort_other_plans ,
Fixed a few bugs in the "step in" thread plan logic.
Added a "step-in-target" flag to "thread step-in" so if you have something like:
Process 28464 stopped
* thread #1: tid = 0x1c03, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000e08 a.out`main at main.c:62
61
-> 62 int A6 = complex (a(4), b(5), c(6)); // Stop here to step targetting b and hitting breakpoint.
63
and you want to get into "complex" skipping a, b and c, you can do:
(lldb) step -t complex
Process 28464 stopped
* thread #1: tid = 0x1c03, function: complex , stop reason = step in
frame #0: 0x0000000100000d0d a.out`complex at main.c:44
41
42 int complex (int first, int second, int third)
43 {
-> 44 return first + second + third; // Step in targetting complex should stop here
45 }
46
47 int main (int argc, char const *argv[])
llvm-svn: 170008
2012-12-13 03:58:40 +08:00
sc . line_entry . range ,
sc ,
target_name ,
stop_other_threads ,
2014-03-13 10:47:14 +08:00
step_in_avoids_code_without_debug_info ,
step_out_avoids_code_without_debug_info ) ;
2010-06-09 00:52:24 +08:00
}
else
{
2013-07-19 05:48:26 +08:00
new_plan_sp = thread - > QueueThreadPlanForStepSingleInstruction ( false ,
2012-05-04 05:19:36 +08:00
abort_other_plans ,
stop_other_threads ) ;
2010-10-06 11:53:16 +08:00
}
2012-05-04 05:19:36 +08:00
// This returns an error, we should use it!
2013-07-19 05:48:26 +08:00
ResumeNewPlan ( exe_ctx , new_plan_sp . get ( ) ) ;
2010-06-09 00:52:24 +08:00
}
}
void
SBThread : : StepOut ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2010-10-26 11:11:13 +08:00
2012-01-30 10:53:15 +08:00
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::StepOut () " , exe_ctx . GetThreadPtr ( ) ) ;
2012-01-30 10:53:15 +08:00
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-06-09 00:52:24 +08:00
{
2012-05-12 07:47:32 +08:00
bool abort_other_plans = false ;
2012-09-15 05:07:14 +08:00
bool stop_other_threads = false ;
2010-06-09 00:52:24 +08:00
2012-02-21 08:09:25 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2014-03-13 10:47:14 +08:00
const LazyBool avoid_no_debug = eLazyBoolCalculate ;
2013-07-19 05:48:26 +08:00
ThreadPlanSP new_plan_sp ( thread - > QueueThreadPlanForStepOut ( abort_other_plans ,
2012-05-04 05:19:36 +08:00
NULL ,
false ,
stop_other_threads ,
eVoteYes ,
eVoteNoOpinion ,
2014-03-13 10:47:14 +08:00
0 ,
avoid_no_debug ) ) ;
2012-05-04 05:19:36 +08:00
// This returns an error, we should use it!
2013-07-19 05:48:26 +08:00
ResumeNewPlan ( exe_ctx , new_plan_sp . get ( ) ) ;
2011-01-21 14:11:58 +08:00
}
}
void
SBThread : : StepOutOfFrame ( lldb : : SBFrame & sb_frame )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-06-09 00:52:24 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ( sb_frame . GetFrameSP ( ) ) ;
2011-01-21 14:11:58 +08:00
if ( log )
{
SBStream frame_desc_strm ;
sb_frame . GetDescription ( frame_desc_strm ) ;
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s) " , exe_ctx . GetThreadPtr ( ) , frame_sp . get ( ) , frame_desc_strm . GetData ( ) ) ;
2011-01-21 14:11:58 +08:00
}
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2011-01-21 14:11:58 +08:00
{
2012-05-12 07:47:32 +08:00
bool abort_other_plans = false ;
2012-09-15 05:07:14 +08:00
bool stop_other_threads = false ;
2012-02-21 08:09:25 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2011-01-21 14:11:58 +08:00
2013-07-19 05:48:26 +08:00
ThreadPlanSP new_plan_sp ( thread - > QueueThreadPlanForStepOut ( abort_other_plans ,
2012-05-04 05:19:36 +08:00
NULL ,
false ,
stop_other_threads ,
eVoteYes ,
eVoteNoOpinion ,
2013-07-19 05:48:26 +08:00
frame_sp - > GetFrameIndex ( ) ) ) ;
2012-05-04 05:19:36 +08:00
// This returns an error, we should use it!
2013-07-19 05:48:26 +08:00
ResumeNewPlan ( exe_ctx , new_plan_sp . get ( ) ) ;
2010-06-09 00:52:24 +08:00
}
}
void
SBThread : : StepInstruction ( bool step_over )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
2010-10-26 11:11:13 +08:00
2012-01-30 10:53:15 +08:00
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::StepInstruction (step_over=%i) " , exe_ctx . GetThreadPtr ( ) , step_over ) ;
2012-01-30 10:53:15 +08:00
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-06-09 00:52:24 +08:00
{
2012-02-21 08:09:25 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2013-07-19 05:48:26 +08:00
ThreadPlanSP new_plan_sp ( thread - > QueueThreadPlanForStepSingleInstruction ( step_over , true , true ) ) ;
2012-05-04 05:19:36 +08:00
// This returns an error, we should use it!
2013-07-19 05:48:26 +08:00
ResumeNewPlan ( exe_ctx , new_plan_sp . get ( ) ) ;
2010-06-09 00:52:24 +08:00
}
}
void
SBThread : : RunToAddress ( lldb : : addr_t addr )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2010-10-26 11:11:13 +08:00
2012-01-30 10:53:15 +08:00
if ( log )
2012-11-30 05:49:15 +08:00
log - > Printf ( " SBThread(%p)::RunToAddress (addr=0x% " PRIx64 " ) " , exe_ctx . GetThreadPtr ( ) , addr ) ;
2012-01-30 10:53:15 +08:00
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-06-09 00:52:24 +08:00
{
2012-05-12 07:47:32 +08:00
bool abort_other_plans = false ;
2010-06-09 00:52:24 +08:00
bool stop_other_threads = true ;
2012-02-24 09:59:29 +08:00
Address target_addr ( addr ) ;
2010-06-09 00:52:24 +08:00
2012-02-21 08:09:25 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2013-07-19 05:48:26 +08:00
ThreadPlanSP new_plan_sp ( thread - > QueueThreadPlanForRunToAddress ( abort_other_plans , target_addr , stop_other_threads ) ) ;
2012-05-04 05:19:36 +08:00
// This returns an error, we should use it!
2013-07-19 05:48:26 +08:00
ResumeNewPlan ( exe_ctx , new_plan_sp . get ( ) ) ;
2010-06-09 00:52:24 +08:00
}
2011-01-21 14:11:58 +08:00
}
SBError
SBThread : : StepOverUntil ( lldb : : SBFrame & sb_frame ,
lldb : : SBFileSpec & sb_file_spec ,
uint32_t line )
{
SBError sb_error ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2011-01-21 14:11:58 +08:00
char path [ PATH_MAX ] ;
2012-01-30 10:53:15 +08:00
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ( sb_frame . GetFrameSP ( ) ) ;
2012-01-30 15:41:31 +08:00
2011-01-21 14:11:58 +08:00
if ( log )
{
SBStream frame_desc_strm ;
sb_frame . GetDescription ( frame_desc_strm ) ;
sb_file_spec - > GetPath ( path , sizeof ( path ) ) ;
log - > Printf ( " SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u) " ,
2012-02-21 08:09:25 +08:00
exe_ctx . GetThreadPtr ( ) ,
2012-01-30 15:41:31 +08:00
frame_sp . get ( ) ,
2011-01-21 14:11:58 +08:00
frame_desc_strm . GetData ( ) ,
path , line ) ;
}
2012-01-30 10:53:15 +08:00
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2011-01-21 14:11:58 +08:00
{
2012-02-21 08:09:25 +08:00
Target * target = exe_ctx . GetTargetPtr ( ) ;
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2010-06-09 00:52:24 +08:00
2011-01-21 14:11:58 +08:00
if ( line = = 0 )
{
sb_error . SetErrorString ( " invalid line argument " ) ;
return sb_error ;
}
2012-01-30 15:41:31 +08:00
if ( ! frame_sp )
2011-01-21 14:11:58 +08:00
{
2012-02-21 08:09:25 +08:00
frame_sp = thread - > GetSelectedFrame ( ) ;
2011-01-21 14:11:58 +08:00
if ( ! frame_sp )
2012-02-21 08:09:25 +08:00
frame_sp = thread - > GetStackFrameAtIndex ( 0 ) ;
2011-01-21 14:11:58 +08:00
}
SymbolContext frame_sc ;
if ( ! frame_sp )
{
sb_error . SetErrorString ( " no valid frames in thread to step " ) ;
return sb_error ;
}
// If we have a frame, get its line
frame_sc = frame_sp - > GetSymbolContext ( eSymbolContextCompUnit |
eSymbolContextFunction |
eSymbolContextLineEntry |
eSymbolContextSymbol ) ;
if ( frame_sc . comp_unit = = NULL )
{
sb_error . SetErrorStringWithFormat ( " frame %u doesn't have debug information " , frame_sp - > GetFrameIndex ( ) ) ;
return sb_error ;
}
FileSpec step_file_spec ;
if ( sb_file_spec . IsValid ( ) )
{
// The file spec passed in was valid, so use it
step_file_spec = sb_file_spec . ref ( ) ;
}
else
{
if ( frame_sc . line_entry . IsValid ( ) )
step_file_spec = frame_sc . line_entry . file ;
else
{
sb_error . SetErrorString ( " invalid file argument or no file for frame " ) ;
return sb_error ;
}
}
2011-05-08 08:56:32 +08:00
// Grab the current function, then we will make sure the "until" address is
// within the function. We discard addresses that are out of the current
// function, and then if there are no addresses remaining, give an appropriate
// error message.
bool all_in_function = true ;
AddressRange fun_range = frame_sc . function - > GetAddressRange ( ) ;
2011-01-21 14:11:58 +08:00
std : : vector < addr_t > step_over_until_addrs ;
2012-05-12 07:47:32 +08:00
const bool abort_other_plans = false ;
2012-09-15 02:57:14 +08:00
const bool stop_other_threads = false ;
2011-01-21 14:11:58 +08:00
const bool check_inlines = true ;
const bool exact = false ;
SymbolContextList sc_list ;
2011-05-08 08:56:32 +08:00
const uint32_t num_matches = frame_sc . comp_unit - > ResolveSymbolContext ( step_file_spec ,
line ,
check_inlines ,
exact ,
eSymbolContextLineEntry ,
sc_list ) ;
2011-01-21 14:11:58 +08:00
if ( num_matches > 0 )
{
SymbolContext sc ;
for ( uint32_t i = 0 ; i < num_matches ; + + i )
{
if ( sc_list . GetContextAtIndex ( i , sc ) )
{
2011-05-08 08:56:32 +08:00
addr_t step_addr = sc . line_entry . range . GetBaseAddress ( ) . GetLoadAddress ( target ) ;
2011-01-21 14:11:58 +08:00
if ( step_addr ! = LLDB_INVALID_ADDRESS )
{
2011-05-08 08:56:32 +08:00
if ( fun_range . ContainsLoadAddress ( step_addr , target ) )
step_over_until_addrs . push_back ( step_addr ) ;
else
all_in_function = false ;
2011-01-21 14:11:58 +08:00
}
}
}
}
2011-05-08 08:56:32 +08:00
2011-01-21 14:11:58 +08:00
if ( step_over_until_addrs . empty ( ) )
{
2011-05-08 08:56:32 +08:00
if ( all_in_function )
{
step_file_spec . GetPath ( path , sizeof ( path ) ) ;
2011-09-21 05:44:10 +08:00
sb_error . SetErrorStringWithFormat ( " No line entries for %s:%u " , path , line ) ;
2011-05-08 08:56:32 +08:00
}
else
2011-10-26 08:56:27 +08:00
sb_error . SetErrorString ( " step until target not in current function " ) ;
2011-01-21 14:11:58 +08:00
}
else
{
2013-07-19 05:48:26 +08:00
ThreadPlanSP new_plan_sp ( thread - > QueueThreadPlanForStepUntil ( abort_other_plans ,
2012-05-04 05:19:36 +08:00
& step_over_until_addrs [ 0 ] ,
step_over_until_addrs . size ( ) ,
stop_other_threads ,
2013-07-19 05:48:26 +08:00
frame_sp - > GetFrameIndex ( ) ) ) ;
2012-02-21 08:09:25 +08:00
2013-07-19 05:48:26 +08:00
sb_error = ResumeNewPlan ( exe_ctx , new_plan_sp . get ( ) ) ;
2011-01-21 14:11:58 +08:00
}
}
else
{
sb_error . SetErrorString ( " this SBThread object is invalid " ) ;
}
return sb_error ;
2010-06-09 00:52:24 +08:00
}
2013-09-12 10:20:34 +08:00
SBError
SBThread : : JumpToLine ( lldb : : SBFileSpec & file_spec , uint32_t line )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
SBError sb_error ;
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
if ( log )
log - > Printf ( " SBThread(%p)::JumpToLine (file+line = %s:%u) " , exe_ctx . GetThreadPtr ( ) , file_spec - > GetPath ( ) . c_str ( ) , line ) ;
if ( ! exe_ctx . HasThreadScope ( ) )
{
sb_error . SetErrorString ( " this SBThread object is invalid " ) ;
return sb_error ;
}
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
Error err = thread - > JumpToLine ( file_spec . get ( ) , line , true ) ;
sb_error . SetError ( err ) ;
return sb_error ;
}
2012-09-12 08:40:39 +08:00
SBError
2012-09-14 10:14:15 +08:00
SBThread : : ReturnFromFrame ( SBFrame & frame , SBValue & return_value )
2012-09-12 08:40:39 +08:00
{
SBError sb_error ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2012-09-12 08:40:39 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
if ( log )
2012-09-14 10:14:15 +08:00
log - > Printf ( " SBThread(%p)::ReturnFromFrame (frame=%d) " , exe_ctx . GetThreadPtr ( ) , frame . GetFrameID ( ) ) ;
2012-09-12 08:40:39 +08:00
if ( exe_ctx . HasThreadScope ( ) )
{
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
2012-09-14 10:14:15 +08:00
sb_error . SetError ( thread - > ReturnFromFrame ( frame . GetFrameSP ( ) , return_value . GetSP ( ) ) ) ;
2012-09-12 08:40:39 +08:00
}
return sb_error ;
}
2011-01-21 14:11:58 +08:00
2011-01-12 10:25:42 +08:00
bool
SBThread : : Suspend ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2012-04-06 00:12:35 +08:00
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) ) ;
2012-04-06 10:17:47 +08:00
bool result = false ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2011-01-12 10:25:42 +08:00
{
2012-04-06 10:17:47 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
exe_ctx . GetThreadPtr ( ) - > SetResumeState ( eStateSuspended ) ;
result = true ;
}
else
{
if ( log )
log - > Printf ( " SBThread(%p)::Suspend() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2011-01-12 10:25:42 +08:00
}
2012-04-06 10:17:47 +08:00
if ( log )
log - > Printf ( " SBThread(%p)::Suspend() => %i " , exe_ctx . GetThreadPtr ( ) , result ) ;
return result ;
2011-01-12 10:25:42 +08:00
}
bool
SBThread : : Resume ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2012-04-06 00:12:35 +08:00
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) ) ;
2012-04-06 10:17:47 +08:00
bool result = false ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2011-01-12 10:25:42 +08:00
{
2012-04-06 10:17:47 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
2014-04-03 09:26:14 +08:00
const bool override_suspend = true ;
exe_ctx . GetThreadPtr ( ) - > SetResumeState ( eStateRunning , override_suspend ) ;
2012-04-06 10:17:47 +08:00
result = true ;
}
else
{
if ( log )
log - > Printf ( " SBThread(%p)::Resume() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2011-01-12 10:25:42 +08:00
}
2012-04-06 10:17:47 +08:00
if ( log )
log - > Printf ( " SBThread(%p)::Resume() => %i " , exe_ctx . GetThreadPtr ( ) , result ) ;
return result ;
2011-01-12 10:25:42 +08:00
}
bool
SBThread : : IsSuspended ( )
{
2012-04-06 00:12:35 +08:00
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
return exe_ctx . GetThreadPtr ( ) - > GetResumeState ( ) = = eStateSuspended ;
2011-01-12 10:25:42 +08:00
return false ;
}
2013-04-16 07:33:53 +08:00
bool
SBThread : : IsStopped ( )
{
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) ) ;
if ( exe_ctx . HasThreadScope ( ) )
return StateIsStoppedState ( exe_ctx . GetThreadPtr ( ) - > GetState ( ) , true ) ;
return false ;
}
2011-01-12 10:25:42 +08:00
2010-06-09 00:52:24 +08:00
SBProcess
SBThread : : GetProcess ( )
{
2012-01-30 15:41:31 +08:00
SBProcess sb_process ;
2012-04-06 00:12:35 +08:00
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
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...
2012-02-21 08:09:25 +08:00
sb_process . SetSP ( exe_ctx . GetProcessSP ( ) ) ;
2010-06-09 00:52:24 +08:00
}
2010-10-26 11:11:13 +08:00
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
if ( log )
{
2011-01-21 14:11:58 +08:00
SBStream frame_desc_strm ;
2012-01-30 15:41:31 +08:00
sb_process . GetDescription ( frame_desc_strm ) ;
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::GetProcess () => SBProcess(%p): %s " , exe_ctx . GetThreadPtr ( ) ,
2013-02-28 10:18:49 +08:00
sb_process . GetSP ( ) . get ( ) , frame_desc_strm . GetData ( ) ) ;
2010-10-26 11:11:13 +08:00
}
2012-01-30 15:41:31 +08:00
return sb_process ;
2010-06-09 00:52:24 +08:00
}
uint32_t
SBThread : : GetNumFrames ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
uint32_t num_frames = 0 ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-12-21 04:49:23 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
num_frames = exe_ctx . GetThreadPtr ( ) - > GetStackFrameCount ( ) ;
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetNumFrames() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-12-21 04:49:23 +08:00
}
2010-10-26 11:11:13 +08:00
if ( log )
2012-02-21 08:09:25 +08:00
log - > Printf ( " SBThread(%p)::GetNumFrames () => %u " , exe_ctx . GetThreadPtr ( ) , num_frames ) ;
2010-10-26 11:11:13 +08:00
return num_frames ;
2010-06-09 00:52:24 +08:00
}
SBFrame
SBThread : : GetFrameAtIndex ( uint32_t idx )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-10-26 11:11:13 +08:00
2010-06-09 00:52:24 +08:00
SBFrame sb_frame ;
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-12-21 04:49:23 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
frame_sp = exe_ctx . GetThreadPtr ( ) - > GetStackFrameAtIndex ( idx ) ;
sb_frame . SetFrameSP ( frame_sp ) ;
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetFrameAtIndex() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-12-21 04:49:23 +08:00
}
2010-10-26 11:11:13 +08:00
if ( log )
{
2011-01-21 14:11:58 +08:00
SBStream frame_desc_strm ;
sb_frame . GetDescription ( frame_desc_strm ) ;
2010-10-30 12:51:46 +08:00
log - > Printf ( " SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s " ,
2012-02-21 08:09:25 +08:00
exe_ctx . GetThreadPtr ( ) , idx , frame_sp . get ( ) , frame_desc_strm . GetData ( ) ) ;
2010-10-26 11:11:13 +08:00
}
2010-06-09 00:52:24 +08:00
return sb_frame ;
}
2010-12-17 10:26:24 +08:00
lldb : : SBFrame
SBThread : : GetSelectedFrame ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-12-17 10:26:24 +08:00
SBFrame sb_frame ;
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-12-21 04:49:23 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
frame_sp = exe_ctx . GetThreadPtr ( ) - > GetSelectedFrame ( ) ;
sb_frame . SetFrameSP ( frame_sp ) ;
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::GetSelectedFrame() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-12-21 04:49:23 +08:00
}
2010-12-17 10:26:24 +08:00
if ( log )
{
2011-01-21 14:11:58 +08:00
SBStream frame_desc_strm ;
sb_frame . GetDescription ( frame_desc_strm ) ;
2010-12-17 10:26:24 +08:00
log - > Printf ( " SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s " ,
2012-02-21 08:09:25 +08:00
exe_ctx . GetThreadPtr ( ) , frame_sp . get ( ) , frame_desc_strm . GetData ( ) ) ;
2010-12-17 10:26:24 +08:00
}
return sb_frame ;
}
lldb : : SBFrame
SBThread : : SetSelectedFrame ( uint32_t idx )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
2010-12-17 10:26:24 +08:00
SBFrame sb_frame ;
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ;
2012-08-23 05:34:33 +08:00
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-12-17 10:26:24 +08:00
{
2012-04-06 00:12:35 +08:00
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
2010-12-17 10:26:24 +08:00
{
2012-04-06 00:12:35 +08:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
frame_sp = thread - > GetStackFrameAtIndex ( idx ) ;
if ( frame_sp )
{
thread - > SetSelectedFrame ( frame_sp . get ( ) ) ;
sb_frame . SetFrameSP ( frame_sp ) ;
}
2010-12-17 10:26:24 +08:00
}
2012-04-06 10:17:47 +08:00
else
{
if ( log )
log - > Printf ( " SBThread(%p)::SetSelectedFrame() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
}
2010-12-17 10:26:24 +08:00
}
if ( log )
{
2011-01-21 14:11:58 +08:00
SBStream frame_desc_strm ;
sb_frame . GetDescription ( frame_desc_strm ) ;
2010-12-17 10:26:24 +08:00
log - > Printf ( " SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s " ,
2012-02-21 08:09:25 +08:00
exe_ctx . GetThreadPtr ( ) , idx , frame_sp . get ( ) , frame_desc_strm . GetData ( ) ) ;
2010-12-17 10:26:24 +08:00
}
return sb_frame ;
}
2012-10-11 02:32:14 +08:00
bool
SBThread : : EventIsThreadEvent ( const SBEvent & event )
{
return Thread : : ThreadEventData : : GetEventDataFromEvent ( event . get ( ) ) ! = NULL ;
}
SBFrame
SBThread : : GetStackFrameFromEvent ( const SBEvent & event )
{
return Thread : : ThreadEventData : : GetStackFrameFromEvent ( event . get ( ) ) ;
}
SBThread
SBThread : : GetThreadFromEvent ( const SBEvent & event )
{
return Thread : : ThreadEventData : : GetThreadFromEvent ( event . get ( ) ) ;
}
2010-12-17 10:26:24 +08:00
2010-06-09 00:52:24 +08:00
bool
SBThread : : operator = = ( const SBThread & rhs ) const
{
2012-04-06 00:12:35 +08:00
return m_opaque_sp - > GetThreadSP ( ) . get ( ) = = rhs . m_opaque_sp - > GetThreadSP ( ) . get ( ) ;
2010-06-09 00:52:24 +08:00
}
bool
SBThread : : operator ! = ( const SBThread & rhs ) const
{
2012-04-06 00:12:35 +08:00
return m_opaque_sp - > GetThreadSP ( ) . get ( ) ! = rhs . m_opaque_sp - > GetThreadSP ( ) . get ( ) ;
2010-06-09 00:52:24 +08:00
}
2010-09-20 13:20:02 +08:00
2012-10-11 02:32:14 +08:00
bool
SBThread : : GetStatus ( SBStream & status ) const
{
Stream & strm = status . ref ( ) ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) ) ;
if ( exe_ctx . HasThreadScope ( ) )
{
exe_ctx . GetThreadPtr ( ) - > GetStatus ( strm , 0 , 1 , 1 ) ;
}
else
strm . PutCString ( " No status " ) ;
return true ;
}
2010-10-26 11:11:13 +08:00
bool
SBThread : : GetDescription ( SBStream & description ) const
{
2011-11-13 14:57:31 +08:00
Stream & strm = description . ref ( ) ;
2012-04-06 00:12:35 +08:00
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) ) ;
2012-02-21 08:09:25 +08:00
if ( exe_ctx . HasThreadScope ( ) )
2010-10-26 11:11:13 +08:00
{
2012-11-30 05:49:15 +08:00
strm . Printf ( " SBThread: tid = 0x%4.4 " PRIx64 , exe_ctx . GetThreadPtr ( ) - > GetID ( ) ) ;
2010-10-26 11:11:13 +08:00
}
else
2011-11-13 14:57:31 +08:00
strm . PutCString ( " No value " ) ;
2010-10-26 11:11:13 +08:00
return true ;
}
2013-11-06 08:04:44 +08:00
SBThread
2013-11-13 07:33:32 +08:00
SBThread : : GetExtendedBacktraceThread ( const char * type )
2013-11-06 08:04:44 +08:00
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_API ) ) ;
Mutex : : Locker api_locker ;
ExecutionContext exe_ctx ( m_opaque_sp . get ( ) , api_locker ) ;
SBThread sb_origin_thread ;
if ( exe_ctx . HasThreadScope ( ) )
{
Process : : StopLocker stop_locker ;
if ( stop_locker . TryLock ( & exe_ctx . GetProcessPtr ( ) - > GetRunLock ( ) ) )
{
2013-11-11 13:19:34 +08:00
ThreadSP real_thread ( exe_ctx . GetThreadSP ( ) ) ;
2013-11-06 08:04:44 +08:00
if ( real_thread )
{
ConstString type_const ( type ) ;
2013-11-11 13:19:34 +08:00
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
2013-11-06 08:04:44 +08:00
{
2013-11-11 13:19:34 +08:00
SystemRuntime * runtime = process - > GetSystemRuntime ( ) ;
if ( runtime )
{
2013-11-13 07:33:32 +08:00
ThreadSP new_thread_sp ( runtime - > GetExtendedBacktraceThread ( real_thread , type_const ) ) ;
2013-11-19 13:44:41 +08:00
if ( new_thread_sp )
{
// Save this in the Process' ExtendedThreadList so a strong pointer retains the
// object.
process - > GetExtendedThreadList ( ) . AddThread ( new_thread_sp ) ;
sb_origin_thread . SetThread ( new_thread_sp ) ;
if ( log )
{
const char * queue_name = new_thread_sp - > GetQueueName ( ) ;
if ( queue_name = = NULL )
queue_name = " " ;
log - > Printf ( " SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x% " PRIx64 " queue name '%s' " , exe_ctx . GetThreadPtr ( ) , new_thread_sp . get ( ) , new_thread_sp - > GetQueueID ( ) , queue_name ) ;
}
}
2013-11-11 13:19:34 +08:00
}
2013-11-06 08:04:44 +08:00
}
}
}
else
{
if ( log )
2013-11-19 13:44:41 +08:00
log - > Printf ( " SBThread(%p)::GetExtendedBacktraceThread() => error: process is running " , exe_ctx . GetThreadPtr ( ) ) ;
2013-11-06 08:04:44 +08:00
}
}
2014-03-08 09:34:55 +08:00
if ( log & & sb_origin_thread . IsValid ( ) = = false )
{
log - > Printf ( " SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread " , exe_ctx . GetThreadPtr ( ) ) ;
}
2013-11-06 08:04:44 +08:00
return sb_origin_thread ;
}
2013-11-16 09:24:22 +08:00
uint32_t
SBThread : : GetExtendedBacktraceOriginatingIndexID ( )
{
ThreadSP thread_sp ( m_opaque_sp - > GetThreadSP ( ) ) ;
if ( thread_sp )
return thread_sp - > GetExtendedBacktraceOriginatingIndexID ( ) ;
return LLDB_INVALID_INDEX32 ;
}