2011-09-23 02:04:58 +08:00
//===-- CommandObjectWatchpoint.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "CommandObjectWatchpoint.h"
2012-08-10 07:09:42 +08:00
# include "CommandObjectWatchpointCommand.h"
2011-09-23 02:04:58 +08:00
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2011-10-14 08:42:25 +08:00
# include "lldb/Breakpoint/Watchpoint.h"
# include "lldb/Breakpoint/WatchpointList.h"
2011-09-23 02:04:58 +08:00
# include "lldb/Core/StreamString.h"
2012-01-31 05:46:17 +08:00
# include "lldb/Core/ValueObject.h"
# include "lldb/Core/ValueObjectVariable.h"
2015-01-16 04:08:35 +08:00
# include "lldb/Host/StringConvert.h"
2011-09-23 02:04:58 +08:00
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandReturnObject.h"
# include "lldb/Interpreter/CommandCompletions.h"
2012-01-31 05:46:17 +08:00
# include "lldb/Symbol/Variable.h"
# include "lldb/Symbol/VariableList.h"
2015-03-04 07:11:11 +08:00
# include "lldb/Target/StackFrame.h"
2012-01-31 05:46:17 +08:00
# include "lldb/Target/Target.h"
2011-09-23 02:04:58 +08:00
2014-03-20 14:08:36 +08:00
# include "llvm/ADT/StringRef.h"
2011-09-23 02:04:58 +08:00
# include <vector>
using namespace lldb ;
using namespace lldb_private ;
static void
2011-10-14 08:42:25 +08:00
AddWatchpointDescription ( Stream * s , Watchpoint * wp , lldb : : DescriptionLevel level )
2011-09-23 02:04:58 +08:00
{
s - > IndentMore ( ) ;
2011-10-14 08:42:25 +08:00
wp - > GetDescription ( s , level ) ;
2011-09-23 02:04:58 +08:00
s - > IndentLess ( ) ;
s - > EOL ( ) ;
}
static bool
CheckTargetForWatchpointOperations ( Target * target , CommandReturnObject & result )
{
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No existing target or watchpoints. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
bool process_is_valid = target - > GetProcessSP ( ) & & target - > GetProcessSP ( ) - > IsAlive ( ) ;
if ( ! process_is_valid )
{
result . AppendError ( " Thre's no process or it is not alive. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Target passes our checks, return true.
return true ;
}
// Equivalent class: {"-", "to", "To", "TO"} of range specifier array.
static const char * RSA [ 4 ] = { " - " , " to " , " To " , " TO " } ;
// Return the index to RSA if found; otherwise -1 is returned.
static int32_t
WithRSAIndex ( llvm : : StringRef & Arg )
{
uint32_t i ;
for ( i = 0 ; i < 4 ; + + i )
if ( Arg . find ( RSA [ i ] ) ! = llvm : : StringRef : : npos )
return i ;
return - 1 ;
}
// Return true if wp_ids is successfully populated with the watch ids.
// False otherwise.
2012-06-20 06:12:58 +08:00
bool
2013-07-02 10:09:46 +08:00
CommandObjectMultiwordWatchpoint : : VerifyWatchpointIDs ( Target * target , Args & args , std : : vector < uint32_t > & wp_ids )
2011-09-23 02:04:58 +08:00
{
// Pre-condition: args.GetArgumentCount() > 0.
2013-07-02 10:09:46 +08:00
if ( args . GetArgumentCount ( ) = = 0 )
{
if ( target = = NULL )
return false ;
WatchpointSP watch_sp = target - > GetLastCreatedWatchpoint ( ) ;
if ( watch_sp )
{
wp_ids . push_back ( watch_sp - > GetID ( ) ) ;
return true ;
}
else
return false ;
}
2011-09-23 02:04:58 +08:00
llvm : : StringRef Minus ( " - " ) ;
std : : vector < llvm : : StringRef > StrRefArgs ;
std : : pair < llvm : : StringRef , llvm : : StringRef > Pair ;
size_t i ;
int32_t idx ;
// Go through the argments and make a canonical form of arg list containing
// only numbers with possible "-" in between.
for ( i = 0 ; i < args . GetArgumentCount ( ) ; + + i ) {
llvm : : StringRef Arg ( args . GetArgumentAtIndex ( i ) ) ;
if ( ( idx = WithRSAIndex ( Arg ) ) = = - 1 ) {
StrRefArgs . push_back ( Arg ) ;
continue ;
}
// The Arg contains the range specifier, split it, then.
Pair = Arg . split ( RSA [ idx ] ) ;
if ( ! Pair . first . empty ( ) )
StrRefArgs . push_back ( Pair . first ) ;
StrRefArgs . push_back ( Minus ) ;
if ( ! Pair . second . empty ( ) )
StrRefArgs . push_back ( Pair . second ) ;
}
// Now process the canonical list and fill in the vector of uint32_t's.
// If there is any error, return false and the client should ignore wp_ids.
uint32_t beg , end , id ;
size_t size = StrRefArgs . size ( ) ;
bool in_range = false ;
for ( i = 0 ; i < size ; + + i ) {
llvm : : StringRef Arg = StrRefArgs [ i ] ;
if ( in_range ) {
// Look for the 'end' of the range. Note StringRef::getAsInteger()
// returns true to signify error while parsing.
if ( Arg . getAsInteger ( 0 , end ) )
return false ;
// Found a range! Now append the elements.
for ( id = beg ; id < = end ; + + id )
wp_ids . push_back ( id ) ;
in_range = false ;
continue ;
}
if ( i < ( size - 1 ) & & StrRefArgs [ i + 1 ] = = Minus ) {
if ( Arg . getAsInteger ( 0 , beg ) )
return false ;
// Turn on the in_range flag, we are looking for end of range next.
+ + i ; in_range = true ;
continue ;
}
// Otherwise, we have a simple ID. Just append it.
if ( Arg . getAsInteger ( 0 , beg ) )
return false ;
wp_ids . push_back ( beg ) ;
}
// It is an error if after the loop, we're still in_range.
if ( in_range )
return false ;
return true ; // Success!
}
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
// CommandObjectWatchpointList
2011-09-23 02:04:58 +08:00
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
# pragma mark List
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointList : public CommandObjectParsed
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectWatchpointList ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" watchpoint list " ,
" List all watchpoints at configurable levels of detail. " ,
NULL ) ,
m_options ( interpreter )
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeWatchpointID , eArgTypeWatchpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointList ( ) { }
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
virtual Options *
GetOptions ( )
{
return & m_options ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
class CommandOptions : public Options
{
public :
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
m_level ( lldb : : eDescriptionLevelBrief ) // Watchpoint List defaults to brief descriptions
{
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandOptions ( ) { }
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
virtual Error
SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
switch ( short_option )
{
case ' b ' :
m_level = lldb : : eDescriptionLevelBrief ;
break ;
case ' f ' :
m_level = lldb : : eDescriptionLevelFull ;
break ;
case ' v ' :
m_level = lldb : : eDescriptionLevelVerbose ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
return error ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
void
OptionParsingStarting ( )
{
2011-09-23 02:04:58 +08:00
m_level = lldb : : eDescriptionLevelFull ;
2012-06-09 05:56:10 +08:00
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
const OptionDefinition *
GetDefinitions ( )
{
return g_option_table ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
// Options table: Required for subclasses of Options.
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
static OptionDefinition g_option_table [ ] ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
// Instance variables to hold the values for command options.
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
lldb : : DescriptionLevel m_level ;
} ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
protected :
virtual bool
DoExecute ( Args & command , CommandReturnObject & result )
2012-05-24 05:09:52 +08:00
{
2012-06-09 05:56:10 +08:00
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
if ( target = = NULL )
{
result . AppendError ( " Invalid target. No current target or watchpoints. " ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return true ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
if ( target - > GetProcessSP ( ) & & target - > GetProcessSP ( ) - > IsAlive ( ) )
{
uint32_t num_supported_hardware_watchpoints ;
Error error = target - > GetProcessSP ( ) - > GetWatchpointSupportInfo ( num_supported_hardware_watchpoints ) ;
if ( error . Success ( ) )
result . AppendMessageWithFormat ( " Number of supported hardware watchpoints: %u \n " ,
num_supported_hardware_watchpoints ) ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
const WatchpointList & watchpoints = target - > GetWatchpointList ( ) ;
Mutex : : Locker locker ;
target - > GetWatchpointList ( ) . GetListMutex ( locker ) ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
size_t num_watchpoints = watchpoints . GetSize ( ) ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
if ( num_watchpoints = = 0 )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
result . AppendMessage ( " No watchpoints currently set. " ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
return true ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
Stream & output_stream = result . GetOutputStream ( ) ;
if ( command . GetArgumentCount ( ) = = 0 )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
// No watchpoint selected; show info about all currently set watchpoints.
result . AppendMessage ( " Current watchpoints: " ) ;
for ( size_t i = 0 ; i < num_watchpoints ; + + i )
{
Watchpoint * wp = watchpoints . GetByIndex ( i ) . get ( ) ;
2011-10-14 08:42:25 +08:00
AddWatchpointDescription ( & output_stream , wp , m_options . m_level ) ;
2012-06-09 05:56:10 +08:00
}
2011-09-23 02:04:58 +08:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
2012-06-09 05:56:10 +08:00
else
{
// Particular watchpoints selected; enable them.
std : : vector < uint32_t > wp_ids ;
2013-07-02 10:09:46 +08:00
if ( ! CommandObjectMultiwordWatchpoint : : VerifyWatchpointIDs ( target , command , wp_ids ) )
2012-06-09 05:56:10 +08:00
{
result . AppendError ( " Invalid watchpoints specification. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
const size_t size = wp_ids . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
{
Watchpoint * wp = watchpoints . FindByID ( wp_ids [ i ] ) . get ( ) ;
if ( wp )
AddWatchpointDescription ( & output_stream , wp , m_options . m_level ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
}
return result . Succeeded ( ) ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
private :
CommandOptions m_options ;
} ;
2011-09-23 02:04:58 +08:00
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
// CommandObjectWatchpointList::Options
2011-09-23 02:04:58 +08:00
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
# pragma mark List::CommandOptions
OptionDefinition
CommandObjectWatchpointList : : CommandOptions : : g_option_table [ ] =
2011-09-23 02:04:58 +08:00
{
2014-07-10 00:31:49 +08:00
{ LLDB_OPT_SET_1 , false , " brief " , ' b ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2012-06-09 05:56:10 +08:00
" Give a brief description of the watchpoint (no location info). " } ,
2011-09-23 02:04:58 +08:00
2014-07-10 00:31:49 +08:00
{ LLDB_OPT_SET_2 , false , " full " , ' f ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2012-06-09 05:56:10 +08:00
" Give a full description of the watchpoint and its locations. " } ,
2011-09-23 02:04:58 +08:00
2014-07-10 00:31:49 +08:00
{ LLDB_OPT_SET_3 , false , " verbose " , ' v ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone ,
2012-06-09 05:56:10 +08:00
" Explain everything we know about the watchpoint (for debugging debugger bugs). " } ,
2011-09-23 02:04:58 +08:00
2014-07-10 00:31:49 +08:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2012-06-09 05:56:10 +08:00
} ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
//-------------------------------------------------------------------------
// CommandObjectWatchpointEnable
//-------------------------------------------------------------------------
# pragma mark Enable
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointEnable : public CommandObjectParsed
{
public :
CommandObjectWatchpointEnable ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" enable " ,
" Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them. " ,
NULL )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeWatchpointID , eArgTypeWatchpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointEnable ( ) { }
protected :
virtual bool
DoExecute ( Args & command ,
CommandReturnObject & result )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
if ( ! CheckTargetForWatchpointOperations ( target , result ) )
return false ;
Mutex : : Locker locker ;
target - > GetWatchpointList ( ) . GetListMutex ( locker ) ;
const WatchpointList & watchpoints = target - > GetWatchpointList ( ) ;
size_t num_watchpoints = watchpoints . GetSize ( ) ;
if ( num_watchpoints = = 0 )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
result . AppendError ( " No watchpoints exist to be enabled. " ) ;
2011-09-23 02:04:58 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-06-09 05:56:10 +08:00
if ( command . GetArgumentCount ( ) = = 0 )
{
// No watchpoint selected; enable all currently set watchpoints.
target - > EnableAllWatchpoints ( ) ;
2014-03-04 03:15:20 +08:00
result . AppendMessageWithFormat ( " All watchpoints enabled. (% " PRIu64 " watchpoints) \n " , ( uint64_t ) num_watchpoints ) ;
2012-06-09 05:56:10 +08:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
// Particular watchpoints selected; enable them.
std : : vector < uint32_t > wp_ids ;
2013-07-02 10:09:46 +08:00
if ( ! CommandObjectMultiwordWatchpoint : : VerifyWatchpointIDs ( target , command , wp_ids ) )
2012-06-09 05:56:10 +08:00
{
result . AppendError ( " Invalid watchpoints specification. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
int count = 0 ;
const size_t size = wp_ids . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
if ( target - > EnableWatchpointByID ( wp_ids [ i ] ) )
+ + count ;
result . AppendMessageWithFormat ( " %d watchpoints enabled. \n " , count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
return result . Succeeded ( ) ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
private :
} ;
2011-09-23 02:04:58 +08:00
//-------------------------------------------------------------------------
// CommandObjectWatchpointDisable
//-------------------------------------------------------------------------
# pragma mark Disable
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointDisable : public CommandObjectParsed
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectWatchpointDisable ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" watchpoint disable " ,
" Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all. " ,
NULL )
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeWatchpointID , eArgTypeWatchpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointDisable ( ) { }
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
protected :
virtual bool
DoExecute ( Args & command , CommandReturnObject & result )
{
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
if ( ! CheckTargetForWatchpointOperations ( target , result ) )
return false ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
Mutex : : Locker locker ;
target - > GetWatchpointList ( ) . GetListMutex ( locker ) ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
const WatchpointList & watchpoints = target - > GetWatchpointList ( ) ;
size_t num_watchpoints = watchpoints . GetSize ( ) ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
if ( num_watchpoints = = 0 )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
result . AppendError ( " No watchpoints exist to be disabled. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
if ( command . GetArgumentCount ( ) = = 0 )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
// No watchpoint selected; disable all currently set watchpoints.
if ( target - > DisableAllWatchpoints ( ) )
{
2014-03-04 03:15:20 +08:00
result . AppendMessageWithFormat ( " All watchpoints disabled. (% " PRIu64 " watchpoints) \n " , ( uint64_t ) num_watchpoints ) ;
2012-06-09 05:56:10 +08:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( " Disable all watchpoints failed \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
else
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
// Particular watchpoints selected; disable them.
std : : vector < uint32_t > wp_ids ;
2013-07-02 10:09:46 +08:00
if ( ! CommandObjectMultiwordWatchpoint : : VerifyWatchpointIDs ( target , command , wp_ids ) )
2012-06-09 05:56:10 +08:00
{
result . AppendError ( " Invalid watchpoints specification. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
int count = 0 ;
const size_t size = wp_ids . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
if ( target - > DisableWatchpointByID ( wp_ids [ i ] ) )
+ + count ;
result . AppendMessageWithFormat ( " %d watchpoints disabled. \n " , count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
return result . Succeeded ( ) ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
} ;
2011-09-23 02:04:58 +08:00
//-------------------------------------------------------------------------
// CommandObjectWatchpointDelete
//-------------------------------------------------------------------------
# pragma mark Delete
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointDelete : public CommandObjectParsed
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectWatchpointDelete ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" watchpoint delete " ,
" Delete the specified watchpoint(s). If no watchpoints are specified, delete them all. " ,
NULL )
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeWatchpointID , eArgTypeWatchpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointDelete ( ) { }
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
protected :
virtual bool
DoExecute ( Args & command , CommandReturnObject & result )
{
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
if ( ! CheckTargetForWatchpointOperations ( target , result ) )
return false ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
Mutex : : Locker locker ;
target - > GetWatchpointList ( ) . GetListMutex ( locker ) ;
const WatchpointList & watchpoints = target - > GetWatchpointList ( ) ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
size_t num_watchpoints = watchpoints . GetSize ( ) ;
2011-09-23 02:04:58 +08:00
2012-06-09 05:56:10 +08:00
if ( num_watchpoints = = 0 )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
result . AppendError ( " No watchpoints exist to be deleted. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
if ( command . GetArgumentCount ( ) = = 0 )
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
if ( ! m_interpreter . Confirm ( " About to delete all watchpoints, do you want to do that? " , true ) )
{
result . AppendMessage ( " Operation cancelled... " ) ;
}
else
{
target - > RemoveAllWatchpoints ( ) ;
2014-03-04 03:15:20 +08:00
result . AppendMessageWithFormat ( " All watchpoints removed. (% " PRIu64 " watchpoints) \n " , ( uint64_t ) num_watchpoints ) ;
2012-06-09 05:56:10 +08:00
}
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
2011-09-23 02:04:58 +08:00
{
2012-06-09 05:56:10 +08:00
// Particular watchpoints selected; delete them.
std : : vector < uint32_t > wp_ids ;
2013-07-02 10:09:46 +08:00
if ( ! CommandObjectMultiwordWatchpoint : : VerifyWatchpointIDs ( target , command , wp_ids ) )
2012-06-09 05:56:10 +08:00
{
result . AppendError ( " Invalid watchpoints specification. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
int count = 0 ;
const size_t size = wp_ids . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
if ( target - > RemoveWatchpointByID ( wp_ids [ i ] ) )
+ + count ;
result . AppendMessageWithFormat ( " %d watchpoints deleted. \n " , count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
return result . Succeeded ( ) ;
2011-09-23 02:04:58 +08:00
}
2012-06-09 05:56:10 +08:00
} ;
2011-09-23 02:04:58 +08:00
2011-10-06 05:35:46 +08:00
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
// CommandObjectWatchpointIgnore
2011-10-06 05:35:46 +08:00
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointIgnore : public CommandObjectParsed
2011-10-06 05:35:46 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectWatchpointIgnore ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" watchpoint ignore " ,
" Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all. " ,
NULL ) ,
m_options ( interpreter )
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeWatchpointID , eArgTypeWatchpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointIgnore ( ) { }
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
virtual Options *
GetOptions ( )
{
return & m_options ;
}
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
class CommandOptions : public Options
2011-10-06 05:35:46 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
m_ignore_count ( 0 )
2011-10-06 05:35:46 +08:00
{
}
2012-06-09 05:56:10 +08:00
virtual
~ CommandOptions ( ) { }
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
virtual Error
SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
switch ( short_option )
{
case ' i ' :
{
2015-01-16 04:08:35 +08:00
m_ignore_count = StringConvert : : ToUInt32 ( option_arg , UINT32_MAX , 0 ) ;
2012-06-09 05:56:10 +08:00
if ( m_ignore_count = = UINT32_MAX )
error . SetErrorStringWithFormat ( " invalid ignore count '%s' " , option_arg ) ;
}
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
return error ;
}
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
void
OptionParsingStarting ( )
{
m_ignore_count = 0 ;
}
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
const OptionDefinition *
GetDefinitions ( )
{
return g_option_table ;
}
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
// Options table: Required for subclasses of Options.
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
static OptionDefinition g_option_table [ ] ;
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
// Instance variables to hold the values for command options.
uint32_t m_ignore_count ;
} ;
protected :
virtual bool
DoExecute ( Args & command ,
CommandReturnObject & result )
2011-10-06 05:35:46 +08:00
{
2012-06-09 05:56:10 +08:00
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
if ( ! CheckTargetForWatchpointOperations ( target , result ) )
return false ;
Mutex : : Locker locker ;
target - > GetWatchpointList ( ) . GetListMutex ( locker ) ;
const WatchpointList & watchpoints = target - > GetWatchpointList ( ) ;
size_t num_watchpoints = watchpoints . GetSize ( ) ;
if ( num_watchpoints = = 0 )
2011-10-06 05:35:46 +08:00
{
2012-06-09 05:56:10 +08:00
result . AppendError ( " No watchpoints exist to be ignored. " ) ;
2011-10-06 05:35:46 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-06-09 05:56:10 +08:00
if ( command . GetArgumentCount ( ) = = 0 )
{
target - > IgnoreAllWatchpoints ( m_options . m_ignore_count ) ;
2014-03-04 03:15:20 +08:00
result . AppendMessageWithFormat ( " All watchpoints ignored. (% " PRIu64 " watchpoints) \n " , ( uint64_t ) num_watchpoints ) ;
2012-06-09 05:56:10 +08:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
// Particular watchpoints selected; ignore them.
std : : vector < uint32_t > wp_ids ;
2013-07-02 10:09:46 +08:00
if ( ! CommandObjectMultiwordWatchpoint : : VerifyWatchpointIDs ( target , command , wp_ids ) )
2012-06-09 05:56:10 +08:00
{
result . AppendError ( " Invalid watchpoints specification. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2011-10-06 05:35:46 +08:00
2012-06-09 05:56:10 +08:00
int count = 0 ;
const size_t size = wp_ids . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
if ( target - > IgnoreWatchpointByID ( wp_ids [ i ] , m_options . m_ignore_count ) )
+ + count ;
result . AppendMessageWithFormat ( " %d watchpoints ignored. \n " , count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
return result . Succeeded ( ) ;
}
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
private :
CommandOptions m_options ;
} ;
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
# pragma mark Ignore::CommandOptions
2011-10-18 02:58:00 +08:00
OptionDefinition
2012-06-09 05:56:10 +08:00
CommandObjectWatchpointIgnore : : CommandOptions : : g_option_table [ ] =
2011-10-18 02:58:00 +08:00
{
2014-07-10 00:31:49 +08:00
{ LLDB_OPT_SET_ALL , true , " ignore-count " , ' i ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeCount , " Set the number of times this watchpoint is skipped before stopping. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2011-10-18 02:58:00 +08:00
} ;
2012-06-09 05:56:10 +08:00
//-------------------------------------------------------------------------
// CommandObjectWatchpointModify
//-------------------------------------------------------------------------
# pragma mark Modify
class CommandObjectWatchpointModify : public CommandObjectParsed
2011-10-18 02:58:00 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectWatchpointModify ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" watchpoint modify " ,
" Modify the options on a watchpoint or set of watchpoints in the executable. "
" If no watchpoint is specified, act on the last created watchpoint. "
" Passing an empty argument clears the modification. " ,
NULL ) ,
m_options ( interpreter )
{
CommandArgumentEntry arg ;
CommandObject : : AddIDsArgumentData ( arg , eArgTypeWatchpointID , eArgTypeWatchpointIDRange ) ;
// Add the entry for the first argument for this command to the object's arguments vector.
m_arguments . push_back ( arg ) ;
}
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointModify ( ) { }
virtual Options *
GetOptions ( )
2011-10-18 02:58:00 +08:00
{
2012-06-09 05:56:10 +08:00
return & m_options ;
2011-10-18 02:58:00 +08:00
}
2012-06-09 05:56:10 +08:00
class CommandOptions : public Options
{
public :
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter ) ,
m_condition ( ) ,
m_condition_passed ( false )
{
}
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandOptions ( ) { }
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
virtual Error
SetOptionValue ( uint32_t option_idx , const char * option_arg )
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = m_getopt_table [ option_idx ] . val ;
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
switch ( short_option )
{
case ' c ' :
if ( option_arg ! = NULL )
m_condition . assign ( option_arg ) ;
else
m_condition . clear ( ) ;
m_condition_passed = true ;
break ;
default :
error . SetErrorStringWithFormat ( " unrecognized option '%c' " , short_option ) ;
break ;
}
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
return error ;
}
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
void
OptionParsingStarting ( )
{
m_condition . clear ( ) ;
m_condition_passed = false ;
}
const OptionDefinition *
GetDefinitions ( )
{
return g_option_table ;
}
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
// Options table: Required for subclasses of Options.
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
static OptionDefinition g_option_table [ ] ;
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
// Instance variables to hold the values for command options.
2011-10-18 02:58:00 +08:00
2012-06-09 05:56:10 +08:00
std : : string m_condition ;
bool m_condition_passed ;
} ;
protected :
virtual bool
DoExecute ( Args & command , CommandReturnObject & result )
2011-10-18 02:58:00 +08:00
{
2012-06-09 05:56:10 +08:00
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
if ( ! CheckTargetForWatchpointOperations ( target , result ) )
return false ;
Mutex : : Locker locker ;
target - > GetWatchpointList ( ) . GetListMutex ( locker ) ;
const WatchpointList & watchpoints = target - > GetWatchpointList ( ) ;
size_t num_watchpoints = watchpoints . GetSize ( ) ;
if ( num_watchpoints = = 0 )
2011-10-18 02:58:00 +08:00
{
2012-06-09 05:56:10 +08:00
result . AppendError ( " No watchpoints exist to be modified. " ) ;
2011-10-18 02:58:00 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-06-09 05:56:10 +08:00
if ( command . GetArgumentCount ( ) = = 0 )
{
WatchpointSP wp_sp = target - > GetLastCreatedWatchpoint ( ) ;
wp_sp - > SetCondition ( m_options . m_condition . c_str ( ) ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
2011-10-18 02:58:00 +08:00
{
2012-06-09 05:56:10 +08:00
// Particular watchpoints selected; set condition on them.
std : : vector < uint32_t > wp_ids ;
2013-07-02 10:09:46 +08:00
if ( ! CommandObjectMultiwordWatchpoint : : VerifyWatchpointIDs ( target , command , wp_ids ) )
2011-10-18 02:58:00 +08:00
{
2012-06-09 05:56:10 +08:00
result . AppendError ( " Invalid watchpoints specification. " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2011-10-18 02:58:00 +08:00
}
2012-06-09 05:56:10 +08:00
int count = 0 ;
const size_t size = wp_ids . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
{
WatchpointSP wp_sp = watchpoints . FindByID ( wp_ids [ i ] ) ;
if ( wp_sp )
{
wp_sp - > SetCondition ( m_options . m_condition . c_str ( ) ) ;
+ + count ;
}
}
result . AppendMessageWithFormat ( " %d watchpoints modified. \n " , count ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
return result . Succeeded ( ) ;
}
2012-02-08 09:13:31 +08:00
2012-06-09 05:56:10 +08:00
private :
CommandOptions m_options ;
} ;
2012-02-08 09:13:31 +08:00
2012-06-09 05:56:10 +08:00
# pragma mark Modify::CommandOptions
OptionDefinition
CommandObjectWatchpointModify : : CommandOptions : : g_option_table [ ] =
2012-02-08 09:13:31 +08:00
{
2014-07-10 00:31:49 +08:00
{ LLDB_OPT_SET_ALL , false , " condition " , ' c ' , OptionParser : : eRequiredArgument , NULL , NULL , 0 , eArgTypeExpression , " The watchpoint stops only if this condition expression evaluates to true. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , NULL , 0 , eArgTypeNone , NULL }
2012-06-09 05:56:10 +08:00
} ;
2012-02-08 09:13:31 +08:00
2012-02-09 06:37:48 +08:00
//-------------------------------------------------------------------------
// CommandObjectWatchpointSetVariable
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
# pragma mark SetVariable
2012-02-08 09:13:31 +08:00
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointSetVariable : public CommandObjectParsed
2012-02-08 09:13:31 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectWatchpointSetVariable ( CommandInterpreter & interpreter ) :
CommandObjectParsed ( interpreter ,
" watchpoint set variable " ,
" Set a watchpoint on a variable. "
" Use the '-w' option to specify the type of watchpoint and "
" the '-x' option to specify the byte size to watch for. "
2012-06-30 03:35:01 +08:00
" If no '-w' option is specified, it defaults to write. "
2012-06-09 05:56:10 +08:00
" If no '-x' option is specified, it defaults to the variable's "
" byte size. "
" Note that there are limited hardware resources for watchpoints. "
" If watchpoint setting fails, consider disable/delete existing ones "
" to free up resources. " ,
NULL ,
2015-05-27 13:04:35 +08:00
eCommandRequiresFrame |
eCommandTryTargetAPILock |
eCommandProcessMustBeLaunched |
eCommandProcessMustBePaused ) ,
2012-06-09 05:56:10 +08:00
m_option_group ( interpreter ) ,
m_option_watchpoint ( )
2012-02-09 06:37:48 +08:00
{
2012-06-09 05:56:10 +08:00
SetHelpLong (
" Examples: \n \
\ n \
2013-11-07 03:56:05 +08:00
watchpoint set variable - w read_write my_global_var \ n \
2012-06-09 05:56:10 +08:00
# Watch my_global_var for read / write access, with the region to watch corresponding to the byte size of the data type.\n");
CommandArgumentEntry arg ;
CommandArgumentData var_name_arg ;
// Define the only variant of this arg.
var_name_arg . arg_type = eArgTypeVarName ;
var_name_arg . arg_repetition = eArgRepeatPlain ;
// Push the variant into the argument entry.
arg . push_back ( var_name_arg ) ;
// Push the data for the only argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
// Absorb the '-w' and '-x' options into our option group.
m_option_group . Append ( & m_option_watchpoint , LLDB_OPT_SET_ALL , LLDB_OPT_SET_1 ) ;
m_option_group . Finalize ( ) ;
2012-02-09 06:37:48 +08:00
}
2012-02-08 09:13:31 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointSetVariable ( ) { }
virtual Options *
GetOptions ( )
2012-02-08 09:13:31 +08:00
{
2012-06-09 05:56:10 +08:00
return & m_option_group ;
2012-02-08 09:13:31 +08:00
}
2012-06-09 05:56:10 +08:00
protected :
2013-01-26 02:06:21 +08:00
static size_t GetVariableCallback ( void * baton ,
const char * name ,
VariableList & variable_list )
2012-09-15 01:20:18 +08:00
{
Target * target = static_cast < Target * > ( baton ) ;
if ( target )
{
return target - > GetImages ( ) . FindGlobalVariables ( ConstString ( name ) ,
true ,
UINT32_MAX ,
variable_list ) ;
}
return 0 ;
}
2012-06-09 05:56:10 +08:00
virtual bool
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2012-02-09 06:37:48 +08:00
{
2012-06-09 05:56:10 +08:00
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
2013-11-04 17:33:30 +08:00
StackFrame * frame = m_exe_ctx . GetFramePtr ( ) ;
2012-02-08 09:13:31 +08:00
2012-06-09 05:56:10 +08:00
// If no argument is present, issue an error message. There's no way to set a watchpoint.
if ( command . GetArgumentCount ( ) < = 0 )
{
result . GetErrorStream ( ) . Printf ( " error: required argument missing; specify your program variable to watch for \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-02-09 06:37:48 +08:00
2012-06-30 03:35:01 +08:00
// If no '-w' is specified, default to '-w write'.
2012-06-09 05:56:10 +08:00
if ( ! m_option_watchpoint . watch_type_specified )
{
2012-06-30 03:35:01 +08:00
m_option_watchpoint . watch_type = OptionGroupWatchpoint : : eWatchWrite ;
2012-06-09 05:56:10 +08:00
}
2012-02-09 06:37:48 +08:00
2012-06-09 05:56:10 +08:00
// We passed the sanity check for the command.
// Proceed to set the watchpoint now.
lldb : : addr_t addr = 0 ;
size_t size = 0 ;
VariableSP var_sp ;
ValueObjectSP valobj_sp ;
Stream & output_stream = result . GetOutputStream ( ) ;
// A simple watch variable gesture allows only one argument.
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( command . GetArgumentCount ( ) ! = 1 )
{
2012-06-09 05:56:10 +08:00
result . GetErrorStream ( ) . Printf ( " error: specify exactly one variable to watch for \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-02-09 06:37:48 +08:00
2012-06-09 05:56:10 +08:00
// Things have checked out ok...
Error error ;
2013-11-04 17:33:30 +08:00
uint32_t expr_path_options = StackFrame : : eExpressionPathOptionCheckPtrVsMember |
StackFrame : : eExpressionPathOptionsAllowDirectIVarAccess ;
2012-06-09 05:56:10 +08:00
valobj_sp = frame - > GetValueForVariableExpressionPath ( command . GetArgumentAtIndex ( 0 ) ,
eNoDynamicValues ,
expr_path_options ,
var_sp ,
error ) ;
2012-09-15 01:20:18 +08:00
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( ! valobj_sp )
{
2012-09-15 01:20:18 +08:00
// Not in the frame; let's check the globals.
VariableList variable_list ;
ValueObjectList valobj_list ;
Error error ( Variable : : GetValuesForVariableExpressionPath ( command . GetArgumentAtIndex ( 0 ) ,
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
m_exe_ctx . GetBestExecutionContextScope ( ) ,
2012-09-15 01:20:18 +08:00
GetVariableCallback ,
target ,
variable_list ,
valobj_list ) ) ;
if ( valobj_list . GetSize ( ) )
valobj_sp = valobj_list . GetValueObjectAtIndex ( 0 ) ;
}
2013-07-12 06:46:58 +08:00
ClangASTType clang_type ;
2012-10-23 15:20:06 +08:00
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( valobj_sp )
{
2012-06-09 05:56:10 +08:00
AddressType addr_type ;
addr = valobj_sp - > GetAddressOf ( false , & addr_type ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( addr_type = = eAddressTypeLoad )
{
2012-06-09 05:56:10 +08:00
// We're in business.
// Find out the size of this variable.
size = m_option_watchpoint . watch_size = = 0 ? valobj_sp - > GetByteSize ( )
: m_option_watchpoint . watch_size ;
}
2013-07-12 06:46:58 +08:00
clang_type = valobj_sp - > GetClangType ( ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
}
else
{
2012-06-09 05:56:10 +08:00
const char * error_cstr = error . AsCString ( NULL ) ;
if ( error_cstr )
result . GetErrorStream ( ) . Printf ( " error: %s \n " , error_cstr ) ;
else
result . GetErrorStream ( ) . Printf ( " error: unable to find any variable expression path that matches '%s' \n " ,
command . GetArgumentAtIndex ( 0 ) ) ;
return false ;
2012-02-09 06:37:48 +08:00
}
2012-06-09 05:56:10 +08:00
// Now it's time to create the watchpoint.
uint32_t watch_type = m_option_watchpoint . watch_type ;
2013-06-19 05:52:48 +08:00
2012-06-09 05:56:10 +08:00
error . Clear ( ) ;
2013-07-12 06:46:58 +08:00
Watchpoint * wp = target - > CreateWatchpoint ( addr , size , & clang_type , watch_type , error ) . get ( ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( wp )
{
2012-08-14 05:09:54 +08:00
wp - > SetWatchSpec ( command . GetArgumentAtIndex ( 0 ) ) ;
wp - > SetWatchVariable ( true ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( var_sp & & var_sp - > GetDeclaration ( ) . GetFile ( ) )
{
2012-06-09 05:56:10 +08:00
StreamString ss ;
// True to show fullpath for declaration file.
var_sp - > GetDeclaration ( ) . DumpStopContext ( & ss , true ) ;
wp - > SetDeclInfo ( ss . GetString ( ) ) ;
}
output_stream . Printf ( " Watchpoint created: " ) ;
wp - > GetDescription ( & output_stream , lldb : : eDescriptionLevelFull ) ;
output_stream . EOL ( ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
}
else
{
2014-03-04 03:15:20 +08:00
result . AppendErrorWithFormat ( " Watchpoint creation failed (addr=0x% " PRIx64 " , size=% " PRIu64 " , variable expression='%s'). \n " ,
addr , ( uint64_t ) size , command . GetArgumentAtIndex ( 0 ) ) ;
2012-06-09 05:56:10 +08:00
if ( error . AsCString ( NULL ) )
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
2012-02-09 06:37:48 +08:00
}
2012-06-09 05:56:10 +08:00
return result . Succeeded ( ) ;
2012-02-09 06:37:48 +08:00
}
2012-06-09 05:56:10 +08:00
private :
OptionGroupOptions m_option_group ;
OptionGroupWatchpoint m_option_watchpoint ;
} ;
2012-02-08 09:13:31 +08:00
2012-01-31 05:46:17 +08:00
//-------------------------------------------------------------------------
2012-02-09 06:37:48 +08:00
// CommandObjectWatchpointSetExpression
2012-01-31 05:46:17 +08:00
//-------------------------------------------------------------------------
# pragma mark Set
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointSetExpression : public CommandObjectRaw
2012-01-31 05:46:17 +08:00
{
2012-06-09 05:56:10 +08:00
public :
CommandObjectWatchpointSetExpression ( CommandInterpreter & interpreter ) :
CommandObjectRaw ( interpreter ,
" watchpoint set expression " ,
" Set a watchpoint on an address by supplying an expression. "
" Use the '-w' option to specify the type of watchpoint and "
" the '-x' option to specify the byte size to watch for. "
2012-06-30 03:35:01 +08:00
" If no '-w' option is specified, it defaults to write. "
2012-06-09 05:56:10 +08:00
" If no '-x' option is specified, it defaults to the target's "
" pointer byte size. "
" Note that there are limited hardware resources for watchpoints. "
" If watchpoint setting fails, consider disable/delete existing ones "
" to free up resources. " ,
NULL ,
2015-05-27 13:04:35 +08:00
eCommandRequiresFrame |
eCommandTryTargetAPILock |
eCommandProcessMustBeLaunched |
eCommandProcessMustBePaused ) ,
2012-06-09 05:56:10 +08:00
m_option_group ( interpreter ) ,
m_option_watchpoint ( )
{
SetHelpLong (
" Examples: \n \
\ n \
watchpoint set expression - w write - x 1 - - foo + 32 \ n \
# Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n");
CommandArgumentEntry arg ;
CommandArgumentData expression_arg ;
// Define the only variant of this arg.
expression_arg . arg_type = eArgTypeExpression ;
expression_arg . arg_repetition = eArgRepeatPlain ;
// Push the only variant into the argument entry.
arg . push_back ( expression_arg ) ;
// Push the data for the only argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
// Absorb the '-w' and '-x' options into our option group.
m_option_group . Append ( & m_option_watchpoint , LLDB_OPT_SET_ALL , LLDB_OPT_SET_1 ) ;
m_option_group . Finalize ( ) ;
}
2012-02-08 09:13:31 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointSetExpression ( ) { }
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
virtual bool
WantsCompletion ( ) { return true ; }
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
virtual Options *
GetOptions ( )
{
return & m_option_group ;
}
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
protected :
virtual bool
DoExecute ( const char * raw_command , CommandReturnObject & result )
{
2013-07-26 07:12:53 +08:00
m_option_group . NotifyOptionParsingStarting ( ) ; // This is a raw command, so notify the option group
2012-06-09 05:56:10 +08:00
Target * target = m_interpreter . GetDebugger ( ) . GetSelectedTarget ( ) . get ( ) ;
2013-11-04 17:33:30 +08:00
StackFrame * frame = m_exe_ctx . GetFramePtr ( ) ;
2012-02-09 06:37:48 +08:00
2012-06-09 05:56:10 +08:00
Args command ( raw_command ) ;
2013-02-14 12:15:23 +08:00
const char * expr = NULL ;
if ( raw_command [ 0 ] = = ' - ' )
{
// We have some options and these options MUST end with --.
const char * end_options = NULL ;
const char * s = raw_command ;
while ( s & & s [ 0 ] )
{
end_options = : : strstr ( s , " -- " ) ;
if ( end_options )
{
end_options + = 2 ; // Get past the "--"
if ( : : isspace ( end_options [ 0 ] ) )
{
expr = end_options ;
while ( : : isspace ( * expr ) )
+ + expr ;
break ;
}
}
s = end_options ;
}
if ( end_options )
{
2015-03-02 20:46:22 +08:00
Args args ( llvm : : StringRef ( raw_command , end_options - raw_command ) ) ;
2013-02-14 12:15:23 +08:00
if ( ! ParseOptions ( args , result ) )
return false ;
Error error ( m_option_group . NotifyOptionParsingFinished ( ) ) ;
if ( error . Fail ( ) )
{
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
}
2012-02-09 06:37:48 +08:00
2013-02-14 12:15:23 +08:00
if ( expr = = NULL )
expr = raw_command ;
2012-02-09 06:37:48 +08:00
2012-06-09 05:56:10 +08:00
// If no argument is present, issue an error message. There's no way to set a watchpoint.
2013-02-14 12:15:23 +08:00
if ( command . GetArgumentCount ( ) = = 0 )
2012-06-09 05:56:10 +08:00
{
2013-06-19 05:52:48 +08:00
result . GetErrorStream ( ) . Printf ( " error: required argument missing; specify an expression to evaulate into the address to watch for \n " ) ;
2012-06-09 05:56:10 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-01-31 05:46:17 +08:00
2012-06-30 03:35:01 +08:00
// If no '-w' is specified, default to '-w write'.
2013-06-19 05:52:48 +08:00
if ( ! m_option_watchpoint . watch_type_specified )
2012-06-09 05:56:10 +08:00
{
2012-06-30 03:35:01 +08:00
m_option_watchpoint . watch_type = OptionGroupWatchpoint : : eWatchWrite ;
2012-06-09 05:56:10 +08:00
}
2012-02-09 06:37:48 +08:00
2012-06-09 05:56:10 +08:00
// We passed the sanity check for the command.
// Proceed to set the watchpoint now.
lldb : : addr_t addr = 0 ;
size_t size = 0 ;
2012-02-08 09:13:31 +08:00
2012-06-09 05:56:10 +08:00
ValueObjectSP valobj_sp ;
// Use expression evaluation to arrive at the address to watch.
2012-10-17 05:41:58 +08:00
EvaluateExpressionOptions options ;
2013-11-07 08:11:47 +08:00
options . SetCoerceToId ( false ) ;
options . SetUnwindOnError ( true ) ;
options . SetKeepInMemory ( false ) ;
options . SetTryAllThreads ( true ) ;
options . SetTimeoutUsec ( 0 ) ;
2012-09-06 04:41:26 +08:00
2014-05-05 10:26:40 +08:00
ExpressionResults expr_result = target - > EvaluateExpression ( expr ,
2012-06-09 05:56:10 +08:00
frame ,
2012-07-17 07:10:35 +08:00
valobj_sp ,
2012-09-06 04:41:26 +08:00
options ) ;
2014-05-05 10:47:44 +08:00
if ( expr_result ! = eExpressionCompleted )
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
{
2012-06-09 05:56:10 +08:00
result . GetErrorStream ( ) . Printf ( " error: expression evaluation of address to watch failed \n " ) ;
2013-02-14 12:15:23 +08:00
result . GetErrorStream ( ) . Printf ( " expression evaluated: %s \n " , expr ) ;
2012-06-09 05:56:10 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
// Get the address to watch.
bool success = false ;
addr = valobj_sp - > GetValueAsUnsigned ( 0 , & success ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( ! success )
{
2012-06-09 05:56:10 +08:00
result . GetErrorStream ( ) . Printf ( " error: expression did not evaluate to an address \n " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2013-06-19 05:52:48 +08:00
if ( m_option_watchpoint . watch_size ! = 0 )
size = m_option_watchpoint . watch_size ;
else
size = target - > GetArchitecture ( ) . GetAddressByteSize ( ) ;
2012-06-09 05:56:10 +08:00
// Now it's time to create the watchpoint.
uint32_t watch_type = m_option_watchpoint . watch_type ;
2012-10-23 15:20:06 +08:00
// Fetch the type from the value object, the type of the watched object is the pointee type
/// of the expression, so convert to that if we found a valid type.
2013-07-12 06:46:58 +08:00
ClangASTType clang_type ( valobj_sp - > GetClangType ( ) ) ;
2012-10-23 15:20:06 +08:00
2012-06-09 05:56:10 +08:00
Error error ;
2013-07-12 06:46:58 +08:00
Watchpoint * wp = target - > CreateWatchpoint ( addr , size , & clang_type , watch_type , error ) . get ( ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
if ( wp )
{
2013-02-14 12:15:23 +08:00
Stream & output_stream = result . GetOutputStream ( ) ;
2012-06-09 05:56:10 +08:00
output_stream . Printf ( " Watchpoint created: " ) ;
wp - > GetDescription ( & output_stream , lldb : : eDescriptionLevelFull ) ;
output_stream . EOL ( ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
}
else
{
2014-03-04 03:15:20 +08:00
result . AppendErrorWithFormat ( " Watchpoint creation failed (addr=0x% " PRIx64 " , size=% " PRIu64 " ). \n " ,
addr , ( uint64_t ) size ) ;
2012-06-09 05:56:10 +08:00
if ( error . AsCString ( NULL ) )
result . AppendError ( error . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
2012-01-31 05:46:17 +08:00
}
2012-06-09 05:56:10 +08:00
private :
OptionGroupOptions m_option_group ;
OptionGroupWatchpoint m_option_watchpoint ;
} ;
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
//-------------------------------------------------------------------------
// CommandObjectWatchpointSet
//-------------------------------------------------------------------------
# pragma mark Set
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
class CommandObjectWatchpointSet : public CommandObjectMultiword
{
public :
2012-02-10 02:44:27 +08:00
2012-06-09 05:56:10 +08:00
CommandObjectWatchpointSet ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" watchpoint set " ,
" A set of commands for setting a watchpoint. " ,
" watchpoint set <subcommand> [<subcommand-options>] " )
2012-02-10 02:44:27 +08:00
{
2012-06-09 05:56:10 +08:00
LoadSubCommand ( " variable " , CommandObjectSP ( new CommandObjectWatchpointSetVariable ( interpreter ) ) ) ;
LoadSubCommand ( " expression " , CommandObjectSP ( new CommandObjectWatchpointSetExpression ( interpreter ) ) ) ;
2012-02-10 02:44:27 +08:00
}
2012-02-09 06:37:48 +08:00
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
virtual
~ CommandObjectWatchpointSet ( ) { }
2012-01-31 05:46:17 +08:00
2012-06-09 05:56:10 +08:00
} ;
//-------------------------------------------------------------------------
// CommandObjectMultiwordWatchpoint
//-------------------------------------------------------------------------
# pragma mark MultiwordWatchpoint
CommandObjectMultiwordWatchpoint : : CommandObjectMultiwordWatchpoint ( CommandInterpreter & interpreter ) :
CommandObjectMultiword ( interpreter ,
" watchpoint " ,
" A set of commands for operating on watchpoints. " ,
" watchpoint <command> [<command-options>] " )
{
CommandObjectSP list_command_object ( new CommandObjectWatchpointList ( interpreter ) ) ;
CommandObjectSP enable_command_object ( new CommandObjectWatchpointEnable ( interpreter ) ) ;
CommandObjectSP disable_command_object ( new CommandObjectWatchpointDisable ( interpreter ) ) ;
CommandObjectSP delete_command_object ( new CommandObjectWatchpointDelete ( interpreter ) ) ;
CommandObjectSP ignore_command_object ( new CommandObjectWatchpointIgnore ( interpreter ) ) ;
2012-08-10 07:09:42 +08:00
CommandObjectSP command_command_object ( new CommandObjectWatchpointCommand ( interpreter ) ) ;
2012-06-09 05:56:10 +08:00
CommandObjectSP modify_command_object ( new CommandObjectWatchpointModify ( interpreter ) ) ;
CommandObjectSP set_command_object ( new CommandObjectWatchpointSet ( interpreter ) ) ;
list_command_object - > SetCommandName ( " watchpoint list " ) ;
enable_command_object - > SetCommandName ( " watchpoint enable " ) ;
disable_command_object - > SetCommandName ( " watchpoint disable " ) ;
delete_command_object - > SetCommandName ( " watchpoint delete " ) ;
ignore_command_object - > SetCommandName ( " watchpoint ignore " ) ;
2012-08-10 07:09:42 +08:00
command_command_object - > SetCommandName ( " watchpoint command " ) ;
2012-06-09 05:56:10 +08:00
modify_command_object - > SetCommandName ( " watchpoint modify " ) ;
set_command_object - > SetCommandName ( " watchpoint set " ) ;
2012-07-17 11:23:13 +08:00
LoadSubCommand ( " list " , list_command_object ) ;
LoadSubCommand ( " enable " , enable_command_object ) ;
LoadSubCommand ( " disable " , disable_command_object ) ;
LoadSubCommand ( " delete " , delete_command_object ) ;
LoadSubCommand ( " ignore " , ignore_command_object ) ;
2012-08-10 07:09:42 +08:00
LoadSubCommand ( " command " , command_command_object ) ;
2012-07-17 11:23:13 +08:00
LoadSubCommand ( " modify " , modify_command_object ) ;
LoadSubCommand ( " set " , set_command_object ) ;
2012-01-31 05:46:17 +08:00
}
2012-06-09 05:56:10 +08:00
CommandObjectMultiwordWatchpoint : : ~ CommandObjectMultiwordWatchpoint ( )
{
}