2013-08-23 17:46:38 +00:00
//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "CommandObjectBreakpoint.h"
# include "CommandObjectBreakpointCommand.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
# include "lldb/Breakpoint/Breakpoint.h"
# include "lldb/Breakpoint/BreakpointIDList.h"
# include "lldb/Breakpoint/BreakpointLocation.h"
2015-02-09 01:44:09 +00:00
# include "lldb/Host/StringConvert.h"
2013-08-23 17:46:38 +00:00
# include "lldb/Interpreter/Options.h"
2015-07-03 16:57:06 +00:00
# include "lldb/Interpreter/OptionValueBoolean.h"
2015-02-06 21:38:51 +00:00
# include "lldb/Interpreter/OptionValueString.h"
# include "lldb/Interpreter/OptionValueUInt64.h"
2013-08-23 17:46:38 +00:00
# include "lldb/Core/RegularExpression.h"
# include "lldb/Core/StreamString.h"
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandReturnObject.h"
2015-12-30 11:55:28 +00:00
# include "lldb/Target/Language.h"
2013-08-23 17:46:38 +00:00
# include "lldb/Target/Target.h"
# include "lldb/Interpreter/CommandCompletions.h"
# include "lldb/Target/StackFrame.h"
# include "lldb/Target/Thread.h"
# include "lldb/Target/ThreadSpec.h"
# include <vector>
using namespace lldb ;
using namespace lldb_private ;
static void
AddBreakpointDescription ( Stream * s , Breakpoint * bp , lldb : : DescriptionLevel level )
{
s - > IndentMore ( ) ;
bp - > GetDescription ( s , level , true ) ;
s - > IndentLess ( ) ;
s - > EOL ( ) ;
}
//-------------------------------------------------------------------------
// CommandObjectBreakpointSet
//-------------------------------------------------------------------------
class CommandObjectBreakpointSet : public CommandObjectParsed
{
public :
typedef enum BreakpointSetType
{
eSetTypeInvalid ,
eSetTypeFileAndLine ,
eSetTypeAddress ,
eSetTypeFunctionName ,
eSetTypeFunctionRegexp ,
eSetTypeSourceRegexp ,
eSetTypeException
} BreakpointSetType ;
CommandObjectBreakpointSet ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" breakpoint set " ,
" Sets a breakpoint or set of breakpoints in the executable. " ,
" breakpoint set <cmd-options> " ) ,
m_options ( interpreter )
{
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointSet ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Options *
GetOptions ( ) override
2013-08-23 17:46:38 +00:00
{
return & m_options ;
}
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
m_condition ( ) ,
m_filenames ( ) ,
m_line_num ( 0 ) ,
m_column ( 0 ) ,
m_func_names ( ) ,
m_func_name_type_mask ( eFunctionNameTypeNone ) ,
m_func_regexp ( ) ,
m_source_text_regexp ( ) ,
m_modules ( ) ,
m_load_addr ( ) ,
m_ignore_count ( 0 ) ,
m_thread_id ( LLDB_INVALID_THREAD_ID ) ,
m_thread_index ( UINT32_MAX ) ,
m_thread_name ( ) ,
m_queue_name ( ) ,
m_catch_bp ( false ) ,
m_throw_bp ( true ) ,
2013-11-06 16:48:53 +00:00
m_hardware ( false ) ,
2015-07-03 16:57:06 +00:00
m_exception_language ( eLanguageTypeUnknown ) ,
2015-12-30 11:55:28 +00:00
m_language ( lldb : : eLanguageTypeUnknown ) ,
2013-08-23 17:46:38 +00:00
m_skip_prologue ( eLazyBoolCalculate ) ,
2015-07-03 16:57:06 +00:00
m_one_shot ( false ) ,
m_all_files ( false ) ,
m_move_to_nearest_code ( eLazyBoolCalculate )
2013-08-23 17:46:38 +00:00
{
}
2015-12-30 11:55:28 +00:00
~ CommandOptions ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 17:46:38 +00:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' a ' :
{
ExecutionContext exe_ctx ( m_interpreter . GetExecutionContext ( ) ) ;
m_load_addr = Args : : StringToAddress ( & exe_ctx , option_arg , LLDB_INVALID_ADDRESS , & error ) ;
}
break ;
2015-07-03 16:57:06 +00:00
case ' A ' :
m_all_files = true ;
break ;
2013-08-23 17:46:38 +00:00
case ' b ' :
m_func_names . push_back ( option_arg ) ;
m_func_name_type_mask | = eFunctionNameTypeBase ;
break ;
case ' C ' :
2015-07-03 16:57:06 +00:00
{
bool success ;
m_column = StringConvert : : ToUInt32 ( option_arg , 0 , 0 , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " invalid column number: %s " , option_arg ) ;
2013-08-23 17:46:38 +00:00
break ;
2015-07-03 16:57:06 +00:00
}
2013-08-23 17:46:38 +00:00
case ' c ' :
m_condition . assign ( option_arg ) ;
break ;
2015-02-06 21:38:51 +00:00
case ' D ' :
m_use_dummy = true ;
break ;
2013-08-23 17:46:38 +00:00
case ' E ' :
{
2015-12-30 11:55:28 +00:00
LanguageType language = Language : : GetLanguageTypeFromString ( option_arg ) ;
2013-08-23 17:46:38 +00:00
switch ( language )
{
case eLanguageTypeC89 :
case eLanguageTypeC :
case eLanguageTypeC99 :
2014-11-25 21:00:58 +00:00
case eLanguageTypeC11 :
2015-07-03 16:57:06 +00:00
m_exception_language = eLanguageTypeC ;
2013-08-23 17:46:38 +00:00
break ;
case eLanguageTypeC_plus_plus :
2014-11-25 21:00:58 +00:00
case eLanguageTypeC_plus_plus_03 :
case eLanguageTypeC_plus_plus_11 :
2015-02-09 01:44:09 +00:00
case eLanguageTypeC_plus_plus_14 :
2015-07-03 16:57:06 +00:00
m_exception_language = eLanguageTypeC_plus_plus ;
2013-08-23 17:46:38 +00:00
break ;
case eLanguageTypeObjC :
2015-07-03 16:57:06 +00:00
m_exception_language = eLanguageTypeObjC ;
2013-08-23 17:46:38 +00:00
break ;
case eLanguageTypeObjC_plus_plus :
error . SetErrorStringWithFormat ( " Set exception breakpoints separately for c++ and objective-c " ) ;
break ;
case eLanguageTypeUnknown :
error . SetErrorStringWithFormat ( " Unknown language type: '%s' for exception breakpoint " , option_arg ) ;
break ;
default :
error . SetErrorStringWithFormat ( " Unsupported language type: '%s' for exception breakpoint " , option_arg ) ;
}
}
break ;
case ' f ' :
m_filenames . AppendIfUnique ( FileSpec ( option_arg , false ) ) ;
break ;
case ' F ' :
m_func_names . push_back ( option_arg ) ;
m_func_name_type_mask | = eFunctionNameTypeFull ;
break ;
case ' h ' :
2013-11-06 16:48:53 +00:00
{
bool success ;
m_catch_bp = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " Invalid boolean value for on-catch option: '%s' " , option_arg ) ;
}
break ;
case ' H ' :
m_hardware = true ;
break ;
2013-08-23 17:46:38 +00:00
case ' i ' :
{
2015-02-09 01:44:09 +00:00
m_ignore_count = StringConvert : : ToUInt32 ( option_arg , UINT32_MAX , 0 ) ;
2013-08-23 17:46:38 +00:00
if ( m_ignore_count = = UINT32_MAX )
error . SetErrorStringWithFormat ( " invalid ignore count '%s' " , option_arg ) ;
break ;
}
case ' K ' :
{
bool success ;
bool value ;
value = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( value )
m_skip_prologue = eLazyBoolYes ;
else
m_skip_prologue = eLazyBoolNo ;
if ( ! success )
error . SetErrorStringWithFormat ( " Invalid boolean value for skip prologue option: '%s' " , option_arg ) ;
}
break ;
case ' l ' :
2015-07-03 16:57:06 +00:00
{
bool success ;
m_line_num = StringConvert : : ToUInt32 ( option_arg , 0 , 0 , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " invalid line number: %s. " , option_arg ) ;
break ;
}
2015-12-30 11:55:28 +00:00
case ' L ' :
m_language = Language : : GetLanguageTypeFromString ( option_arg ) ;
if ( m_language = = eLanguageTypeUnknown )
error . SetErrorStringWithFormat ( " Unknown language type: '%s' for breakpoint " , option_arg ) ;
break ;
2015-07-03 16:57:06 +00:00
case ' m ' :
{
bool success ;
bool value ;
value = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( value )
m_move_to_nearest_code = eLazyBoolYes ;
else
m_move_to_nearest_code = eLazyBoolNo ;
if ( ! success )
error . SetErrorStringWithFormat ( " Invalid boolean value for move-to-nearest-code option: '%s' " , option_arg ) ;
2013-08-23 17:46:38 +00:00
break ;
2015-07-03 16:57:06 +00:00
}
2013-08-23 17:46:38 +00:00
case ' M ' :
m_func_names . push_back ( option_arg ) ;
m_func_name_type_mask | = eFunctionNameTypeMethod ;
break ;
case ' n ' :
m_func_names . push_back ( option_arg ) ;
m_func_name_type_mask | = eFunctionNameTypeAuto ;
break ;
2015-02-06 21:38:51 +00:00
case ' N ' :
if ( BreakpointID : : StringIsBreakpointName ( option_arg , error ) )
m_breakpoint_names . push_back ( option_arg ) ;
break ;
2013-08-23 17:46:38 +00:00
case ' o ' :
m_one_shot = true ;
break ;
2015-07-03 16:57:06 +00:00
case ' O ' :
m_exception_extra_args . AppendArgument ( " -O " ) ;
m_exception_extra_args . AppendArgument ( option_arg ) ;
break ;
2013-08-23 17:46:38 +00:00
case ' p ' :
m_source_text_regexp . assign ( option_arg ) ;
break ;
case ' q ' :
m_queue_name . assign ( option_arg ) ;
break ;
case ' r ' :
m_func_regexp . assign ( option_arg ) ;
break ;
case ' s ' :
{
m_modules . AppendIfUnique ( FileSpec ( option_arg , false ) ) ;
break ;
}
case ' S ' :
m_func_names . push_back ( option_arg ) ;
m_func_name_type_mask | = eFunctionNameTypeSelector ;
break ;
case ' t ' :
{
2015-02-09 01:44:09 +00:00
m_thread_id = StringConvert : : ToUInt64 ( option_arg , LLDB_INVALID_THREAD_ID , 0 ) ;
2013-08-23 17:46:38 +00:00
if ( m_thread_id = = LLDB_INVALID_THREAD_ID )
error . SetErrorStringWithFormat ( " invalid thread id string '%s' " , option_arg ) ;
}
break ;
case ' T ' :
m_thread_name . assign ( option_arg ) ;
break ;
case ' w ' :
{
bool success ;
m_throw_bp = Args : : StringToBoolean ( option_arg , true , & success ) ;
if ( ! success )
error . SetErrorStringWithFormat ( " Invalid boolean value for on-throw option: '%s' " , option_arg ) ;
}
break ;
case ' x ' :
{
2015-02-09 01:44:09 +00:00
m_thread_index = StringConvert : : ToUInt32 ( option_arg , UINT32_MAX , 0 ) ;
2013-08-23 17:46:38 +00:00
if ( m_thread_id = = UINT32_MAX )
error . SetErrorStringWithFormat ( " invalid thread index string '%s' " , option_arg ) ;
}
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 11:55:28 +00:00
OptionParsingStarting ( ) override
2013-08-23 17:46:38 +00:00
{
m_condition . clear ( ) ;
m_filenames . Clear ( ) ;
m_line_num = 0 ;
m_column = 0 ;
m_func_names . clear ( ) ;
m_func_name_type_mask = eFunctionNameTypeNone ;
m_func_regexp . clear ( ) ;
m_source_text_regexp . clear ( ) ;
m_modules . Clear ( ) ;
m_load_addr = LLDB_INVALID_ADDRESS ;
m_ignore_count = 0 ;
m_thread_id = LLDB_INVALID_THREAD_ID ;
m_thread_index = UINT32_MAX ;
m_thread_name . clear ( ) ;
m_queue_name . clear ( ) ;
m_catch_bp = false ;
m_throw_bp = true ;
2013-11-06 16:48:53 +00:00
m_hardware = false ;
2015-07-03 16:57:06 +00:00
m_exception_language = eLanguageTypeUnknown ;
2015-12-30 11:55:28 +00:00
m_language = lldb : : eLanguageTypeUnknown ;
2013-08-23 17:46:38 +00:00
m_skip_prologue = eLazyBoolCalculate ;
m_one_shot = false ;
2015-02-06 21:38:51 +00:00
m_use_dummy = false ;
m_breakpoint_names . clear ( ) ;
2015-07-03 16:57:06 +00:00
m_all_files = false ;
m_exception_extra_args . Clear ( ) ;
m_move_to_nearest_code = eLazyBoolCalculate ;
2013-08-23 17:46:38 +00:00
}
const OptionDefinition *
2015-12-30 11:55:28 +00:00
GetDefinitions ( ) override
2013-08-23 17:46:38 +00:00
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
std : : string m_condition ;
FileSpecList m_filenames ;
uint32_t m_line_num ;
uint32_t m_column ;
std : : vector < std : : string > m_func_names ;
2015-02-06 21:38:51 +00:00
std : : vector < std : : string > m_breakpoint_names ;
2013-08-23 17:46:38 +00:00
uint32_t m_func_name_type_mask ;
std : : string m_func_regexp ;
std : : string m_source_text_regexp ;
FileSpecList m_modules ;
lldb : : addr_t m_load_addr ;
uint32_t m_ignore_count ;
lldb : : tid_t m_thread_id ;
uint32_t m_thread_index ;
std : : string m_thread_name ;
std : : string m_queue_name ;
bool m_catch_bp ;
bool m_throw_bp ;
2013-11-06 16:48:53 +00:00
bool m_hardware ; // Request to use hardware breakpoints
2015-07-03 16:57:06 +00:00
lldb : : LanguageType m_exception_language ;
2015-12-30 11:55:28 +00:00
lldb : : LanguageType m_language ;
2013-08-23 17:46:38 +00:00
LazyBool m_skip_prologue ;
bool m_one_shot ;
2015-02-06 21:38:51 +00:00
bool m_use_dummy ;
2015-07-03 16:57:06 +00:00
bool m_all_files ;
Args m_exception_extra_args ;
LazyBool m_move_to_nearest_code ;
2013-08-23 17:46:38 +00:00
} ;
protected :
2015-12-30 11:55:28 +00:00
bool
2013-08-23 17:46:38 +00:00
DoExecute ( Args & command ,
2015-12-30 11:55:28 +00:00
CommandReturnObject & result ) override
2013-08-23 17:46:38 +00:00
{
2015-02-06 21:38:51 +00:00
Target * target = GetSelectedOrDummyTarget ( m_options . m_use_dummy ) ;
if ( target = = nullptr )
2013-08-23 17:46:38 +00:00
{
result . AppendError ( " Invalid target. Must set target before setting breakpoints (see 'target create' command). " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// The following are the various types of breakpoints that could be set:
// 1). -f -l -p [-s -g] (setting breakpoint by source location)
// 2). -a [-s -g] (setting breakpoint by address)
// 3). -n [-s -g] (setting breakpoint by function name)
// 4). -r [-s -g] (setting breakpoint by function name regular expression)
// 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
// 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
BreakpointSetType break_type = eSetTypeInvalid ;
if ( m_options . m_line_num ! = 0 )
break_type = eSetTypeFileAndLine ;
else if ( m_options . m_load_addr ! = LLDB_INVALID_ADDRESS )
break_type = eSetTypeAddress ;
else if ( ! m_options . m_func_names . empty ( ) )
break_type = eSetTypeFunctionName ;
else if ( ! m_options . m_func_regexp . empty ( ) )
break_type = eSetTypeFunctionRegexp ;
else if ( ! m_options . m_source_text_regexp . empty ( ) )
break_type = eSetTypeSourceRegexp ;
2015-07-03 16:57:06 +00:00
else if ( m_options . m_exception_language ! = eLanguageTypeUnknown )
2013-08-23 17:46:38 +00:00
break_type = eSetTypeException ;
Breakpoint * bp = NULL ;
FileSpec module_spec ;
const bool internal = false ;
switch ( break_type )
{
case eSetTypeFileAndLine : // Breakpoint by source position
{
FileSpec file ;
const size_t num_files = m_options . m_filenames . GetSize ( ) ;
if ( num_files = = 0 )
{
if ( ! GetDefaultFile ( target , file , result ) )
{
result . AppendError ( " No file supplied and no default file available. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
else if ( num_files > 1 )
{
result . AppendError ( " Only one file at a time is allowed for file and line breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
else
file = m_options . m_filenames . GetFileSpecAtIndex ( 0 ) ;
// Only check for inline functions if
LazyBool check_inlines = eLazyBoolCalculate ;
bp = target - > CreateBreakpoint ( & ( m_options . m_modules ) ,
file ,
m_options . m_line_num ,
check_inlines ,
m_options . m_skip_prologue ,
2013-11-06 16:48:53 +00:00
internal ,
2015-07-03 16:57:06 +00:00
m_options . m_hardware ,
m_options . m_move_to_nearest_code ) . get ( ) ;
2013-08-23 17:46:38 +00:00
}
break ;
case eSetTypeAddress : // Breakpoint by address
2015-12-30 11:55:28 +00:00
{
// If a shared library has been specified, make an lldb_private::Address with the library, and
// use that. That way the address breakpoint will track the load location of the library.
size_t num_modules_specified = m_options . m_modules . GetSize ( ) ;
if ( num_modules_specified = = 1 )
{
const FileSpec * file_spec = m_options . m_modules . GetFileSpecPointerAtIndex ( 0 ) ;
bp = target - > CreateAddressInModuleBreakpoint ( m_options . m_load_addr ,
internal ,
file_spec ,
m_options . m_hardware ) . get ( ) ;
}
else if ( num_modules_specified = = 0 )
{
bp = target - > CreateBreakpoint ( m_options . m_load_addr ,
internal ,
m_options . m_hardware ) . get ( ) ;
}
else
{
result . AppendError ( " Only one shared library can be specified for address breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-08-23 17:46:38 +00:00
break ;
2015-12-30 11:55:28 +00:00
}
2013-08-23 17:46:38 +00:00
case eSetTypeFunctionName : // Breakpoint by function name
{
uint32_t name_type_mask = m_options . m_func_name_type_mask ;
if ( name_type_mask = = 0 )
name_type_mask = eFunctionNameTypeAuto ;
bp = target - > CreateBreakpoint ( & ( m_options . m_modules ) ,
& ( m_options . m_filenames ) ,
m_options . m_func_names ,
name_type_mask ,
2015-12-30 11:55:28 +00:00
m_options . m_language ,
2013-08-23 17:46:38 +00:00
m_options . m_skip_prologue ,
2013-11-06 16:48:53 +00:00
internal ,
m_options . m_hardware ) . get ( ) ;
2013-08-23 17:46:38 +00:00
}
break ;
case eSetTypeFunctionRegexp : // Breakpoint by regular expression function name
{
RegularExpression regexp ( m_options . m_func_regexp . c_str ( ) ) ;
if ( ! regexp . IsValid ( ) )
{
char err_str [ 1024 ] ;
regexp . GetErrorAsCString ( err_str , sizeof ( err_str ) ) ;
result . AppendErrorWithFormat ( " Function name regular expression could not be compiled: \" %s \" " ,
err_str ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
bp = target - > CreateFuncRegexBreakpoint ( & ( m_options . m_modules ) ,
& ( m_options . m_filenames ) ,
regexp ,
2015-12-30 11:55:28 +00:00
m_options . m_language ,
2013-08-23 17:46:38 +00:00
m_options . m_skip_prologue ,
2013-11-06 16:48:53 +00:00
internal ,
m_options . m_hardware ) . get ( ) ;
2013-08-23 17:46:38 +00:00
}
break ;
case eSetTypeSourceRegexp : // Breakpoint by regexp on source text.
{
const size_t num_files = m_options . m_filenames . GetSize ( ) ;
2015-07-03 16:57:06 +00:00
if ( num_files = = 0 & & ! m_options . m_all_files )
2013-08-23 17:46:38 +00:00
{
FileSpec file ;
if ( ! GetDefaultFile ( target , file , result ) )
{
result . AppendError ( " No files provided and could not find default file. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
else
{
m_options . m_filenames . Append ( file ) ;
}
}
RegularExpression regexp ( m_options . m_source_text_regexp . c_str ( ) ) ;
if ( ! regexp . IsValid ( ) )
{
char err_str [ 1024 ] ;
regexp . GetErrorAsCString ( err_str , sizeof ( err_str ) ) ;
result . AppendErrorWithFormat ( " Source text regular expression could not be compiled: \" %s \" " ,
err_str ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-11-06 16:48:53 +00:00
bp = target - > CreateSourceRegexBreakpoint ( & ( m_options . m_modules ) ,
& ( m_options . m_filenames ) ,
regexp ,
internal ,
2015-07-03 16:57:06 +00:00
m_options . m_hardware ,
m_options . m_move_to_nearest_code ) . get ( ) ;
2013-08-23 17:46:38 +00:00
}
break ;
case eSetTypeException :
{
2015-07-03 16:57:06 +00:00
Error precond_error ;
bp = target - > CreateExceptionBreakpoint ( m_options . m_exception_language ,
2013-11-06 16:48:53 +00:00
m_options . m_catch_bp ,
m_options . m_throw_bp ,
2015-07-03 16:57:06 +00:00
internal ,
& m_options . m_exception_extra_args ,
& precond_error ) . get ( ) ;
if ( precond_error . Fail ( ) )
{
result . AppendErrorWithFormat ( " Error setting extra exception arguments: %s " ,
precond_error . AsCString ( ) ) ;
target - > RemoveBreakpointByID ( bp - > GetID ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-08-23 17:46:38 +00:00
}
break ;
default :
break ;
}
// Now set the various options that were passed in:
if ( bp )
{
if ( m_options . m_thread_id ! = LLDB_INVALID_THREAD_ID )
bp - > SetThreadID ( m_options . m_thread_id ) ;
if ( m_options . m_thread_index ! = UINT32_MAX )
bp - > GetOptions ( ) - > GetThreadSpec ( ) - > SetIndex ( m_options . m_thread_index ) ;
if ( ! m_options . m_thread_name . empty ( ) )
bp - > GetOptions ( ) - > GetThreadSpec ( ) - > SetName ( m_options . m_thread_name . c_str ( ) ) ;
if ( ! m_options . m_queue_name . empty ( ) )
bp - > GetOptions ( ) - > GetThreadSpec ( ) - > SetQueueName ( m_options . m_queue_name . c_str ( ) ) ;
if ( m_options . m_ignore_count ! = 0 )
bp - > GetOptions ( ) - > SetIgnoreCount ( m_options . m_ignore_count ) ;
if ( ! m_options . m_condition . empty ( ) )
bp - > GetOptions ( ) - > SetCondition ( m_options . m_condition . c_str ( ) ) ;
2015-02-06 21:38:51 +00:00
if ( ! m_options . m_breakpoint_names . empty ( ) )
{
Error error ; // We don't need to check the error here, since the option parser checked it...
for ( auto name : m_options . m_breakpoint_names )
bp - > AddName ( name . c_str ( ) , error ) ;
}
2013-08-23 17:46:38 +00:00
bp - > SetOneShot ( m_options . m_one_shot ) ;
}
if ( bp )
{
Stream & output_stream = result . GetOutputStream ( ) ;
const bool show_locations = false ;
bp - > GetDescription ( & output_stream , lldb : : eDescriptionLevelInitial , show_locations ) ;
2015-02-06 21:38:51 +00:00
if ( target = = m_interpreter . GetDebugger ( ) . GetDummyTarget ( ) )
output_stream . Printf ( " Breakpoint set in dummy target, will get copied into future targets. \n " ) ;
else
{
// Don't print out this warning for exception breakpoints. They can get set before the target
// is set, but we won't know how to actually set the breakpoint till we run.
if ( bp - > GetNumLocations ( ) = = 0 & & break_type ! = eSetTypeException )
{
output_stream . Printf ( " WARNING: Unable to resolve breakpoint to any actual locations. \n " ) ;
}
}
2013-08-23 17:46:38 +00:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
else if ( ! bp )
{
result . AppendError ( " Breakpoint creation failed: No breakpoint created. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
private :
bool
GetDefaultFile ( Target * target , FileSpec & file , CommandReturnObject & result )
{
uint32_t default_line ;
// First use the Source Manager's default file.
// Then use the current stack frame's file.
if ( ! target - > GetSourceManager ( ) . GetDefaultFileAndLine ( file , default_line ) )
{
StackFrame * cur_frame = m_exe_ctx . GetFramePtr ( ) ;
if ( cur_frame = = NULL )
{
result . AppendError ( " No selected frame to use to find the default file. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
else if ( ! cur_frame - > HasDebugInformation ( ) )
{
result . AppendError ( " Cannot use the selected frame to find the default file, it has no debug info. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
else
{
const SymbolContext & sc = cur_frame - > GetSymbolContext ( eSymbolContextLineEntry ) ;
if ( sc . line_entry . file )
{
file = sc . line_entry . file ;
}
else
{
result . AppendError ( " Can't find the file for the selected frame to use as the default file. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
}
return true ;
}
CommandOptions m_options ;
} ;
// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
# define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
# define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
# define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
2015-07-03 16:57:06 +00:00
# define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
2015-12-30 11:55:28 +00:00
# define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
2013-08-23 17:46:38 +00:00
OptionDefinition
CommandObjectBreakpointSet : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_NOT_10 , false , " shlib " , ' s ' , OptionParser : : eRequiredArgument , NULL , NULL , CommandCompletions : : eModuleCompletion , eArgTypeShlibName ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint only in this shared library. "
" Can repeat this option multiple times to specify multiple shared libraries. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " ignore-count " , ' i ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeCount ,
2013-08-23 17:46:38 +00:00
" Set the number of times this breakpoint is skipped before stopping. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " one-shot " , ' o ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2013-08-23 17:46:38 +00:00
" The breakpoint is deleted the first time it causes a stop. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " condition " , ' c ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeExpression ,
2013-08-23 17:46:38 +00:00
" The breakpoint stops only if this condition expression evaluates to true. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " thread-index " , ' x ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeThreadIndex ,
2013-08-23 17:46:38 +00:00
" The breakpoint stops only for the thread whose indeX matches this argument. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " thread-id " , ' t ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeThreadID ,
2013-08-23 17:46:38 +00:00
" The breakpoint stops only for the thread whose TID matches this argument. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " thread-name " , ' T ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeThreadName ,
2013-08-23 17:46:38 +00:00
" The breakpoint stops only for the thread whose thread name matches this argument. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " hardware " , ' H ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2013-11-06 16:48:53 +00:00
" Require the breakpoint to use hardware breakpoints. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " queue-name " , ' q ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeQueueName ,
2013-08-23 17:46:38 +00:00
" The breakpoint stops only for threads in the queue whose name is given by this argument. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_FILE , false , " file " , ' f ' , OptionParser : : eRequiredArgument , NULL , NULL , CommandCompletions : : eSourceFileCompletion , eArgTypeFilename ,
2013-08-23 17:46:38 +00:00
" Specifies the source file in which to set this breakpoint. "
" Note, by default lldb only looks for files that are #included if they use the standard include file extensions. "
" To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy "
" to \" always \" . " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_1 , true , " line " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLineNum ,
2013-08-23 17:46:38 +00:00
" Specifies the line number on which to set this breakpoint. " } ,
// Comment out this option for the moment, as we don't actually use it, but will in the future.
// This way users won't see it, but the infrastructure is left in place.
2013-11-06 16:48:53 +00:00
// { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
2013-08-23 17:46:38 +00:00
// "Set the breakpoint by source location at this particular column."},
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_2 , true , " address " , ' a ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeAddressOrExpression ,
2015-12-30 11:55:28 +00:00
" Set the breakpoint at the specified address. "
" If the address maps uniquely to a particular "
" binary, then the address will be converted to a \" file \" address, so that the breakpoint will track that binary+offset no matter where "
" the binary eventually loads. "
" Alternately, if you also specify the module - with the -s option - then the address will be treated as "
" a file address in that module, and resolved accordingly. Again, this will allow lldb to track that offset on "
" subsequent reloads. The module need not have been loaded at the time you specify this breakpoint, and will "
" get resolved when the module is loaded. " } ,
2013-08-23 17:46:38 +00:00
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_3 , true , " name " , ' n ' , OptionParser : : eRequiredArgument , NULL , NULL , CommandCompletions : : eSymbolCompletion , eArgTypeFunctionName ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_4 , true , " fullname " , ' F ' , OptionParser : : eRequiredArgument , NULL , NULL , CommandCompletions : : eSymbolCompletion , eArgTypeFullName ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
2015-12-30 11:55:28 +00:00
" for Objective C this means a full function prototype with class and selector. "
2013-08-23 17:46:38 +00:00
" Can be repeated multiple times to make one breakpoint for multiple names. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_5 , true , " selector " , ' S ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeSelector ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_6 , true , " method " , ' M ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeMethod ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_7 , true , " func-regex " , ' r ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeRegularExpression ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint by function name, evaluating a regular-expression to find the function name(s). " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_8 , true , " basename " , ' b ' , OptionParser : : eRequiredArgument , NULL , NULL , CommandCompletions : : eSymbolCompletion , eArgTypeFunctionName ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
" Can be repeated multiple times to make one breakpoint for multiple symbols. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_9 , true , " source-pattern-regexp " , ' p ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeRegularExpression ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
" specified with the -f option. The -f option can be specified more than once. "
" If no source files are specified, uses the current \" default source file \" " } ,
2015-07-03 16:57:06 +00:00
{ LLDB_OPT_SET_9 , false , " all-files " , ' A ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
" All files are searched for source pattern matches. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_10 , true , " language-exception " , ' E ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.) " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_10 , false , " on-throw " , ' w ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint on exception throW. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_10 , false , " on-catch " , ' h ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean ,
2013-08-23 17:46:38 +00:00
" Set the breakpoint on exception catcH. " } ,
2015-07-03 16:57:06 +00:00
// Don't add this option till it actually does something useful...
// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
2015-12-30 11:55:28 +00:00
{ LLDB_OPT_EXPR_LANGUAGE , false , " language " , ' L ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLanguage ,
" Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SKIP_PROLOGUE , false , " skip-prologue " , ' K ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean ,
2013-08-23 17:46:38 +00:00
" sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used. " } ,
2015-02-06 21:38:51 +00:00
{ LLDB_OPT_SET_ALL , false , " dummy-breakpoints " , ' D ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
" Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets. " } ,
{ LLDB_OPT_SET_ALL , false , " breakpoint-name " , ' N ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBreakpointName ,
" Adds this to the list of names for this breakopint. " } ,
2015-07-03 16:57:06 +00:00
{ LLDB_OPT_MOVE_TO_NEAREST_CODE , false , " move-to-nearest-code " , ' m ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean ,
" Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used. " } ,
2014-11-25 21:00:58 +00:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 17:46:38 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectBreakpointModify
//-------------------------------------------------------------------------
# pragma mark Modify
class CommandObjectBreakpointModify : public CommandObjectParsed
{
public :
CommandObjectBreakpointModify ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" breakpoint modify " ,
" Modify the options on a breakpoint or set of breakpoints in the executable. "
" If no breakpoint is specified, acts on the last created breakpoint. "
" With the exception of -e, -d and -i, passing an empty argument clears the modification. " ,
NULL ) ,
m_options ( interpreter )
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeBreakpointID , eArgTypeBreakpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointModify ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Options *
GetOptions ( ) override
2013-08-23 17:46:38 +00:00
{
return & m_options ;
}
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
m_ignore_count ( 0 ) ,
m_thread_id ( LLDB_INVALID_THREAD_ID ) ,
m_thread_id_passed ( false ) ,
m_thread_index ( UINT32_MAX ) ,
m_thread_index_passed ( false ) ,
m_thread_name ( ) ,
m_queue_name ( ) ,
m_condition ( ) ,
m_one_shot ( false ) ,
m_enable_passed ( false ) ,
m_enable_value ( false ) ,
m_name_passed ( false ) ,
m_queue_passed ( false ) ,
m_condition_passed ( false ) ,
2015-02-06 21:38:51 +00:00
m_one_shot_passed ( false ) ,
m_use_dummy ( false )
2013-08-23 17:46:38 +00:00
{
}
2015-12-30 11:55:28 +00:00
~ CommandOptions ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 17:46:38 +00:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' c ' :
if ( option_arg ! = NULL )
m_condition . assign ( option_arg ) ;
else
m_condition . clear ( ) ;
m_condition_passed = true ;
break ;
case ' d ' :
m_enable_passed = true ;
m_enable_value = false ;
break ;
2015-02-06 21:38:51 +00:00
case ' D ' :
m_use_dummy = true ;
break ;
2013-08-23 17:46:38 +00:00
case ' e ' :
m_enable_passed = true ;
m_enable_value = true ;
break ;
case ' i ' :
{
2015-02-09 01:44:09 +00:00
m_ignore_count = StringConvert : : ToUInt32 ( option_arg , UINT32_MAX , 0 ) ;
2013-08-23 17:46:38 +00:00
if ( m_ignore_count = = UINT32_MAX )
error . SetErrorStringWithFormat ( " invalid ignore count '%s' " , option_arg ) ;
}
break ;
case ' o ' :
{
bool value , success ;
value = Args : : StringToBoolean ( option_arg , false , & success ) ;
if ( success )
{
m_one_shot_passed = true ;
m_one_shot = value ;
}
else
error . SetErrorStringWithFormat ( " invalid boolean value '%s' passed for -o option " , option_arg ) ;
}
break ;
case ' t ' :
{
if ( option_arg [ 0 ] = = ' \0 ' )
{
m_thread_id = LLDB_INVALID_THREAD_ID ;
m_thread_id_passed = true ;
}
else
{
2015-02-09 01:44:09 +00:00
m_thread_id = StringConvert : : ToUInt64 ( option_arg , LLDB_INVALID_THREAD_ID , 0 ) ;
2013-08-23 17:46:38 +00:00
if ( m_thread_id = = LLDB_INVALID_THREAD_ID )
error . SetErrorStringWithFormat ( " invalid thread id string '%s' " , option_arg ) ;
else
m_thread_id_passed = true ;
}
}
break ;
case ' T ' :
if ( option_arg ! = NULL )
m_thread_name . assign ( option_arg ) ;
else
m_thread_name . clear ( ) ;
m_name_passed = true ;
break ;
case ' q ' :
if ( option_arg ! = NULL )
m_queue_name . assign ( option_arg ) ;
else
m_queue_name . clear ( ) ;
m_queue_passed = true ;
break ;
case ' x ' :
{
if ( option_arg [ 0 ] = = ' \n ' )
{
m_thread_index = UINT32_MAX ;
m_thread_index_passed = true ;
}
else
{
2015-02-09 01:44:09 +00:00
m_thread_index = StringConvert : : ToUInt32 ( option_arg , UINT32_MAX , 0 ) ;
2013-08-23 17:46:38 +00:00
if ( m_thread_id = = UINT32_MAX )
error . SetErrorStringWithFormat ( " invalid thread index string '%s' " , option_arg ) ;
else
m_thread_index_passed = true ;
}
}
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 11:55:28 +00:00
OptionParsingStarting ( ) override
2013-08-23 17:46:38 +00:00
{
m_ignore_count = 0 ;
m_thread_id = LLDB_INVALID_THREAD_ID ;
m_thread_id_passed = false ;
m_thread_index = UINT32_MAX ;
m_thread_index_passed = false ;
m_thread_name . clear ( ) ;
m_queue_name . clear ( ) ;
m_condition . clear ( ) ;
m_one_shot = false ;
m_enable_passed = false ;
m_queue_passed = false ;
m_name_passed = false ;
m_condition_passed = false ;
m_one_shot_passed = false ;
2015-02-06 21:38:51 +00:00
m_use_dummy = false ;
2013-08-23 17:46:38 +00:00
}
const OptionDefinition *
2015-12-30 11:55:28 +00:00
GetDefinitions ( ) override
2013-08-23 17:46:38 +00:00
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
uint32_t m_ignore_count ;
lldb : : tid_t m_thread_id ;
bool m_thread_id_passed ;
uint32_t m_thread_index ;
bool m_thread_index_passed ;
std : : string m_thread_name ;
std : : string m_queue_name ;
std : : string m_condition ;
bool m_one_shot ;
bool m_enable_passed ;
bool m_enable_value ;
bool m_name_passed ;
bool m_queue_passed ;
bool m_condition_passed ;
bool m_one_shot_passed ;
2015-02-06 21:38:51 +00:00
bool m_use_dummy ;
2013-08-23 17:46:38 +00:00
} ;
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 17:46:38 +00:00
{
2015-02-06 21:38:51 +00:00
Target * target = GetSelectedOrDummyTarget ( m_options . m_use_dummy ) ;
2013-08-23 17:46:38 +00:00
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
BreakpointIDList valid_bp_ids ;
2015-02-06 21:38:51 +00:00
CommandObjectMultiwordBreakpoint : : VerifyBreakpointOrLocationIDs ( command , target , result , & valid_bp_ids ) ;
2013-08-23 17:46:38 +00:00
if ( result . Succeeded ( ) )
{
const size_t count = valid_bp_ids . GetSize ( ) ;
for ( size_t i = 0 ; i < count ; + + i )
{
BreakpointID cur_bp_id = valid_bp_ids . GetBreakpointIDAtIndex ( i ) ;
if ( cur_bp_id . GetBreakpointID ( ) ! = LLDB_INVALID_BREAK_ID )
{
Breakpoint * bp = target - > GetBreakpointByID ( cur_bp_id . GetBreakpointID ( ) ) . get ( ) ;
if ( cur_bp_id . GetLocationID ( ) ! = LLDB_INVALID_BREAK_ID )
{
BreakpointLocation * location = bp - > FindLocationByID ( cur_bp_id . GetLocationID ( ) ) . get ( ) ;
if ( location )
{
if ( m_options . m_thread_id_passed )
location - > SetThreadID ( m_options . m_thread_id ) ;
if ( m_options . m_thread_index_passed )
location - > SetThreadIndex ( m_options . m_thread_index ) ;
if ( m_options . m_name_passed )
location - > SetThreadName ( m_options . m_thread_name . c_str ( ) ) ;
if ( m_options . m_queue_passed )
location - > SetQueueName ( m_options . m_queue_name . c_str ( ) ) ;
if ( m_options . m_ignore_count ! = 0 )
location - > SetIgnoreCount ( m_options . m_ignore_count ) ;
if ( m_options . m_enable_passed )
location - > SetEnabled ( m_options . m_enable_value ) ;
if ( m_options . m_condition_passed )
location - > SetCondition ( m_options . m_condition . c_str ( ) ) ;
}
}
else
{
if ( m_options . m_thread_id_passed )
bp - > SetThreadID ( m_options . m_thread_id ) ;
if ( m_options . m_thread_index_passed )
bp - > SetThreadIndex ( m_options . m_thread_index ) ;
if ( m_options . m_name_passed )
bp - > SetThreadName ( m_options . m_thread_name . c_str ( ) ) ;
if ( m_options . m_queue_passed )
bp - > SetQueueName ( m_options . m_queue_name . c_str ( ) ) ;
if ( m_options . m_ignore_count ! = 0 )
bp - > SetIgnoreCount ( m_options . m_ignore_count ) ;
if ( m_options . m_enable_passed )
bp - > SetEnabled ( m_options . m_enable_value ) ;
if ( m_options . m_condition_passed )
bp - > SetCondition ( m_options . m_condition . c_str ( ) ) ;
}
}
}
}
return result . Succeeded ( ) ;
}
private :
CommandOptions m_options ;
} ;
# pragma mark Modify::CommandOptions
OptionDefinition
CommandObjectBreakpointModify : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " ignore-count " , ' i ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeCount , " Set the number of times this breakpoint is skipped before stopping. " } ,
{ LLDB_OPT_SET_ALL , false , " one-shot " , ' o ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBoolean , " The breakpoint is deleted the first time it stop causes a stop. " } ,
{ LLDB_OPT_SET_ALL , false , " thread-index " , ' x ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeThreadIndex , " The breakpoint stops only for the thread whose index matches this argument. " } ,
{ LLDB_OPT_SET_ALL , false , " thread-id " , ' t ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeThreadID , " The breakpoint stops only for the thread whose TID matches this argument. " } ,
{ LLDB_OPT_SET_ALL , false , " thread-name " , ' T ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeThreadName , " The breakpoint stops only for the thread whose thread name matches this argument. " } ,
{ LLDB_OPT_SET_ALL , false , " queue-name " , ' q ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeQueueName , " The breakpoint stops only for threads in the queue whose name is given by this argument. " } ,
{ LLDB_OPT_SET_ALL , false , " condition " , ' c ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeExpression , " The breakpoint stops only if this condition expression evaluates to true. " } ,
{ LLDB_OPT_SET_1 , false , " enable " , ' e ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Enable the breakpoint. " } ,
{ LLDB_OPT_SET_2 , false , " disable " , ' d ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Disable the breakpoint. " } ,
2015-02-06 21:38:51 +00:00
{ LLDB_OPT_SET_ALL , false , " dummy-breakpoints " , ' D ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets. " } ,
2014-11-25 21:00:58 +00:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 17:46:38 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectBreakpointEnable
//-------------------------------------------------------------------------
# pragma mark Enable
class CommandObjectBreakpointEnable : public CommandObjectParsed
{
public :
CommandObjectBreakpointEnable ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" enable " ,
" Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them. " ,
NULL )
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeBreakpointID , eArgTypeBreakpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointEnable ( ) override { }
2013-08-23 17:46:38 +00:00
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 17:46:38 +00:00
{
2015-02-06 21:38:51 +00:00
Target * target = GetSelectedOrDummyTarget ( ) ;
2013-08-23 17:46:38 +00:00
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
const BreakpointList & breakpoints = target - > GetBreakpointList ( ) ;
size_t num_breakpoints = breakpoints . GetSize ( ) ;
if ( num_breakpoints = = 0 )
{
result . AppendError ( " No breakpoints exist to be enabled. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( command . GetArgumentCount ( ) = = 0 )
{
// No breakpoint selected; enable all currently set breakpoints.
target - > EnableAllBreakpoints ( ) ;
2014-11-25 21:00:58 +00:00
result . AppendMessageWithFormat ( " All breakpoints enabled. (% " PRIu64 " breakpoints) \n " , ( uint64_t ) num_breakpoints ) ;
2013-08-23 17:46:38 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
// Particular breakpoint selected; enable that breakpoint.
BreakpointIDList valid_bp_ids ;
2015-02-06 21:38:51 +00:00
CommandObjectMultiwordBreakpoint : : VerifyBreakpointOrLocationIDs ( command , target , result , & valid_bp_ids ) ;
2013-08-23 17:46:38 +00:00
if ( result . Succeeded ( ) )
{
int enable_count = 0 ;
int loc_count = 0 ;
const size_t count = valid_bp_ids . GetSize ( ) ;
for ( size_t i = 0 ; i < count ; + + i )
{
BreakpointID cur_bp_id = valid_bp_ids . GetBreakpointIDAtIndex ( i ) ;
if ( cur_bp_id . GetBreakpointID ( ) ! = LLDB_INVALID_BREAK_ID )
{
Breakpoint * breakpoint = target - > GetBreakpointByID ( cur_bp_id . GetBreakpointID ( ) ) . get ( ) ;
if ( cur_bp_id . GetLocationID ( ) ! = LLDB_INVALID_BREAK_ID )
{
BreakpointLocation * location = breakpoint - > FindLocationByID ( cur_bp_id . GetLocationID ( ) ) . get ( ) ;
if ( location )
{
location - > SetEnabled ( true ) ;
+ + loc_count ;
}
}
else
{
breakpoint - > SetEnabled ( true ) ;
+ + enable_count ;
}
}
}
result . AppendMessageWithFormat ( " %d breakpoints enabled. \n " , enable_count + loc_count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
}
return result . Succeeded ( ) ;
}
} ;
//-------------------------------------------------------------------------
// CommandObjectBreakpointDisable
//-------------------------------------------------------------------------
# pragma mark Disable
class CommandObjectBreakpointDisable : public CommandObjectParsed
{
public :
CommandObjectBreakpointDisable ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" breakpoint disable " ,
2015-09-06 14:32:30 +00:00
" Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints. " ,
2013-08-23 17:46:38 +00:00
NULL )
{
SetHelpLong (
2015-09-06 14:32:30 +00:00
" Disable the specified breakpoint(s) without removing them. \
If none are specified , disable all breakpoints . " R " (
) " " Note : disabling a breakpoint will cause none of its locations to be hit \
regardless of whether they are enabled or disabled . After the sequence : " R " (
( lldb ) break disable 1
( lldb ) break enable 1.1
execution will NOT stop at location 1.1 . To achieve that , type :
( lldb ) break disable 1. *
( lldb ) break enable 1.1
) " " The first command disables all the locations of breakpoint 1 , \
2013-08-23 17:46:38 +00:00
the second re - enables the first location . "
2015-09-06 14:32:30 +00:00
) ;
2013-08-23 17:46:38 +00:00
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeBreakpointID , eArgTypeBreakpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointDisable ( ) override { }
2013-08-23 17:46:38 +00:00
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 17:46:38 +00:00
{
2015-02-06 21:38:51 +00:00
Target * target = GetSelectedOrDummyTarget ( ) ;
2013-08-23 17:46:38 +00:00
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
const BreakpointList & breakpoints = target - > GetBreakpointList ( ) ;
size_t num_breakpoints = breakpoints . GetSize ( ) ;
if ( num_breakpoints = = 0 )
{
result . AppendError ( " No breakpoints exist to be disabled. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( command . GetArgumentCount ( ) = = 0 )
{
// No breakpoint selected; disable all currently set breakpoints.
target - > DisableAllBreakpoints ( ) ;
2014-11-25 21:00:58 +00:00
result . AppendMessageWithFormat ( " All breakpoints disabled. (% " PRIu64 " breakpoints) \n " , ( uint64_t ) num_breakpoints ) ;
2013-08-23 17:46:38 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids ;
2015-02-06 21:38:51 +00:00
CommandObjectMultiwordBreakpoint : : VerifyBreakpointOrLocationIDs ( command , target , result , & valid_bp_ids ) ;
2013-08-23 17:46:38 +00:00
if ( result . Succeeded ( ) )
{
int disable_count = 0 ;
int loc_count = 0 ;
const size_t count = valid_bp_ids . GetSize ( ) ;
for ( size_t i = 0 ; i < count ; + + i )
{
BreakpointID cur_bp_id = valid_bp_ids . GetBreakpointIDAtIndex ( i ) ;
if ( cur_bp_id . GetBreakpointID ( ) ! = LLDB_INVALID_BREAK_ID )
{
Breakpoint * breakpoint = target - > GetBreakpointByID ( cur_bp_id . GetBreakpointID ( ) ) . get ( ) ;
if ( cur_bp_id . GetLocationID ( ) ! = LLDB_INVALID_BREAK_ID )
{
BreakpointLocation * location = breakpoint - > FindLocationByID ( cur_bp_id . GetLocationID ( ) ) . get ( ) ;
if ( location )
{
location - > SetEnabled ( false ) ;
+ + loc_count ;
}
}
else
{
breakpoint - > SetEnabled ( false ) ;
+ + disable_count ;
}
}
}
result . AppendMessageWithFormat ( " %d breakpoints disabled. \n " , disable_count + loc_count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
}
return result . Succeeded ( ) ;
}
} ;
//-------------------------------------------------------------------------
// CommandObjectBreakpointList
//-------------------------------------------------------------------------
# pragma mark List
class CommandObjectBreakpointList : public CommandObjectParsed
{
public :
CommandObjectBreakpointList ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" breakpoint list " ,
" List some or all breakpoints at configurable levels of detail. " ,
NULL ) ,
m_options ( interpreter )
{
CommandArgumentEntry arg ;
CommandArgumentData bp_id_arg ;
// Define the first (and only) variant of this arg.
bp_id_arg . arg_type = eArgTypeBreakpointID ;
bp_id_arg . arg_repetition = eArgRepeatOptional ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( bp_id_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointList ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Options *
GetOptions ( ) override
2013-08-23 17:46:38 +00:00
{
return & m_options ;
}
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
2015-02-06 21:38:51 +00:00
m_level ( lldb : : eDescriptionLevelBrief ) ,
m_use_dummy ( false )
2013-08-23 17:46:38 +00:00
{
}
2015-12-30 11:55:28 +00:00
~ CommandOptions ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 17:46:38 +00:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' b ' :
m_level = lldb : : eDescriptionLevelBrief ;
break ;
2015-02-06 21:38:51 +00:00
case ' D ' :
m_use_dummy = true ;
break ;
2013-08-23 17:46:38 +00:00
case ' f ' :
m_level = lldb : : eDescriptionLevelFull ;
break ;
case ' v ' :
m_level = lldb : : eDescriptionLevelVerbose ;
break ;
case ' i ' :
m_internal = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 11:55:28 +00:00
OptionParsingStarting ( ) override
2013-08-23 17:46:38 +00:00
{
m_level = lldb : : eDescriptionLevelFull ;
m_internal = false ;
2015-02-06 21:38:51 +00:00
m_use_dummy = false ;
2013-08-23 17:46:38 +00:00
}
const OptionDefinition *
2015-12-30 11:55:28 +00:00
GetDefinitions ( ) override
2013-08-23 17:46:38 +00:00
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
lldb : : DescriptionLevel m_level ;
bool m_internal ;
2015-02-06 21:38:51 +00:00
bool m_use_dummy ;
2013-08-23 17:46:38 +00:00
} ;
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 17:46:38 +00:00
{
2015-02-06 21:38:51 +00:00
Target * target = GetSelectedOrDummyTarget ( m_options . m_use_dummy ) ;
2013-08-23 17:46:38 +00:00
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No current target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return true ;
}
const BreakpointList & breakpoints = target - > GetBreakpointList ( m_options . m_internal ) ;
Mutex : : Locker locker ;
target - > GetBreakpointList ( m_options . m_internal ) . GetListMutex ( locker ) ;
size_t num_breakpoints = breakpoints . GetSize ( ) ;
if ( num_breakpoints = = 0 )
{
result . AppendMessage ( " No breakpoints currently set. " ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return true ;
}
Stream & output_stream = result . GetOutputStream ( ) ;
if ( command . GetArgumentCount ( ) = = 0 )
{
// No breakpoint selected; show info about all currently set breakpoints.
result . AppendMessage ( " Current breakpoints: " ) ;
for ( size_t i = 0 ; i < num_breakpoints ; + + i )
{
Breakpoint * breakpoint = breakpoints . GetBreakpointAtIndex ( i ) . get ( ) ;
AddBreakpointDescription ( & output_stream , breakpoint , m_options . m_level ) ;
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
// Particular breakpoints selected; show info about that breakpoint.
BreakpointIDList valid_bp_ids ;
2015-02-06 21:38:51 +00:00
CommandObjectMultiwordBreakpoint : : VerifyBreakpointOrLocationIDs ( command , target , result , & valid_bp_ids ) ;
2013-08-23 17:46:38 +00:00
if ( result . Succeeded ( ) )
{
for ( size_t i = 0 ; i < valid_bp_ids . GetSize ( ) ; + + i )
{
BreakpointID cur_bp_id = valid_bp_ids . GetBreakpointIDAtIndex ( i ) ;
Breakpoint * breakpoint = target - > GetBreakpointByID ( cur_bp_id . GetBreakpointID ( ) ) . get ( ) ;
AddBreakpointDescription ( & output_stream , breakpoint , m_options . m_level ) ;
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( " Invalid breakpoint id. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
return result . Succeeded ( ) ;
}
private :
CommandOptions m_options ;
} ;
# pragma mark List::CommandOptions
OptionDefinition
CommandObjectBreakpointList : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_ALL , false , " internal " , ' i ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2013-08-23 17:46:38 +00:00
" Show debugger internal breakpoints " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_1 , false , " brief " , ' b ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2013-08-23 17:46:38 +00:00
" Give a brief description of the breakpoint (no location info). " } ,
// FIXME: We need to add an "internal" command, and then add this sort of thing to it.
// But I need to see it for now, and don't want to wait.
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_2 , false , " full " , ' f ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2013-08-23 17:46:38 +00:00
" Give a full description of the breakpoint and its locations. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_3 , false , " verbose " , ' v ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2013-08-23 17:46:38 +00:00
" Explain everything we know about the breakpoint (for debugging debugger bugs). " } ,
2015-02-06 21:38:51 +00:00
{ LLDB_OPT_SET_ALL , false , " dummy-breakpoints " , ' D ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
" List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets. " } ,
2014-11-25 21:00:58 +00:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 17:46:38 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectBreakpointClear
//-------------------------------------------------------------------------
# pragma mark Clear
class CommandObjectBreakpointClear : public CommandObjectParsed
{
public :
typedef enum BreakpointClearType
{
eClearTypeInvalid ,
eClearTypeFileAndLine
} BreakpointClearType ;
CommandObjectBreakpointClear ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" breakpoint clear " ,
" Clears a breakpoint or set of breakpoints in the executable. " ,
" breakpoint clear <cmd-options> " ) ,
m_options ( interpreter )
{
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointClear ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Options *
GetOptions ( ) override
2013-08-23 17:46:38 +00:00
{
return & m_options ;
}
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
m_filename ( ) ,
m_line_num ( 0 )
{
}
2015-12-30 11:55:28 +00:00
~ CommandOptions ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2013-08-23 17:46:38 +00:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' f ' :
m_filename . assign ( option_arg ) ;
break ;
case ' l ' :
2015-02-09 01:44:09 +00:00
m_line_num = StringConvert : : ToUInt32 ( option_arg , 0 ) ;
2013-08-23 17:46:38 +00:00
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 11:55:28 +00:00
OptionParsingStarting ( ) override
2013-08-23 17:46:38 +00:00
{
m_filename . clear ( ) ;
m_line_num = 0 ;
}
const OptionDefinition *
2015-12-30 11:55:28 +00:00
GetDefinitions ( ) override
2013-08-23 17:46:38 +00:00
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
std : : string m_filename ;
uint32_t m_line_num ;
} ;
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 17:46:38 +00:00
{
2015-02-06 21:38:51 +00:00
Target * target = GetSelectedOrDummyTarget ( ) ;
2013-08-23 17:46:38 +00:00
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// The following are the various types of breakpoints that could be cleared:
// 1). -f -l (clearing breakpoint by source location)
BreakpointClearType break_type = eClearTypeInvalid ;
if ( m_options . m_line_num ! = 0 )
break_type = eClearTypeFileAndLine ;
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
BreakpointList & breakpoints = target - > GetBreakpointList ( ) ;
size_t num_breakpoints = breakpoints . GetSize ( ) ;
// Early return if there's no breakpoint at all.
if ( num_breakpoints = = 0 )
{
result . AppendError ( " Breakpoint clear: No breakpoint cleared. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return result . Succeeded ( ) ;
}
// Find matching breakpoints and delete them.
// First create a copy of all the IDs.
std : : vector < break_id_t > BreakIDs ;
for ( size_t i = 0 ; i < num_breakpoints ; + + i )
BreakIDs . push_back ( breakpoints . GetBreakpointAtIndex ( i ) . get ( ) - > GetID ( ) ) ;
int num_cleared = 0 ;
StreamString ss ;
switch ( break_type )
{
case eClearTypeFileAndLine : // Breakpoint by source position
{
const ConstString filename ( m_options . m_filename . c_str ( ) ) ;
BreakpointLocationCollection loc_coll ;
for ( size_t i = 0 ; i < num_breakpoints ; + + i )
{
Breakpoint * bp = breakpoints . FindBreakpointByID ( BreakIDs [ i ] ) . get ( ) ;
if ( bp - > GetMatchingFileLine ( filename , m_options . m_line_num , loc_coll ) )
{
// If the collection size is 0, it's a full match and we can just remove the breakpoint.
if ( loc_coll . GetSize ( ) = = 0 )
{
bp - > GetDescription ( & ss , lldb : : eDescriptionLevelBrief ) ;
ss . EOL ( ) ;
target - > RemoveBreakpointByID ( bp - > GetID ( ) ) ;
+ + num_cleared ;
}
}
}
}
break ;
default :
break ;
}
if ( num_cleared > 0 )
{
Stream & output_stream = result . GetOutputStream ( ) ;
output_stream . Printf ( " %d breakpoints cleared: \n " , num_cleared ) ;
output_stream < < ss . GetData ( ) ;
output_stream . EOL ( ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( " Breakpoint clear: No breakpoint cleared. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
private :
CommandOptions m_options ;
} ;
# pragma mark Clear::CommandOptions
OptionDefinition
CommandObjectBreakpointClear : : CommandOptions : : g_option_table [ ] =
{
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_1 , false , " file " , ' f ' , OptionParser : : eRequiredArgument , NULL , NULL , CommandCompletions : : eSourceFileCompletion , eArgTypeFilename ,
2013-08-23 17:46:38 +00:00
" Specify the breakpoint by source location in this particular file. " } ,
2014-11-25 21:00:58 +00:00
{ LLDB_OPT_SET_1 , true , " line " , ' l ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeLineNum ,
2013-08-23 17:46:38 +00:00
" Specify the breakpoint by source location at this particular line. " } ,
2014-11-25 21:00:58 +00:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2013-08-23 17:46:38 +00:00
} ;
//-------------------------------------------------------------------------
// CommandObjectBreakpointDelete
//-------------------------------------------------------------------------
# pragma mark Delete
class CommandObjectBreakpointDelete : public CommandObjectParsed
{
public :
CommandObjectBreakpointDelete ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" breakpoint delete " ,
" Delete the specified breakpoint(s). If no breakpoints are specified, delete them all. " ,
2015-02-06 21:38:51 +00:00
NULL ) ,
m_options ( interpreter )
2013-08-23 17:46:38 +00:00
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeBreakpointID , eArgTypeBreakpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointDelete ( ) override { }
2013-08-23 17:46:38 +00:00
2015-12-30 11:55:28 +00:00
Options *
GetOptions ( ) override
2015-02-06 21:38:51 +00:00
{
return & m_options ;
}
class CommandOptions : public Options
{
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
m_use_dummy ( false ) ,
m_force ( false )
{
}
2015-12-30 11:55:28 +00:00
~ CommandOptions ( ) override { }
2015-02-06 21:38:51 +00:00
2015-12-30 11:55:28 +00:00
Error
SetOptionValue ( uint32_t option_idx , const char * option_arg ) override
2015-02-06 21:38:51 +00:00
{
Error error ;
const int short_option = m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
case ' f ' :
m_force = true ;
break ;
case ' D ' :
m_use_dummy = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
return error ;
}
void
2015-12-30 11:55:28 +00:00
OptionParsingStarting ( ) override
2015-02-06 21:38:51 +00:00
{
m_use_dummy = false ;
m_force = false ;
}
const OptionDefinition *
2015-12-30 11:55:28 +00:00
GetDefinitions ( ) override
2015-02-06 21:38:51 +00:00
{
return g_option_table ;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table [ ] ;
// Instance variables to hold the values for command options.
bool m_use_dummy ;
bool m_force ;
} ;
2013-08-23 17:46:38 +00:00
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2013-08-23 17:46:38 +00:00
{
2015-02-06 21:38:51 +00:00
Target * target = GetSelectedOrDummyTarget ( m_options . m_use_dummy ) ;
2013-08-23 17:46:38 +00:00
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
const BreakpointList & breakpoints = target - > GetBreakpointList ( ) ;
size_t num_breakpoints = breakpoints . GetSize ( ) ;
if ( num_breakpoints = = 0 )
{
result . AppendError ( " No breakpoints exist to be deleted. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( command . GetArgumentCount ( ) = = 0 )
{
2015-02-06 21:38:51 +00:00
if ( ! m_options . m_force & & ! m_interpreter . Confirm ( " About to delete all breakpoints, do you want to do that? " , true ) )
2013-08-23 17:46:38 +00:00
{
result . AppendMessage ( " Operation cancelled... " ) ;
}
else
{
target - > RemoveAllBreakpoints ( ) ;
2014-11-25 21:00:58 +00:00
result . AppendMessageWithFormat ( " All breakpoints removed. (% " PRIu64 " breakpoint%s) \n " , ( uint64_t ) num_breakpoints , num_breakpoints > 1 ? " s " : " " ) ;
2013-08-23 17:46:38 +00:00
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids ;
2015-02-06 21:38:51 +00:00
CommandObjectMultiwordBreakpoint : : VerifyBreakpointOrLocationIDs ( command , target , result , & valid_bp_ids ) ;
2013-08-23 17:46:38 +00:00
if ( result . Succeeded ( ) )
{
int delete_count = 0 ;
int disable_count = 0 ;
const size_t count = valid_bp_ids . GetSize ( ) ;
for ( size_t i = 0 ; i < count ; + + i )
{
BreakpointID cur_bp_id = valid_bp_ids . GetBreakpointIDAtIndex ( i ) ;
if ( cur_bp_id . GetBreakpointID ( ) ! = LLDB_INVALID_BREAK_ID )
{
if ( cur_bp_id . GetLocationID ( ) ! = LLDB_INVALID_BREAK_ID )
{
Breakpoint * breakpoint = target - > GetBreakpointByID ( cur_bp_id . GetBreakpointID ( ) ) . get ( ) ;
BreakpointLocation * location = breakpoint - > FindLocationByID ( cur_bp_id . GetLocationID ( ) ) . get ( ) ;
// It makes no sense to try to delete individual locations, so we disable them instead.
if ( location )
{
location - > SetEnabled ( false ) ;
+ + disable_count ;
}
}
else
{
target - > RemoveBreakpointByID ( cur_bp_id . GetBreakpointID ( ) ) ;
+ + delete_count ;
}
}
}
result . AppendMessageWithFormat ( " %d breakpoints deleted; %d breakpoint locations disabled. \n " ,
delete_count , disable_count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
}
return result . Succeeded ( ) ;
}
2015-02-06 21:38:51 +00:00
private :
CommandOptions m_options ;
} ;
OptionDefinition
CommandObjectBreakpointDelete : : CommandOptions : : g_option_table [ ] =
{
{ LLDB_OPT_SET_1 , false , " force " , ' f ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
" Delete all breakpoints without querying for confirmation. " } ,
{ LLDB_OPT_SET_1 , false , " dummy-breakpoints " , ' D ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
" Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
} ;
//-------------------------------------------------------------------------
// CommandObjectBreakpointName
//-------------------------------------------------------------------------
static OptionDefinition
g_breakpoint_name_options [ ] =
{
{ LLDB_OPT_SET_1 , false , " name " , ' N ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBreakpointName , " Specifies a breakpoint name to use. " } ,
{ LLDB_OPT_SET_2 , false , " breakpoint-id " , ' B ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeBreakpointID , " Specify a breakpoint id to use. " } ,
{ LLDB_OPT_SET_ALL , false , " dummy-breakpoints " , ' D ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
" Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets. " } ,
2013-08-23 17:46:38 +00:00
} ;
2015-02-06 21:38:51 +00:00
class BreakpointNameOptionGroup : public OptionGroup
{
public :
BreakpointNameOptionGroup ( ) :
OptionGroup ( ) ,
m_breakpoint ( LLDB_INVALID_BREAK_ID ) ,
m_use_dummy ( false )
{
}
2015-12-30 11:55:28 +00:00
~ BreakpointNameOptionGroup ( ) override
2015-02-06 21:38:51 +00:00
{
}
2015-12-30 11:55:28 +00:00
uint32_t
GetNumDefinitions ( ) override
2015-02-06 21:38:51 +00:00
{
return sizeof ( g_breakpoint_name_options ) / sizeof ( OptionDefinition ) ;
}
2015-12-30 11:55:28 +00:00
const OptionDefinition *
GetDefinitions ( ) override
2015-02-06 21:38:51 +00:00
{
return g_breakpoint_name_options ;
}
2015-12-30 11:55:28 +00:00
Error
2015-02-06 21:38:51 +00:00
SetOptionValue ( CommandInterpreter & interpreter ,
uint32_t option_idx ,
2015-12-30 11:55:28 +00:00
const char * option_value ) override
2015-02-06 21:38:51 +00:00
{
Error error ;
const int short_option = g_breakpoint_name_options [ option_idx ] . short_option ;
switch ( short_option )
{
case ' N ' :
if ( BreakpointID : : StringIsBreakpointName ( option_value , error ) & & error . Success ( ) )
2015-07-03 16:57:06 +00:00
m_name . SetValueFromString ( option_value ) ;
2015-02-06 21:38:51 +00:00
break ;
case ' B ' :
2015-07-03 16:57:06 +00:00
if ( m_breakpoint . SetValueFromString ( option_value ) . Fail ( ) )
2015-02-06 21:38:51 +00:00
error . SetErrorStringWithFormat ( " unrecognized value \" %s \" for breakpoint " , option_value ) ;
break ;
case ' D ' :
2015-07-03 16:57:06 +00:00
if ( m_use_dummy . SetValueFromString ( option_value ) . Fail ( ) )
2015-02-06 21:38:51 +00:00
error . SetErrorStringWithFormat ( " unrecognized value \" %s \" for use-dummy " , option_value ) ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized short option '%c' " , short_option ) ;
break ;
}
return error ;
}
2015-12-30 11:55:28 +00:00
void
OptionParsingStarting ( CommandInterpreter & interpreter ) override
2015-02-06 21:38:51 +00:00
{
m_name . Clear ( ) ;
m_breakpoint . Clear ( ) ;
m_use_dummy . Clear ( ) ;
m_use_dummy . SetDefaultValue ( false ) ;
}
OptionValueString m_name ;
OptionValueUInt64 m_breakpoint ;
OptionValueBoolean m_use_dummy ;
} ;
class CommandObjectBreakpointNameAdd : public CommandObjectParsed
{
public :
CommandObjectBreakpointNameAdd ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" add " ,
" Add a name to the breakpoints provided. " ,
" breakpoint name add <command-options> <breakpoint-id-list> " ) ,
m_name_options ( ) ,
m_option_group ( interpreter )
{
// Create the first variant for the first (and only) argument for this command.
CommandArgumentEntry arg1 ;
CommandArgumentData id_arg ;
id_arg . arg_type = eArgTypeBreakpointID ;
id_arg . arg_repetition = eArgRepeatOptional ;
arg1 . push_back ( id_arg ) ;
m_arguments . push_back ( arg1 ) ;
m_option_group . Append ( & m_name_options , LLDB_OPT_SET_1 , LLDB_OPT_SET_ALL ) ;
m_option_group . Finalize ( ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointNameAdd ( ) override { }
2015-02-06 21:38:51 +00:00
Options *
2015-12-30 11:55:28 +00:00
GetOptions ( ) override
2015-02-06 21:38:51 +00:00
{
return & m_option_group ;
}
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2015-02-06 21:38:51 +00:00
{
if ( ! m_name_options . m_name . OptionWasSet ( ) )
{
result . SetError ( " No name option provided. " ) ;
return false ;
}
Target * target = GetSelectedOrDummyTarget ( m_name_options . m_use_dummy . GetCurrentValue ( ) ) ;
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
const BreakpointList & breakpoints = target - > GetBreakpointList ( ) ;
size_t num_breakpoints = breakpoints . GetSize ( ) ;
if ( num_breakpoints = = 0 )
{
result . SetError ( " No breakpoints, cannot add names. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids ;
CommandObjectMultiwordBreakpoint : : VerifyBreakpointIDs ( command , target , result , & valid_bp_ids ) ;
if ( result . Succeeded ( ) )
{
if ( valid_bp_ids . GetSize ( ) = = 0 )
{
result . SetError ( " No breakpoints specified, cannot add names. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
size_t num_valid_ids = valid_bp_ids . GetSize ( ) ;
for ( size_t index = 0 ; index < num_valid_ids ; index + + )
{
lldb : : break_id_t bp_id = valid_bp_ids . GetBreakpointIDAtIndex ( index ) . GetBreakpointID ( ) ;
BreakpointSP bp_sp = breakpoints . FindBreakpointByID ( bp_id ) ;
Error error ; // We don't need to check the error here, since the option parser checked it...
bp_sp - > AddName ( m_name_options . m_name . GetCurrentValue ( ) , error ) ;
}
}
return true ;
}
private :
BreakpointNameOptionGroup m_name_options ;
OptionGroupOptions m_option_group ;
} ;
class CommandObjectBreakpointNameDelete : public CommandObjectParsed
{
public :
CommandObjectBreakpointNameDelete ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" delete " ,
" Delete a name from the breakpoints provided. " ,
" breakpoint name delete <command-options> <breakpoint-id-list> " ) ,
m_name_options ( ) ,
m_option_group ( interpreter )
{
// Create the first variant for the first (and only) argument for this command.
CommandArgumentEntry arg1 ;
CommandArgumentData id_arg ;
id_arg . arg_type = eArgTypeBreakpointID ;
id_arg . arg_repetition = eArgRepeatOptional ;
arg1 . push_back ( id_arg ) ;
m_arguments . push_back ( arg1 ) ;
m_option_group . Append ( & m_name_options , LLDB_OPT_SET_1 , LLDB_OPT_SET_ALL ) ;
m_option_group . Finalize ( ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointNameDelete ( ) override { }
2015-02-06 21:38:51 +00:00
Options *
2015-12-30 11:55:28 +00:00
GetOptions ( ) override
2015-02-06 21:38:51 +00:00
{
return & m_option_group ;
}
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2015-02-06 21:38:51 +00:00
{
if ( ! m_name_options . m_name . OptionWasSet ( ) )
{
result . SetError ( " No name option provided. " ) ;
return false ;
}
Target * target = GetSelectedOrDummyTarget ( m_name_options . m_use_dummy . GetCurrentValue ( ) ) ;
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
const BreakpointList & breakpoints = target - > GetBreakpointList ( ) ;
size_t num_breakpoints = breakpoints . GetSize ( ) ;
if ( num_breakpoints = = 0 )
{
result . SetError ( " No breakpoints, cannot delete names. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids ;
CommandObjectMultiwordBreakpoint : : VerifyBreakpointIDs ( command , target , result , & valid_bp_ids ) ;
if ( result . Succeeded ( ) )
{
if ( valid_bp_ids . GetSize ( ) = = 0 )
{
result . SetError ( " No breakpoints specified, cannot delete names. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
size_t num_valid_ids = valid_bp_ids . GetSize ( ) ;
for ( size_t index = 0 ; index < num_valid_ids ; index + + )
{
lldb : : break_id_t bp_id = valid_bp_ids . GetBreakpointIDAtIndex ( index ) . GetBreakpointID ( ) ;
BreakpointSP bp_sp = breakpoints . FindBreakpointByID ( bp_id ) ;
bp_sp - > RemoveName ( m_name_options . m_name . GetCurrentValue ( ) ) ;
}
}
return true ;
}
private :
BreakpointNameOptionGroup m_name_options ;
OptionGroupOptions m_option_group ;
} ;
class CommandObjectBreakpointNameList : public CommandObjectParsed
{
public :
CommandObjectBreakpointNameList ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" list " ,
" List either the names for a breakpoint or the breakpoints for a given name. " ,
" breakpoint name list <command-options> " ) ,
m_name_options ( ) ,
m_option_group ( interpreter )
{
m_option_group . Append ( & m_name_options ) ;
m_option_group . Finalize ( ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointNameList ( ) override { }
2015-02-06 21:38:51 +00:00
Options *
2015-12-30 11:55:28 +00:00
GetOptions ( ) override
2015-02-06 21:38:51 +00:00
{
return & m_option_group ;
}
protected :
2015-12-30 11:55:28 +00:00
bool
DoExecute ( Args & command , CommandReturnObject & result ) override
2015-02-06 21:38:51 +00:00
{
Target * target = GetSelectedOrDummyTarget ( m_name_options . m_use_dummy . GetCurrentValue ( ) ) ;
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or breakpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( m_name_options . m_name . OptionWasSet ( ) )
{
const char * name = m_name_options . m_name . GetCurrentValue ( ) ;
Mutex : : Locker locker ;
target - > GetBreakpointList ( ) . GetListMutex ( locker ) ;
BreakpointList & breakpoints = target - > GetBreakpointList ( ) ;
for ( BreakpointSP bp_sp : breakpoints . Breakpoints ( ) )
{
if ( bp_sp - > MatchesName ( name ) )
{
StreamString s ;
bp_sp - > GetDescription ( & s , eDescriptionLevelBrief ) ;
s . EOL ( ) ;
result . AppendMessage ( s . GetData ( ) ) ;
}
}
}
else if ( m_name_options . m_breakpoint . OptionWasSet ( ) )
{
BreakpointSP bp_sp = target - > GetBreakpointList ( ) . FindBreakpointByID ( m_name_options . m_breakpoint . GetCurrentValue ( ) ) ;
if ( bp_sp )
{
std : : vector < std : : string > names ;
bp_sp - > GetNames ( names ) ;
result . AppendMessage ( " Names: " ) ;
for ( auto name : names )
result . AppendMessageWithFormat ( " %s \n " , name . c_str ( ) ) ;
}
else
{
result . AppendErrorWithFormat ( " Could not find breakpoint % " PRId64 " . \n " ,
m_name_options . m_breakpoint . GetCurrentValue ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
else
{
result . SetError ( " Must specify -N or -B option to list. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
return true ;
}
private :
BreakpointNameOptionGroup m_name_options ;
OptionGroupOptions m_option_group ;
} ;
//-------------------------------------------------------------------------
// CommandObjectMultiwordBreakpoint
//-------------------------------------------------------------------------
class CommandObjectBreakpointName : public CommandObjectMultiword
{
public :
CommandObjectBreakpointName ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" name " ,
" A set of commands to manage name tags for breakpoints " ,
" breakpoint name <command> [<command-options>] " )
{
CommandObjectSP add_command_object ( new CommandObjectBreakpointNameAdd ( interpreter ) ) ;
CommandObjectSP delete_command_object ( new CommandObjectBreakpointNameDelete ( interpreter ) ) ;
CommandObjectSP list_command_object ( new CommandObjectBreakpointNameList ( interpreter ) ) ;
LoadSubCommand ( " add " , add_command_object ) ;
LoadSubCommand ( " delete " , delete_command_object ) ;
LoadSubCommand ( " list " , list_command_object ) ;
}
2015-12-30 11:55:28 +00:00
~ CommandObjectBreakpointName ( ) override
2015-02-06 21:38:51 +00:00
{
}
} ;
2013-08-23 17:46:38 +00:00
//-------------------------------------------------------------------------
// CommandObjectMultiwordBreakpoint
//-------------------------------------------------------------------------
# pragma mark MultiwordBreakpoint
CommandObjectMultiwordBreakpoint : : CommandObjectMultiwordBreakpoint ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" breakpoint " ,
" A set of commands for operating on breakpoints. Also see _regexp-break. " ,
" breakpoint <command> [<command-options>] " )
{
CommandObjectSP list_command_object ( new CommandObjectBreakpointList ( interpreter ) ) ;
CommandObjectSP enable_command_object ( new CommandObjectBreakpointEnable ( interpreter ) ) ;
CommandObjectSP disable_command_object ( new CommandObjectBreakpointDisable ( interpreter ) ) ;
CommandObjectSP clear_command_object ( new CommandObjectBreakpointClear ( interpreter ) ) ;
CommandObjectSP delete_command_object ( new CommandObjectBreakpointDelete ( interpreter ) ) ;
CommandObjectSP set_command_object ( new CommandObjectBreakpointSet ( interpreter ) ) ;
CommandObjectSP command_command_object ( new CommandObjectBreakpointCommand ( interpreter ) ) ;
CommandObjectSP modify_command_object ( new CommandObjectBreakpointModify ( interpreter ) ) ;
2015-02-06 21:38:51 +00:00
CommandObjectSP name_command_object ( new CommandObjectBreakpointName ( interpreter ) ) ;
2013-08-23 17:46:38 +00:00
list_command_object - > SetCommandName ( " breakpoint list " ) ;
enable_command_object - > SetCommandName ( " breakpoint enable " ) ;
disable_command_object - > SetCommandName ( " breakpoint disable " ) ;
clear_command_object - > SetCommandName ( " breakpoint clear " ) ;
delete_command_object - > SetCommandName ( " breakpoint delete " ) ;
set_command_object - > SetCommandName ( " breakpoint set " ) ;
command_command_object - > SetCommandName ( " breakpoint command " ) ;
modify_command_object - > SetCommandName ( " breakpoint modify " ) ;
2015-02-06 21:38:51 +00:00
name_command_object - > SetCommandName ( " breakpoint name " ) ;
2013-08-23 17:46:38 +00:00
LoadSubCommand ( " list " , list_command_object ) ;
LoadSubCommand ( " enable " , enable_command_object ) ;
LoadSubCommand ( " disable " , disable_command_object ) ;
LoadSubCommand ( " clear " , clear_command_object ) ;
LoadSubCommand ( " delete " , delete_command_object ) ;
LoadSubCommand ( " set " , set_command_object ) ;
LoadSubCommand ( " command " , command_command_object ) ;
LoadSubCommand ( " modify " , modify_command_object ) ;
2015-02-06 21:38:51 +00:00
LoadSubCommand ( " name " , name_command_object ) ;
2013-08-23 17:46:38 +00:00
}
CommandObjectMultiwordBreakpoint : : ~ CommandObjectMultiwordBreakpoint ( )
{
}
void
2015-02-06 21:38:51 +00:00
CommandObjectMultiwordBreakpoint : : VerifyIDs ( Args & args ,
Target * target ,
bool allow_locations ,
CommandReturnObject & result ,
BreakpointIDList * valid_ids )
2013-08-23 17:46:38 +00:00
{
// args can be strings representing 1). integers (for breakpoint ids)
// 2). the full breakpoint & location canonical representation
// 3). the word "to" or a hyphen, representing a range (in which case there
// had *better* be an entry both before & after of one of the first two types.
2015-02-06 21:38:51 +00:00
// 4). A breakpoint name
2013-08-23 17:46:38 +00:00
// If args is empty, we will use the last created breakpoint (if there is one.)
Args temp_args ;
if ( args . GetArgumentCount ( ) = = 0 )
{
if ( target - > GetLastCreatedBreakpoint ( ) )
{
valid_ids - > AddBreakpointID ( BreakpointID ( target - > GetLastCreatedBreakpoint ( ) - > GetID ( ) , LLDB_INVALID_BREAK_ID ) ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( " No breakpoint specified and no last created breakpoint. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return ;
}
// Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
// the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
// all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2015-02-06 21:38:51 +00:00
BreakpointIDList : : FindAndReplaceIDRanges ( args , target , allow_locations , result , temp_args ) ;
2013-08-23 17:46:38 +00:00
// NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
valid_ids - > InsertStringArray ( temp_args . GetConstArgumentVector ( ) , temp_args . GetArgumentCount ( ) , result ) ;
// At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
// and put into valid_ids.
if ( result . Succeeded ( ) )
{
// Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
// of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
const size_t count = valid_ids - > GetSize ( ) ;
for ( size_t i = 0 ; i < count ; + + i )
{
BreakpointID cur_bp_id = valid_ids - > GetBreakpointIDAtIndex ( i ) ;
Breakpoint * breakpoint = target - > GetBreakpointByID ( cur_bp_id . GetBreakpointID ( ) ) . get ( ) ;
if ( breakpoint ! = NULL )
{
const size_t num_locations = breakpoint - > GetNumLocations ( ) ;
2014-11-25 21:00:58 +00:00
if ( static_cast < size_t > ( cur_bp_id . GetLocationID ( ) ) > num_locations )
2013-08-23 17:46:38 +00:00
{
StreamString id_str ;
BreakpointID : : GetCanonicalReference ( & id_str ,
cur_bp_id . GetBreakpointID ( ) ,
cur_bp_id . GetLocationID ( ) ) ;
i = valid_ids - > GetSize ( ) + 1 ;
result . AppendErrorWithFormat ( " '%s' is not a currently valid breakpoint/location id. \n " ,
id_str . GetData ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
else
{
i = valid_ids - > GetSize ( ) + 1 ;
result . AppendErrorWithFormat ( " '%d' is not a currently valid breakpoint id. \n " , cur_bp_id . GetBreakpointID ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
}
}