2010-06-08 16:52:24 +00:00
//===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "CommandObjectThread.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2010-06-15 19:49:27 +00:00
# include "lldb/Interpreter/Options.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Core/State.h"
# include "lldb/Core/SourceManager.h"
2011-02-01 01:31:41 +00:00
# include "lldb/Host/Host.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandReturnObject.h"
# include "lldb/Target/Process.h"
# include "lldb/Target/RegisterContext.h"
# include "lldb/Target/Target.h"
# include "lldb/Target/Thread.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"
# include "lldb/Symbol/LineTable.h"
# include "lldb/Symbol/LineEntry.h"
using namespace lldb ;
using namespace lldb_private ;
//-------------------------------------------------------------------------
// CommandObjectThreadBacktrace
//-------------------------------------------------------------------------
class CommandObjectThreadBacktrace : public CommandObject
{
public :
2010-08-26 23:36:03 +00:00
class CommandOptions : public Options
{
public :
2011-04-07 22:46:35 +00:00
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
2010-08-26 23:36:03 +00:00
{
2011-04-13 00:18:08 +00:00
// Keep default values of all options in one place: OptionParsingStarting ()
OptionParsingStarting ( ) ;
2010-08-26 23:36:03 +00:00
}
virtual
~ CommandOptions ( )
{
}
virtual Error
2011-04-13 00:18:08 +00:00
SetOptionValue ( uint32_t option_idx , const char * option_arg )
2010-08-26 23:36:03 +00:00
{
Error error ;
char short_option = ( char ) m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' c ' :
{
bool success ;
int32_t input_count = Args : : StringToSInt32 ( option_arg , - 1 , 0 , & success ) ;
if ( ! success )
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid integer value for option '%c' " , short_option ) ;
2010-08-26 23:36:03 +00:00
if ( input_count < - 1 )
m_count = UINT32_MAX ;
else
m_count = input_count ;
}
break ;
case ' s ' :
{
bool success ;
m_start = Args : : StringToUInt32 ( option_arg , 0 , 0 , & success ) ;
if ( ! success )
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid integer value for option '%c' " , short_option ) ;
2010-08-26 23:36:03 +00:00
}
break ;
default :
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid short option character '%c' " , short_option ) ;
2010-08-26 23:36:03 +00:00
break ;
}
return error ;
}
void
2011-04-13 00:18:08 +00:00
OptionParsingStarting ( )
2010-08-26 23:36:03 +00:00
{
2011-04-18 08:33:37 +00:00
m_count = UINT32_MAX ;
2010-08-26 23:36:03 +00:00
m_start = 0 ;
}
2011-03-24 21:19:54 +00:00
const OptionDefinition *
2010-08-26 23:36:03 +00:00
GetDefinitions ( )
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
2011-03-24 21:19:54 +00:00
static OptionDefinition g_option_table [ ] ;
2010-08-26 23:36:03 +00:00
// Instance variables to hold the values for command options.
uint32_t m_count ;
uint32_t m_start ;
} ;
2010-09-18 01:14:36 +00:00
CommandObjectThreadBacktrace ( CommandInterpreter & interpreter ) :
CommandObject ( interpreter ,
" thread backtrace " ,
2010-09-08 22:08:58 +00:00
" Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \" all \" to see all threads. " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-06-08 16:52:24 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused ) ,
2011-04-07 22:46:35 +00:00
m_options ( interpreter )
2010-06-08 16:52:24 +00:00
{
2010-10-04 22:28:36 +00:00
CommandArgumentEntry arg ;
CommandArgumentData thread_idx_arg ;
// Define the first (and only) variant of this arg.
thread_idx_arg . arg_type = eArgTypeThreadIndex ;
thread_idx_arg . arg_repetition = eArgRepeatStar ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( thread_idx_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
2010-06-08 16:52:24 +00:00
}
~ CommandObjectThreadBacktrace ( )
{
}
2010-08-26 23:36:03 +00:00
virtual Options *
GetOptions ( )
{
return & m_options ;
}
2010-06-08 16:52:24 +00:00
2010-06-23 01:19:29 +00:00
virtual bool
2010-09-18 01:14:36 +00:00
Execute ( Args & command , CommandReturnObject & result )
2011-04-18 08:33:37 +00:00
{
2010-08-27 00:58:05 +00:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
2011-04-18 08:33:37 +00:00
Stream & strm = result . GetOutputStream ( ) ;
// Don't show source context when doing backtraces.
const uint32_t num_frames_with_source = 0 ;
2010-06-08 16:52:24 +00:00
if ( command . GetArgumentCount ( ) = = 0 )
{
2011-04-12 05:54:46 +00:00
ExecutionContext exe_ctx ( m_interpreter . GetExecutionContext ( ) ) ;
2011-09-22 04:58:26 +00:00
Thread * thread = exe_ctx . GetThreadPtr ( ) ;
if ( thread )
2010-06-08 16:52:24 +00:00
{
2011-06-02 18:02:15 +00:00
// Thread::GetStatus() returns the number of frames shown.
2011-09-22 04:58:26 +00:00
if ( thread - > GetStatus ( strm ,
m_options . m_start ,
m_options . m_count ,
num_frames_with_source ) )
2010-06-08 16:52:24 +00:00
{
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
}
else
{
result . AppendError ( " invalid thread " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
2010-08-27 00:58:05 +00:00
else if ( command . GetArgumentCount ( ) = = 1 & & : : strcmp ( command . GetArgumentAtIndex ( 0 ) , " all " ) = = 0 )
{
2011-09-22 04:58:26 +00:00
Process * process = m_interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
2010-08-27 00:58:05 +00:00
uint32_t num_threads = process - > GetThreadList ( ) . GetSize ( ) ;
for ( uint32_t i = 0 ; i < num_threads ; i + + )
{
ThreadSP thread_sp = process - > GetThreadList ( ) . GetThreadAtIndex ( i ) ;
2011-06-01 23:19:52 +00:00
if ( ! thread_sp - > GetStatus ( strm ,
m_options . m_start ,
m_options . m_count ,
num_frames_with_source ) )
2010-08-27 00:58:05 +00:00
{
2010-09-03 22:45:01 +00:00
result . AppendErrorWithFormat ( " error displaying backtrace for thread: \" 0x%4.4x \" \n " , i ) ;
2010-08-27 00:58:05 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2011-07-26 02:39:59 +00:00
if ( i < num_threads - 1 )
result . AppendMessage ( " " ) ;
2010-08-27 00:58:05 +00:00
}
}
2010-06-08 16:52:24 +00:00
else
{
2010-08-27 00:58:05 +00:00
uint32_t num_args = command . GetArgumentCount ( ) ;
2011-09-22 04:58:26 +00:00
Process * process = m_interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
2010-08-27 00:58:05 +00:00
std : : vector < ThreadSP > thread_sps ;
for ( uint32_t i = 0 ; i < num_args ; i + + )
{
bool success ;
uint32_t thread_idx = Args : : StringToUInt32 ( command . GetArgumentAtIndex ( i ) , 0 , 0 , & success ) ;
if ( ! success )
{
result . AppendErrorWithFormat ( " invalid thread specification: \" %s \" \n " , command . GetArgumentAtIndex ( i ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
thread_sps . push_back ( process - > GetThreadList ( ) . FindThreadByIndexID ( thread_idx ) ) ;
if ( ! thread_sps [ i ] )
{
result . AppendErrorWithFormat ( " no thread with index: \" %s \" \n " , command . GetArgumentAtIndex ( i ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
for ( uint32_t i = 0 ; i < num_args ; i + + )
{
2011-04-18 08:33:37 +00:00
if ( ! thread_sps [ i ] - > GetStatus ( strm ,
m_options . m_start ,
m_options . m_count ,
num_frames_with_source ) )
2010-08-27 00:58:05 +00:00
{
result . AppendErrorWithFormat ( " error displaying backtrace for thread: \" %s \" \n " , command . GetArgumentAtIndex ( i ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( i < num_args - 1 )
result . AppendMessage ( " " ) ;
}
2010-06-08 16:52:24 +00:00
}
return result . Succeeded ( ) ;
}
protected :
2010-08-26 23:36:03 +00:00
CommandOptions m_options ;
2010-06-08 16:52:24 +00:00
} ;
2011-03-24 21:19:54 +00:00
OptionDefinition
2010-08-26 23:36:03 +00:00
CommandObjectThreadBacktrace : : CommandOptions : : g_option_table [ ] =
{
2010-10-01 19:59:14 +00:00
{ LLDB_OPT_SET_1 , false , " count " , ' c ' , required_argument , NULL , 0 , eArgTypeCount , " How many frames to display (-1 for all) " } ,
2010-10-04 22:28:36 +00:00
{ LLDB_OPT_SET_1 , false , " start " , ' s ' , required_argument , NULL , 0 , eArgTypeFrameIndex , " Frame in which to start the backtrace " } ,
2010-10-01 19:59:14 +00:00
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2010-08-26 23:36:03 +00:00
} ;
2010-06-08 16:52:24 +00:00
2010-07-07 17:07:17 +00:00
enum StepScope
2010-06-08 16:52:24 +00:00
{
eStepScopeSource ,
eStepScopeInstruction
} ;
class CommandObjectThreadStepWithTypeAndScope : public CommandObject
{
public :
class CommandOptions : public Options
{
public :
2011-04-07 22:46:35 +00:00
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
2010-06-08 16:52:24 +00:00
{
2011-04-13 00:18:08 +00:00
// Keep default values of all options in one place: OptionParsingStarting ()
OptionParsingStarting ( ) ;
2010-06-08 16:52:24 +00:00
}
virtual
~ CommandOptions ( )
{
}
virtual Error
2011-04-13 00:18:08 +00:00
SetOptionValue ( uint32_t option_idx , const char * option_arg )
2010-06-08 16:52:24 +00:00
{
Error error ;
char short_option = ( char ) m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
2010-10-08 04:20:14 +00:00
case ' a ' :
2010-06-08 16:52:24 +00:00
{
bool success ;
m_avoid_no_debug = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid boolean value for option '%c' " , short_option ) ;
2010-06-08 16:52:24 +00:00
}
break ;
2010-10-08 04:20:14 +00:00
case ' m ' :
2010-06-08 16:52:24 +00:00
{
OptionEnumValueElement * enum_values = g_option_table [ option_idx ] . enum_values ;
2011-10-07 18:58:12 +00:00
m_run_mode = ( lldb : : RunMode ) Args : : StringToOptionEnum ( option_arg , enum_values , eOnlyDuringStepping , error ) ;
2010-06-08 16:52:24 +00:00
}
break ;
2010-10-08 04:20:14 +00:00
case ' r ' :
2010-07-10 02:27:39 +00:00
{
m_avoid_regexp . clear ( ) ;
m_avoid_regexp . assign ( option_arg ) ;
}
break ;
2010-10-08 04:20:14 +00:00
default :
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid short option character '%c' " , short_option ) ;
2010-10-08 04:20:14 +00:00
break ;
2010-06-08 16:52:24 +00:00
}
return error ;
}
void
2011-04-13 00:18:08 +00:00
OptionParsingStarting ( )
2010-06-08 16:52:24 +00:00
{
m_avoid_no_debug = true ;
m_run_mode = eOnlyDuringStepping ;
2010-07-10 02:27:39 +00:00
m_avoid_regexp . clear ( ) ;
2010-06-08 16:52:24 +00:00
}
2011-03-24 21:19:54 +00:00
const OptionDefinition *
2010-06-08 16:52:24 +00:00
GetDefinitions ( )
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
2011-03-24 21:19:54 +00:00
static OptionDefinition g_option_table [ ] ;
2010-06-08 16:52:24 +00:00
// Instance variables to hold the values for command options.
bool m_avoid_no_debug ;
RunMode m_run_mode ;
2010-07-10 02:27:39 +00:00
std : : string m_avoid_regexp ;
2010-06-08 16:52:24 +00:00
} ;
2010-09-18 01:14:36 +00:00
CommandObjectThreadStepWithTypeAndScope ( CommandInterpreter & interpreter ,
const char * name ,
const char * help ,
const char * syntax ,
uint32_t flags ,
StepType step_type ,
StepScope step_scope ) :
CommandObject ( interpreter , name , help , syntax , flags ) ,
2010-06-08 16:52:24 +00:00
m_step_type ( step_type ) ,
m_step_scope ( step_scope ) ,
2011-04-07 22:46:35 +00:00
m_options ( interpreter )
2010-06-08 16:52:24 +00:00
{
2010-10-04 22:28:36 +00:00
CommandArgumentEntry arg ;
CommandArgumentData thread_id_arg ;
// Define the first (and only) variant of this arg.
thread_id_arg . arg_type = eArgTypeThreadID ;
thread_id_arg . arg_repetition = eArgRepeatOptional ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( thread_id_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
2010-06-08 16:52:24 +00:00
}
virtual
~ CommandObjectThreadStepWithTypeAndScope ( )
{
}
virtual
Options *
GetOptions ( )
{
return & m_options ;
}
virtual bool
2010-06-23 01:19:29 +00:00
Execute
(
Args & command ,
CommandReturnObject & result
)
2010-06-08 16:52:24 +00:00
{
2011-09-22 04:58:26 +00:00
Process * process = m_interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
2010-09-18 01:14:36 +00:00
bool synchronous_execution = m_interpreter . GetSynchronous ( ) ;
2010-06-08 16:52:24 +00:00
if ( process = = NULL )
{
result . AppendError ( " need a valid process to step " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
else
{
const uint32_t num_threads = process - > GetThreadList ( ) . GetSize ( ) ;
Thread * thread = NULL ;
if ( command . GetArgumentCount ( ) = = 0 )
{
2010-08-26 21:32:51 +00:00
thread = process - > GetThreadList ( ) . GetSelectedThread ( ) . get ( ) ;
2010-06-08 16:52:24 +00:00
if ( thread = = NULL )
{
2010-08-26 23:36:03 +00:00
result . AppendError ( " no selected thread in process " ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
else
{
const char * thread_idx_cstr = command . GetArgumentAtIndex ( 0 ) ;
uint32_t step_thread_idx = Args : : StringToUInt32 ( thread_idx_cstr , LLDB_INVALID_INDEX32 ) ;
if ( step_thread_idx = = LLDB_INVALID_INDEX32 )
{
2011-10-26 00:56:27 +00:00
result . AppendErrorWithFormat ( " invalid thread index '%s'. \n " , thread_idx_cstr ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
thread = process - > GetThreadList ( ) . FindThreadByIndexID ( step_thread_idx ) . get ( ) ;
if ( thread = = NULL )
{
result . AppendErrorWithFormat ( " Thread index %u is out of range (valid values are 0 - %u). \n " ,
2011-09-20 21:44:10 +00:00
step_thread_idx , num_threads ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
const bool abort_other_plans = false ;
const lldb : : RunMode stop_other_threads = m_options . m_run_mode ;
// This is a bit unfortunate, but not all the commands in this command object support
// only while stepping, so I use the bool for them.
bool bool_stop_other_threads ;
if ( m_options . m_run_mode = = eAllThreads )
bool_stop_other_threads = false ;
else
bool_stop_other_threads = true ;
if ( m_step_type = = eStepTypeInto )
{
StackFrame * frame = thread - > GetStackFrameAtIndex ( 0 ) . get ( ) ;
ThreadPlan * new_plan ;
if ( frame - > HasDebugInformation ( ) )
{
new_plan = thread - > QueueThreadPlanForStepRange ( abort_other_plans , m_step_type ,
frame - > GetSymbolContext ( eSymbolContextEverything ) . line_entry . range ,
frame - > GetSymbolContext ( eSymbolContextEverything ) ,
2010-06-12 18:59:55 +00:00
stop_other_threads ,
m_options . m_avoid_no_debug ) ;
2010-07-10 02:27:39 +00:00
if ( new_plan & & ! m_options . m_avoid_regexp . empty ( ) )
{
ThreadPlanStepInRange * step_in_range_plan = static_cast < ThreadPlanStepInRange * > ( new_plan ) ;
step_in_range_plan - > SetAvoidRegexp ( m_options . m_avoid_regexp . c_str ( ) ) ;
}
2010-06-08 16:52:24 +00:00
}
else
new_plan = thread - > QueueThreadPlanForStepSingleInstruction ( false , abort_other_plans , bool_stop_other_threads ) ;
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( thread - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
process - > Resume ( ) ;
}
else if ( m_step_type = = eStepTypeOver )
{
StackFrame * frame = thread - > GetStackFrameAtIndex ( 0 ) . get ( ) ;
ThreadPlan * new_plan ;
if ( frame - > HasDebugInformation ( ) )
new_plan = thread - > QueueThreadPlanForStepRange ( abort_other_plans ,
m_step_type ,
frame - > GetSymbolContext ( eSymbolContextEverything ) . line_entry . range ,
frame - > GetSymbolContext ( eSymbolContextEverything ) ,
2010-06-12 18:59:55 +00:00
stop_other_threads ,
false ) ;
2010-06-08 16:52:24 +00:00
else
new_plan = thread - > QueueThreadPlanForStepSingleInstruction ( true ,
abort_other_plans ,
bool_stop_other_threads ) ;
// FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
// Maybe there should be a parameter to control this.
new_plan - > SetOkayToDiscard ( false ) ;
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( thread - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
process - > Resume ( ) ;
}
else if ( m_step_type = = eStepTypeTrace )
{
thread - > QueueThreadPlanForStepSingleInstruction ( false , abort_other_plans , bool_stop_other_threads ) ;
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( thread - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
process - > Resume ( ) ;
}
else if ( m_step_type = = eStepTypeTraceOver )
{
thread - > QueueThreadPlanForStepSingleInstruction ( true , abort_other_plans , bool_stop_other_threads ) ;
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( thread - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
process - > Resume ( ) ;
}
else if ( m_step_type = = eStepTypeOut )
{
ThreadPlan * new_plan ;
2011-01-21 06:11:58 +00:00
new_plan = thread - > QueueThreadPlanForStepOut ( abort_other_plans ,
NULL ,
false ,
bool_stop_other_threads ,
eVoteYes ,
eVoteNoOpinion ,
thread - > GetSelectedFrameIndex ( ) ) ;
2010-06-08 16:52:24 +00:00
// FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
// Maybe there should be a parameter to control this.
new_plan - > SetOkayToDiscard ( false ) ;
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( thread - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
process - > Resume ( ) ;
}
else
{
result . AppendError ( " step type is not supported " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
if ( synchronous_execution )
{
StateType state = process - > WaitForProcessToStop ( NULL ) ;
//EventSP event_sp;
//StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
//while (! StateIsStoppedState (state))
// {
// state = process->WaitForStateChangedEvents (NULL, event_sp);
// }
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( thread - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
result . SetDidChangeProcessState ( true ) ;
2011-10-19 18:09:39 +00:00
result . AppendMessageWithFormat ( " Process %llu %s \n " , process - > GetID ( ) , StateAsCString ( state ) ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
}
return result . Succeeded ( ) ;
}
protected :
StepType m_step_type ;
StepScope m_step_scope ;
CommandOptions m_options ;
} ;
2011-03-24 21:19:54 +00:00
static OptionEnumValueElement
2010-06-08 16:52:24 +00:00
g_tri_running_mode [ ] =
{
2010-09-18 03:37:20 +00:00
{ eOnlyThisThread , " this-thread " , " Run only this thread " } ,
{ eAllThreads , " all-threads " , " Run all threads " } ,
{ eOnlyDuringStepping , " while-stepping " , " Run only this thread while stepping " } ,
2010-06-08 16:52:24 +00:00
{ 0 , NULL , NULL }
} ;
2011-03-24 21:19:54 +00:00
static OptionEnumValueElement
2010-06-08 16:52:24 +00:00
g_duo_running_mode [ ] =
{
2010-09-18 03:37:20 +00:00
{ eOnlyThisThread , " this-thread " , " Run only this thread " } ,
{ eAllThreads , " all-threads " , " Run all threads " } ,
2010-06-08 16:52:24 +00:00
{ 0 , NULL , NULL }
} ;
2011-03-24 21:19:54 +00:00
OptionDefinition
2010-06-08 16:52:24 +00:00
CommandObjectThreadStepWithTypeAndScope : : CommandOptions : : g_option_table [ ] =
{
2010-10-01 19:59:14 +00:00
{ LLDB_OPT_SET_1 , false , " avoid-no-debug " , ' a ' , required_argument , NULL , 0 , eArgTypeBoolean , " A boolean value that sets whether step-in will step over functions with no debug information. " } ,
{ LLDB_OPT_SET_1 , false , " run-mode " , ' m ' , required_argument , g_tri_running_mode , 0 , eArgTypeRunMode , " Determine how to run other threads while stepping the current thread. " } ,
{ LLDB_OPT_SET_1 , false , " step-over-regexp " , ' r ' , required_argument , NULL , 0 , eArgTypeRegularExpression , " A regular expression that defines function names to step over. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2010-06-08 16:52:24 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectThreadContinue
//-------------------------------------------------------------------------
class CommandObjectThreadContinue : public CommandObject
{
public :
2010-09-18 01:14:36 +00:00
CommandObjectThreadContinue ( CommandInterpreter & interpreter ) :
CommandObject ( interpreter ,
" thread continue " ,
2010-09-08 21:06:11 +00:00
" Continue execution of one or more threads in an active process. " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-06-08 16:52:24 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused )
{
2010-10-04 22:28:36 +00:00
CommandArgumentEntry arg ;
CommandArgumentData thread_idx_arg ;
// Define the first (and only) variant of this arg.
thread_idx_arg . arg_type = eArgTypeThreadIndex ;
thread_idx_arg . arg_repetition = eArgRepeatPlus ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( thread_idx_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
2010-06-08 16:52:24 +00:00
}
virtual
~ CommandObjectThreadContinue ( )
{
}
virtual bool
2010-06-23 01:19:29 +00:00
Execute
(
Args & command ,
CommandReturnObject & result
)
2010-06-08 16:52:24 +00:00
{
2010-09-18 01:14:36 +00:00
bool synchronous_execution = m_interpreter . GetSynchronous ( ) ;
2010-06-08 16:52:24 +00:00
2010-09-18 01:14:36 +00:00
if ( ! m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) )
2010-06-08 16:52:24 +00:00
{
2011-05-03 22:09:39 +00:00
result . AppendError ( " invalid target, create a debug target using the 'target create' command " ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2011-09-22 04:58:26 +00:00
Process * process = m_interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
2010-06-08 16:52:24 +00:00
if ( process = = NULL )
{
result . AppendError ( " no process exists. Cannot continue " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
StateType state = process - > GetState ( ) ;
if ( ( state = = eStateCrashed ) | | ( state = = eStateStopped ) | | ( state = = eStateSuspended ) )
{
const uint32_t num_threads = process - > GetThreadList ( ) . GetSize ( ) ;
uint32_t idx ;
const size_t argc = command . GetArgumentCount ( ) ;
if ( argc > 0 )
{
std : : vector < uint32_t > resume_thread_indexes ;
for ( uint32_t i = 0 ; i < argc ; + + i )
{
idx = Args : : StringToUInt32 ( command . GetArgumentAtIndex ( 0 ) , LLDB_INVALID_INDEX32 ) ;
if ( idx < num_threads )
resume_thread_indexes . push_back ( idx ) ;
else
result . AppendWarningWithFormat ( " Thread index %u out of range. \n " , idx ) ;
}
if ( resume_thread_indexes . empty ( ) )
{
result . AppendError ( " no valid thread indexes were specified " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
else
{
result . AppendMessage ( " Resuming thread " ) ;
for ( idx = 0 ; idx < num_threads ; + + idx )
{
Thread * thread = process - > GetThreadList ( ) . GetThreadAtIndex ( idx ) . get ( ) ;
if ( find ( resume_thread_indexes . begin ( ) , resume_thread_indexes . end ( ) , idx ) ! = resume_thread_indexes . end ( ) )
{
result . AppendMessageWithFormat ( " %u " , idx ) ;
thread - > SetResumeState ( eStateRunning ) ;
}
else
{
thread - > SetResumeState ( eStateSuspended ) ;
}
}
2011-10-19 18:09:39 +00:00
result . AppendMessageWithFormat ( " in process %llu \n " , process - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
}
}
else
{
2010-08-26 21:32:51 +00:00
Thread * current_thread = process - > GetThreadList ( ) . GetSelectedThread ( ) . get ( ) ;
2010-06-08 16:52:24 +00:00
if ( current_thread = = NULL )
{
result . AppendError ( " the process doesn't have a current thread " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Set the actions that the threads should each take when resuming
for ( idx = 0 ; idx < num_threads ; + + idx )
{
Thread * thread = process - > GetThreadList ( ) . GetThreadAtIndex ( idx ) . get ( ) ;
if ( thread = = current_thread )
{
2011-10-19 18:09:39 +00:00
result . AppendMessageWithFormat ( " Resuming thread 0x%4.4llx in process %llu \n " , thread - > GetID ( ) , process - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
thread - > SetResumeState ( eStateRunning ) ;
}
else
{
thread - > SetResumeState ( eStateSuspended ) ;
}
}
}
Error error ( process - > Resume ( ) ) ;
if ( error . Success ( ) )
{
2011-10-19 18:09:39 +00:00
result . AppendMessageWithFormat ( " Process %llu resuming \n " , process - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
if ( synchronous_execution )
{
2010-07-14 00:18:15 +00:00
state = process - > WaitForProcessToStop ( NULL ) ;
2010-06-08 16:52:24 +00:00
result . SetDidChangeProcessState ( true ) ;
2011-10-19 18:09:39 +00:00
result . AppendMessageWithFormat ( " Process %llu %s \n " , process - > GetID ( ) , StateAsCString ( state ) ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . SetStatus ( eReturnStatusSuccessContinuingNoResult ) ;
}
}
else
{
result . AppendErrorWithFormat ( " Failed to resume process: %s \n " , error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
else
{
result . AppendErrorWithFormat ( " Process cannot be continued from its current state (%s). \n " ,
StateAsCString ( state ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
} ;
//-------------------------------------------------------------------------
// CommandObjectThreadUntil
//-------------------------------------------------------------------------
class CommandObjectThreadUntil : public CommandObject
{
public :
class CommandOptions : public Options
{
public :
uint32_t m_thread_idx ;
uint32_t m_frame_idx ;
2011-04-07 22:46:35 +00:00
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
2010-06-08 16:52:24 +00:00
m_thread_idx ( LLDB_INVALID_THREAD_ID ) ,
m_frame_idx ( LLDB_INVALID_FRAME_ID )
{
2011-04-13 00:18:08 +00:00
// Keep default values of all options in one place: OptionParsingStarting ()
OptionParsingStarting ( ) ;
2010-06-08 16:52:24 +00:00
}
virtual
~ CommandOptions ( )
{
}
virtual Error
2011-04-13 00:18:08 +00:00
SetOptionValue ( uint32_t option_idx , const char * option_arg )
2010-06-08 16:52:24 +00:00
{
Error error ;
char short_option = ( char ) m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' t ' :
{
2010-07-14 00:18:15 +00:00
m_thread_idx = Args : : StringToUInt32 ( option_arg , LLDB_INVALID_INDEX32 ) ;
2010-06-08 16:52:24 +00:00
if ( m_thread_idx = = LLDB_INVALID_INDEX32 )
{
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid thread index '%s' " , option_arg ) ;
2010-06-08 16:52:24 +00:00
}
}
break ;
case ' f ' :
{
m_frame_idx = Args : : StringToUInt32 ( option_arg , LLDB_INVALID_FRAME_ID ) ;
if ( m_frame_idx = = LLDB_INVALID_FRAME_ID )
{
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid frame index '%s' " , option_arg ) ;
2010-06-08 16:52:24 +00:00
}
}
break ;
case ' m ' :
{
OptionEnumValueElement * enum_values = g_option_table [ option_idx ] . enum_values ;
2011-10-07 18:58:12 +00:00
lldb : : RunMode run_mode = ( lldb : : RunMode ) Args : : StringToOptionEnum ( option_arg , enum_values , eOnlyDuringStepping , error ) ;
2010-06-08 16:52:24 +00:00
2011-10-07 18:58:12 +00:00
if ( error . Success ( ) )
{
if ( run_mode = = eAllThreads )
m_stop_others = false ;
else
m_stop_others = true ;
}
2010-06-08 16:52:24 +00:00
}
break ;
default :
2011-10-26 00:56:27 +00:00
error . SetErrorStringWithFormat ( " invalid short option character '%c' " , short_option ) ;
2010-06-08 16:52:24 +00:00
break ;
}
return error ;
}
void
2011-04-13 00:18:08 +00:00
OptionParsingStarting ( )
2010-06-08 16:52:24 +00:00
{
m_thread_idx = LLDB_INVALID_THREAD_ID ;
m_frame_idx = 0 ;
m_stop_others = false ;
}
2011-03-24 21:19:54 +00:00
const OptionDefinition *
2010-06-08 16:52:24 +00:00
GetDefinitions ( )
{
return g_option_table ;
}
uint32_t m_step_thread_idx ;
bool m_stop_others ;
// Options table: Required for subclasses of Options.
2011-03-24 21:19:54 +00:00
static OptionDefinition g_option_table [ ] ;
2010-06-08 16:52:24 +00:00
// Instance variables to hold the values for command options.
} ;
2010-09-18 01:14:36 +00:00
CommandObjectThreadUntil ( CommandInterpreter & interpreter ) :
CommandObject ( interpreter ,
" thread until " ,
2010-09-08 21:06:11 +00:00
" Run the current or specified thread until it reaches a given line number or leaves the current function. " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-06-08 16:52:24 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused ) ,
2011-04-07 22:46:35 +00:00
m_options ( interpreter )
2010-06-08 16:52:24 +00:00
{
2010-10-04 22:28:36 +00:00
CommandArgumentEntry arg ;
CommandArgumentData line_num_arg ;
// Define the first (and only) variant of this arg.
line_num_arg . arg_type = eArgTypeLineNum ;
line_num_arg . arg_repetition = eArgRepeatPlain ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( line_num_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
2010-06-08 16:52:24 +00:00
}
virtual
~ CommandObjectThreadUntil ( )
{
}
virtual
Options *
GetOptions ( )
{
return & m_options ;
}
virtual bool
2010-06-23 01:19:29 +00:00
Execute
(
Args & command ,
CommandReturnObject & result
)
2010-06-08 16:52:24 +00:00
{
2010-09-18 01:14:36 +00:00
bool synchronous_execution = m_interpreter . GetSynchronous ( ) ;
2010-06-08 16:52:24 +00:00
2010-09-18 01:14:36 +00:00
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
2010-09-14 23:36:40 +00:00
if ( target = = NULL )
2010-06-08 16:52:24 +00:00
{
2011-05-03 22:09:39 +00:00
result . AppendError ( " invalid target, create a debug target using the 'target create' command " ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2011-09-22 04:58:26 +00:00
Process * process = m_interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
2010-06-08 16:52:24 +00:00
if ( process = = NULL )
{
result . AppendError ( " need a valid process to step " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
else
{
Thread * thread = NULL ;
uint32_t line_number ;
if ( command . GetArgumentCount ( ) ! = 1 )
{
result . AppendErrorWithFormat ( " No line number provided: \n %s " , GetSyntax ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
line_number = Args : : StringToUInt32 ( command . GetArgumentAtIndex ( 0 ) , UINT32_MAX ) ;
if ( line_number = = UINT32_MAX )
{
2011-10-26 00:56:27 +00:00
result . AppendErrorWithFormat ( " invalid line number: '%s'. \n " , command . GetArgumentAtIndex ( 0 ) ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( m_options . m_thread_idx = = LLDB_INVALID_THREAD_ID )
{
2010-08-26 21:32:51 +00:00
thread = process - > GetThreadList ( ) . GetSelectedThread ( ) . get ( ) ;
2010-06-08 16:52:24 +00:00
}
else
{
thread = process - > GetThreadList ( ) . GetThreadAtIndex ( m_options . m_thread_idx ) . get ( ) ;
}
if ( thread = = NULL )
{
const uint32_t num_threads = process - > GetThreadList ( ) . GetSize ( ) ;
2011-05-08 00:56:32 +00:00
result . AppendErrorWithFormat ( " Thread index %u is out of range (valid values are 0 - %u). \n " ,
m_options . m_thread_idx ,
num_threads ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
const bool abort_other_plans = true ;
StackFrame * frame = thread - > GetStackFrameAtIndex ( m_options . m_frame_idx ) . get ( ) ;
if ( frame = = NULL )
{
2011-05-08 00:56:32 +00:00
result . AppendErrorWithFormat ( " Frame index %u is out of range for thread %u. \n " ,
m_options . m_frame_idx ,
m_options . m_thread_idx ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
ThreadPlan * new_plan ;
if ( frame - > HasDebugInformation ( ) )
{
// Finally we got here... Translate the given line number to a bunch of addresses:
SymbolContext sc ( frame - > GetSymbolContext ( eSymbolContextCompUnit ) ) ;
LineTable * line_table = NULL ;
if ( sc . comp_unit )
line_table = sc . comp_unit - > GetLineTable ( ) ;
if ( line_table = = NULL )
{
result . AppendErrorWithFormat ( " Failed to resolve the line table for frame %u of thread index %u. \n " ,
m_options . m_frame_idx , m_options . m_thread_idx ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
LineEntry function_start ;
uint32_t index_ptr = 0 , end_ptr ;
std : : vector < addr_t > address_list ;
// Find the beginning & end index of the
AddressRange fun_addr_range = sc . function - > GetAddressRange ( ) ;
Address fun_start_addr = fun_addr_range . GetBaseAddress ( ) ;
line_table - > FindLineEntryByAddress ( fun_start_addr , function_start , & index_ptr ) ;
2011-05-08 00:56:32 +00:00
Address fun_end_addr ( fun_start_addr . GetSection ( ) ,
fun_start_addr . GetOffset ( ) + fun_addr_range . GetByteSize ( ) ) ;
2010-06-08 16:52:24 +00:00
line_table - > FindLineEntryByAddress ( fun_end_addr , function_start , & end_ptr ) ;
2011-05-08 00:56:32 +00:00
bool all_in_function = true ;
2010-06-08 16:52:24 +00:00
while ( index_ptr < = end_ptr )
{
LineEntry line_entry ;
2011-09-23 00:54:11 +00:00
const bool exact = false ;
index_ptr = sc . comp_unit - > FindLineEntry ( index_ptr , line_number , sc . comp_unit , exact , & line_entry ) ;
2010-06-08 16:52:24 +00:00
if ( index_ptr = = UINT32_MAX )
break ;
2010-09-14 23:36:40 +00:00
addr_t address = line_entry . range . GetBaseAddress ( ) . GetLoadAddress ( target ) ;
2010-06-08 16:52:24 +00:00
if ( address ! = LLDB_INVALID_ADDRESS )
2011-05-08 00:56:32 +00:00
{
if ( fun_addr_range . ContainsLoadAddress ( address , target ) )
address_list . push_back ( address ) ;
else
all_in_function = false ;
}
2010-06-08 16:52:24 +00:00
index_ptr + + ;
}
2011-05-08 00:56:32 +00:00
if ( address_list . size ( ) = = 0 )
{
if ( all_in_function )
result . AppendErrorWithFormat ( " No line entries matching until target. \n " ) ;
else
result . AppendErrorWithFormat ( " Until target outside of the current function. \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
new_plan = thread - > QueueThreadPlanForStepUntil ( abort_other_plans ,
& address_list . front ( ) ,
address_list . size ( ) ,
m_options . m_stop_others ,
thread - > GetSelectedFrameIndex ( ) ) ;
2010-06-08 16:52:24 +00:00
new_plan - > SetOkayToDiscard ( false ) ;
}
else
{
2011-05-08 00:56:32 +00:00
result . AppendErrorWithFormat ( " Frame index %u of thread %u has no debug information. \n " ,
m_options . m_frame_idx ,
m_options . m_thread_idx ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( m_options . m_thread_idx ) ;
2010-06-08 16:52:24 +00:00
Error error ( process - > Resume ( ) ) ;
if ( error . Success ( ) )
{
2011-10-19 18:09:39 +00:00
result . AppendMessageWithFormat ( " Process %llu resuming \n " , process - > GetID ( ) ) ;
2010-06-08 16:52:24 +00:00
if ( synchronous_execution )
{
StateType state = process - > WaitForProcessToStop ( NULL ) ;
result . SetDidChangeProcessState ( true ) ;
2011-10-19 18:09:39 +00:00
result . AppendMessageWithFormat ( " Process %llu %s \n " , process - > GetID ( ) , StateAsCString ( state ) ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . SetStatus ( eReturnStatusSuccessContinuingNoResult ) ;
}
}
else
{
result . AppendErrorWithFormat ( " Failed to resume process: %s. \n " , error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
return result . Succeeded ( ) ;
}
protected :
CommandOptions m_options ;
} ;
2011-03-24 21:19:54 +00:00
OptionDefinition
2010-06-08 16:52:24 +00:00
CommandObjectThreadUntil : : CommandOptions : : g_option_table [ ] =
{
2010-10-04 22:28:36 +00:00
{ LLDB_OPT_SET_1 , false , " frame " , ' f ' , required_argument , NULL , 0 , eArgTypeFrameIndex , " Frame index for until operation - defaults to 0 " } ,
2010-10-01 19:59:14 +00:00
{ LLDB_OPT_SET_1 , false , " thread " , ' t ' , required_argument , NULL , 0 , eArgTypeThreadIndex , " Thread index for the thread for until operation " } ,
{ LLDB_OPT_SET_1 , false , " run-mode " , ' m ' , required_argument , g_duo_running_mode , 0 , eArgTypeRunMode , " Determine how to run other threads while stepping this one " } ,
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2010-06-08 16:52:24 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectThreadSelect
//-------------------------------------------------------------------------
class CommandObjectThreadSelect : public CommandObject
{
public :
2010-09-18 01:14:36 +00:00
CommandObjectThreadSelect ( CommandInterpreter & interpreter ) :
CommandObject ( interpreter ,
" thread select " ,
" Select a thread as the currently active thread. " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-09-18 01:14:36 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused )
2010-06-08 16:52:24 +00:00
{
2010-10-04 22:28:36 +00:00
CommandArgumentEntry arg ;
CommandArgumentData thread_idx_arg ;
// Define the first (and only) variant of this arg.
thread_idx_arg . arg_type = eArgTypeThreadIndex ;
thread_idx_arg . arg_repetition = eArgRepeatPlain ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( thread_idx_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
2010-06-08 16:52:24 +00:00
}
virtual
~ CommandObjectThreadSelect ( )
{
}
virtual bool
2010-06-23 01:19:29 +00:00
Execute
(
Args & command ,
CommandReturnObject & result
)
2010-06-08 16:52:24 +00:00
{
2011-09-22 04:58:26 +00:00
Process * process = m_interpreter . GetExecutionContext ( ) . GetProcessPtr ( ) ;
2010-06-08 16:52:24 +00:00
if ( process = = NULL )
{
result . AppendError ( " no process " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
else if ( command . GetArgumentCount ( ) ! = 1 )
{
2011-09-20 21:44:10 +00:00
result . AppendErrorWithFormat ( " '%s' takes exactly one thread index argument: \n Usage: %s \n " , m_cmd_name . c_str ( ) , m_cmd_syntax . c_str ( ) ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
uint32_t index_id = Args : : StringToUInt32 ( command . GetArgumentAtIndex ( 0 ) , 0 , 0 ) ;
Thread * new_thread = process - > GetThreadList ( ) . FindThreadByIndexID ( index_id ) . get ( ) ;
if ( new_thread = = NULL )
{
2011-10-26 00:56:27 +00:00
result . AppendErrorWithFormat ( " invalid thread #%s. \n " , command . GetArgumentAtIndex ( 0 ) ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-08-26 21:32:51 +00:00
process - > GetThreadList ( ) . SetSelectedThreadByID ( new_thread - > GetID ( ) ) ;
2010-09-14 00:53:53 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2010-06-08 16:52:24 +00:00
2011-04-18 08:33:37 +00:00
const uint32_t start_frame = 0 ;
const uint32_t num_frames = 1 ;
const uint32_t num_frames_with_source = 1 ;
new_thread - > GetStatus ( result . GetOutputStream ( ) ,
start_frame ,
num_frames ,
num_frames_with_source ) ;
2010-06-08 16:52:24 +00:00
return result . Succeeded ( ) ;
}
} ;
//-------------------------------------------------------------------------
// CommandObjectThreadList
//-------------------------------------------------------------------------
2010-06-23 01:19:29 +00:00
class CommandObjectThreadList : public CommandObject
2010-06-08 16:52:24 +00:00
{
2010-06-23 01:19:29 +00:00
public :
2010-06-08 16:52:24 +00:00
2010-09-18 01:14:36 +00:00
CommandObjectThreadList ( CommandInterpreter & interpreter ) :
CommandObject ( interpreter ,
" thread list " ,
2010-09-08 21:06:11 +00:00
" Show a summary of all current threads in a process. " ,
2010-06-23 01:19:29 +00:00
" thread list " ,
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused )
2010-06-08 16:52:24 +00:00
{
2010-06-23 01:19:29 +00:00
}
2010-06-08 16:52:24 +00:00
2010-06-23 01:19:29 +00:00
~ CommandObjectThreadList ( )
{
}
bool
Execute
(
Args & command ,
CommandReturnObject & result
)
{
2011-02-19 02:53:09 +00:00
Stream & strm = result . GetOutputStream ( ) ;
2010-06-23 01:19:29 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2011-04-12 05:54:46 +00:00
ExecutionContext exe_ctx ( m_interpreter . GetExecutionContext ( ) ) ;
2011-09-22 04:58:26 +00:00
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
2010-06-08 16:52:24 +00:00
{
2011-04-18 08:33:37 +00:00
const bool only_threads_with_stop_reason = false ;
const uint32_t start_frame = 0 ;
const uint32_t num_frames = 0 ;
const uint32_t num_frames_with_source = 0 ;
2011-09-22 04:58:26 +00:00
process - > GetStatus ( strm ) ;
process - > GetThreadStatus ( strm ,
only_threads_with_stop_reason ,
start_frame ,
num_frames ,
num_frames_with_source ) ;
2010-06-08 16:52:24 +00:00
}
else
{
2010-06-23 01:19:29 +00:00
result . AppendError ( " no current location or status available " ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
}
2010-06-23 01:19:29 +00:00
return result . Succeeded ( ) ;
2010-06-08 16:52:24 +00:00
}
2010-06-23 01:19:29 +00:00
} ;
2010-06-08 16:52:24 +00:00
//-------------------------------------------------------------------------
// CommandObjectMultiwordThread
//-------------------------------------------------------------------------
2010-06-23 01:19:29 +00:00
CommandObjectMultiwordThread : : CommandObjectMultiwordThread ( CommandInterpreter & interpreter ) :
2010-09-18 01:14:36 +00:00
CommandObjectMultiword ( interpreter ,
" thread " ,
2010-09-07 22:38:08 +00:00
" A set of commands for operating on one or more threads within a running process. " ,
2010-06-08 16:52:24 +00:00
" thread <subcommand> [<subcommand-options>] " )
{
2010-09-18 01:14:36 +00:00
LoadSubCommand ( " backtrace " , CommandObjectSP ( new CommandObjectThreadBacktrace ( interpreter ) ) ) ;
LoadSubCommand ( " continue " , CommandObjectSP ( new CommandObjectThreadContinue ( interpreter ) ) ) ;
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectThreadList ( interpreter ) ) ) ;
LoadSubCommand ( " select " , CommandObjectSP ( new CommandObjectThreadSelect ( interpreter ) ) ) ;
LoadSubCommand ( " until " , CommandObjectSP ( new CommandObjectThreadUntil ( interpreter ) ) ) ;
LoadSubCommand ( " step-in " , CommandObjectSP ( new CommandObjectThreadStepWithTypeAndScope (
interpreter ,
2010-06-23 01:19:29 +00:00
" thread step-in " ,
2010-09-18 01:14:36 +00:00
" Source level single step in specified thread (current thread, if none specified). " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-09-18 01:14:36 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused ,
eStepTypeInto ,
eStepScopeSource ) ) ) ;
2010-06-23 01:19:29 +00:00
2010-09-18 01:14:36 +00:00
LoadSubCommand ( " step-out " , CommandObjectSP ( new CommandObjectThreadStepWithTypeAndScope (
interpreter ,
" thread step-out " ,
2011-06-14 03:55:29 +00:00
" Finish executing the current function and return to its call site in specified thread (current thread, if none specified). " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-09-18 01:14:36 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused ,
eStepTypeOut ,
eStepScopeSource ) ) ) ;
2010-06-08 16:52:24 +00:00
2010-09-18 01:14:36 +00:00
LoadSubCommand ( " step-over " , CommandObjectSP ( new CommandObjectThreadStepWithTypeAndScope (
interpreter ,
" thread step-over " ,
" Source level single step in specified thread (current thread, if none specified), stepping over calls. " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-09-18 01:14:36 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused ,
eStepTypeOver ,
eStepScopeSource ) ) ) ;
2010-06-08 16:52:24 +00:00
2010-09-18 01:14:36 +00:00
LoadSubCommand ( " step-inst " , CommandObjectSP ( new CommandObjectThreadStepWithTypeAndScope (
interpreter ,
" thread step-inst " ,
" Single step one instruction in specified thread (current thread, if none specified). " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-09-18 01:14:36 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused ,
eStepTypeTrace ,
eStepScopeInstruction ) ) ) ;
2010-06-23 01:19:29 +00:00
2010-09-18 01:14:36 +00:00
LoadSubCommand ( " step-inst-over " , CommandObjectSP ( new CommandObjectThreadStepWithTypeAndScope (
interpreter ,
" thread step-inst-over " ,
" Single step one instruction in specified thread (current thread, if none specified), stepping over calls. " ,
2010-10-04 22:28:36 +00:00
NULL ,
2010-09-18 01:14:36 +00:00
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused ,
eStepTypeTraceOver ,
eStepScopeInstruction ) ) ) ;
2010-06-08 16:52:24 +00:00
}
CommandObjectMultiwordThread : : ~ CommandObjectMultiwordThread ( )
{
}