After discussions with Jim and Greg, modify the 'watchpoint set' command to become a mutiword command

with subcommand 'expression' and 'variable'.  The first subcommand is for supplying an expression to
be evaluated into an address to watch for, while the second is for watching a variable.

'watchpoint set expression' is a raw command, which means that you need to use the "--" option terminator
to end the '-w' or '-x' option processing and to start typing your expression.

Also update several test cases to comply and add a couple of test cases into TestCompletion.py,
in particular, test that 'watchpoint set ex' completes to 'watchpoint set expression ' and that
'watchpoint set var' completes to 'watchpoint set variable '.

llvm-svn: 150109
This commit is contained in:
Johnny Chen 2012-02-08 22:37:48 +00:00
parent 8610a59de1
commit 2ffa754a6f
10 changed files with 350 additions and 244 deletions

View File

@ -57,7 +57,7 @@ namespace lldb_private {
WatchType watch_type;
uint32_t watch_size;
bool watch_variable;
bool watch_type_specified;
private:
DISALLOW_COPY_AND_ASSIGN(OptionGroupWatchpoint);

View File

@ -433,7 +433,7 @@ public:
if (variable_list)
{
// If watching a variable, there are certain restrictions to be followed.
if (m_option_watchpoint.watch_variable)
if (m_option_watchpoint.watch_type_specified)
{
if (command.GetArgumentCount() != 1) {
result.GetErrorStream().Printf("error: specify exactly one variable when using the '-w' option\n");
@ -544,7 +544,7 @@ public:
options,
format);
// Process watchpoint if necessary.
if (m_option_watchpoint.watch_variable)
if (m_option_watchpoint.watch_type_specified)
{
AddressType addr_type;
lldb::addr_t addr = 0;

View File

@ -852,146 +852,86 @@ CommandObjectWatchpointModify::Execute
return result.Succeeded();
}
//-------------------------------------------------------------------------
// CommandObjectWatchpointSet::CommandOptions
//-------------------------------------------------------------------------
#pragma mark Set::CommandOptions
CommandObjectWatchpointSet::CommandOptions::CommandOptions() :
OptionGroup()
{
}
CommandObjectWatchpointSet::CommandOptions::~CommandOptions ()
{
}
OptionDefinition
CommandObjectWatchpointSet::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1, true, "expression", 'e', no_argument, NULL, NULL, eArgTypeNone, "Watch an address with an expression specified at the end."},
{ LLDB_OPT_SET_2, true, "variable", 'v', no_argument, NULL, NULL, eArgTypeNone, "Watch a variable name specified at the end."}
};
uint32_t
CommandObjectWatchpointSet::CommandOptions::GetNumDefinitions ()
{
return sizeof(g_option_table)/sizeof(OptionDefinition);
}
const OptionDefinition*
CommandObjectWatchpointSet::CommandOptions::GetDefinitions ()
{
return g_option_table;
}
Error
CommandObjectWatchpointSet::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_arg)
{
Error error;
char short_option = (char) g_option_table[option_idx].short_option;
switch (short_option)
{
case 'e':
m_do_expression = true;
break;
case 'v':
m_do_variable = true;
break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
}
return error;
}
void
CommandObjectWatchpointSet::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
{
m_do_expression = false;
m_do_variable = false;
}
//-------------------------------------------------------------------------
// CommandObjectWatchpointSet
//-------------------------------------------------------------------------
#pragma mark Set
CommandObjectWatchpointSet::CommandObjectWatchpointSet (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"watchpoint set",
"Set a watchpoint. "
"You can choose to watch a variable in scope with the '-v' option "
"or to watch an address with the '-e' option 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. "
"If no '-w' option is specified, it defaults to read_write. "
"Note that hardware resources for watching are often limited.",
NULL,
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
m_option_group (interpreter),
m_option_watchpoint (),
m_command_options ()
CommandObjectMultiword (interpreter,
"watchpoint set",
"A set of commands for setting a watchpoint.",
"watchpoint set <subcommand> [<subcommand-options>]")
{
SetHelpLong(
"Examples: \n\
\n\
watchpoint set -w read_wriate -v my_global_var \n\
# Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n\
\n\
watchpoint set -w write -x 1 -e foo + 32\n\
# Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n\
# If no '-x' option is specified, byte size defaults to 4.\n");
CommandArgumentEntry arg;
CommandArgumentData var_name_arg, expression_arg;
// Define the first variant of this arg.
expression_arg.arg_type = eArgTypeExpression;
expression_arg.arg_repetition = eArgRepeatPlain;
expression_arg.arg_opt_set_association = LLDB_OPT_SET_1;
// Define the second variant of this arg.
var_name_arg.arg_type = eArgTypeVarName;
var_name_arg.arg_repetition = eArgRepeatPlain;
var_name_arg.arg_opt_set_association = LLDB_OPT_SET_2;
// Push the two variants into the argument entry.
arg.push_back (expression_arg);
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 the '-e' (LLDB_OPT_SET_1) set as
// well as the '-v' (LLDB_OPT_SET_2) set.
m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_1, LLDB_OPT_SET_1|LLDB_OPT_SET_2);
m_option_group.Append (&m_command_options);
m_option_group.Finalize();
LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter)));
LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter)));
}
CommandObjectWatchpointSet::~CommandObjectWatchpointSet ()
{
}
//-------------------------------------------------------------------------
// CommandObjectWatchpointSetVariable
//-------------------------------------------------------------------------
#pragma mark Set
CommandObjectWatchpointSetVariable::CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter) :
CommandObject (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. "
"If no '-w' option is specified, it defaults to read_write. "
"If no '-x' option is specified, it defaults to the variable's "
"byte size. "
"Note that hardware resources for watching are often limited.",
NULL,
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
m_option_group (interpreter),
m_option_watchpoint ()
{
SetHelpLong(
"Examples: \n\
\n\
watchpoint set variable -w read_wriate my_global_var \n\
# 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();
}
CommandObjectWatchpointSetVariable::~CommandObjectWatchpointSetVariable ()
{
}
Options *
CommandObjectWatchpointSet::GetOptions ()
CommandObjectWatchpointSetVariable::GetOptions ()
{
return &m_option_group;
}
bool
CommandObjectWatchpointSet::Execute
CommandObjectWatchpointSetVariable::Execute
(
Args& command,
CommandReturnObject &result
)
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == NULL)
@ -1004,18 +944,14 @@ CommandObjectWatchpointSet::Execute
// 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 ('-v') or an address ('-e') to watch for\n");
result.GetErrorStream().Printf("error: required argument missing; specify your program variable to watch for\n");
result.SetStatus(eReturnStatusFailed);
return false;
}
// It's either '-e' to watch an address with expression' or '-v' to watch a variable.
bool watch_address = m_command_options.m_do_expression;
// If no '-w' is specified, default to '-w read_write'.
if (!m_option_watchpoint.watch_variable)
if (!m_option_watchpoint.watch_type_specified)
{
m_option_watchpoint.watch_variable = true;
m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchReadWrite;
}
@ -1028,70 +964,38 @@ CommandObjectWatchpointSet::Execute
ValueObjectSP valobj_sp;
Stream &output_stream = result.GetOutputStream();
if (watch_address) {
// Use expression evaluation to arrive at the address to watch.
std::string expr_str;
command.GetQuotedCommandString(expr_str);
const bool coerce_to_id = true;
const bool unwind_on_error = true;
const bool keep_in_memory = false;
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
frame,
eExecutionPolicyOnlyWhenNeeded,
coerce_to_id,
unwind_on_error,
keep_in_memory,
eNoDynamicValues,
valobj_sp);
if (expr_result != eExecutionCompleted) {
result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n");
result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str());
result.SetStatus(eReturnStatusFailed);
}
// A simple watch variable gesture allows only one argument.
if (command.GetArgumentCount() != 1) {
result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n");
result.SetStatus(eReturnStatusFailed);
return false;
}
// Get the address to watch.
addr = valobj_sp->GetValueAsUnsigned(0);
if (!addr) {
result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
result.SetStatus(eReturnStatusFailed);
return false;
// Things have checked out ok...
Error error;
uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember;
valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0),
eNoDynamicValues,
expr_path_options,
var_sp,
error);
if (valobj_sp) {
AddressType addr_type;
addr = valobj_sp->GetAddressOf(false, &addr_type);
if (addr_type == eAddressTypeLoad) {
// 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;
}
size = m_option_watchpoint.watch_size == 0 ? 4 /* Could use a better default size? */
: m_option_watchpoint.watch_size;
} else {
// A simple watch variable gesture allows only one argument.
if (command.GetArgumentCount() != 1) {
result.GetErrorStream().Printf("error: specify exactly one variable with the '-v' option\n");
result.SetStatus(eReturnStatusFailed);
return false;
}
// Things have checked out ok...
Error error;
uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember;
valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0),
eNoDynamicValues,
expr_path_options,
var_sp,
error);
if (valobj_sp) {
AddressType addr_type;
addr = valobj_sp->GetAddressOf(false, &addr_type);
if (addr_type == eAddressTypeLoad) {
// 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;
}
} else {
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;
}
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;
}
// Now it's time to create the watchpoint.
@ -1117,3 +1021,184 @@ CommandObjectWatchpointSet::Execute
return result.Succeeded();
}
//-------------------------------------------------------------------------
// CommandObjectWatchpointSetExpression
//-------------------------------------------------------------------------
#pragma mark Set
CommandObjectWatchpointSetExpression::CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter) :
CommandObject (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. "
"If no '-w' option is specified, it defaults to read_write. "
"If no '-x' option is specified, it defaults to the target's "
"pointer byte size. "
"Note that hardware resources for watching are often limited.",
NULL,
eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
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();
}
CommandObjectWatchpointSetExpression::~CommandObjectWatchpointSetExpression ()
{
}
Options *
CommandObjectWatchpointSetExpression::GetOptions ()
{
return &m_option_group;
}
#include "llvm/ADT/StringRef.h"
static inline void StripLeadingSpaces(llvm::StringRef &Str)
{
while (!Str.empty() && isspace(Str[0]))
Str = Str.substr(1);
}
static inline llvm::StringRef StripOptionTerminator(llvm::StringRef &Str, bool with_dash_w, bool with_dash_x)
{
llvm::StringRef ExprStr = Str;
// Get rid of the leading spaces first.
StripLeadingSpaces(ExprStr);
// If there's no '-w' and no '-x', we can just return.
if (!with_dash_w && !with_dash_x)
return ExprStr;
// Otherwise, split on the "--" option terminator string, and return the rest of the string.
ExprStr = ExprStr.split("--").second;
StripLeadingSpaces(ExprStr);
return ExprStr;
}
bool
CommandObjectWatchpointSetExpression::ExecuteRawCommandString
(
const char *raw_command,
CommandReturnObject &result
)
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == NULL)
{
result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint.");
result.SetStatus (eReturnStatusFailed);
return false;
}
Args command(raw_command);
// Process possible options.
if (!ParseOptions (command, result))
return false;
// 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 an expression to evaulate into the addres to watch for\n");
result.SetStatus(eReturnStatusFailed);
return false;
}
bool no_dash_w = !m_option_watchpoint.watch_type_specified;
bool no_dash_x = (m_option_watchpoint.watch_size == 0);
// If no '-w' is specified, default to '-w read_write'.
if (no_dash_w)
{
m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchReadWrite;
}
// 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();
// We will process the raw command string to rid of the '-w', '-x', or '--'
llvm::StringRef raw_expr_str(raw_command);
std::string expr_str = StripOptionTerminator(raw_expr_str, !no_dash_w, !no_dash_x).str();
// Use expression evaluation to arrive at the address to watch.
const bool coerce_to_id = true;
const bool unwind_on_error = true;
const bool keep_in_memory = false;
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
frame,
eExecutionPolicyOnlyWhenNeeded,
coerce_to_id,
unwind_on_error,
keep_in_memory,
eNoDynamicValues,
valobj_sp);
if (expr_result != eExecutionCompleted) {
result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n");
result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str());
result.SetStatus(eReturnStatusFailed);
}
// Get the address to watch.
addr = valobj_sp->GetValueAsUnsigned(0);
if (!addr) {
result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
result.SetStatus(eReturnStatusFailed);
return false;
}
size = no_dash_x ? target->GetArchitecture().GetAddressByteSize()
: m_option_watchpoint.watch_size;
// Now it's time to create the watchpoint.
uint32_t watch_type = m_option_watchpoint.watch_type;
Watchpoint *wp = exe_ctx.GetTargetRef().CreateWatchpoint(addr, size, watch_type).get();
if (wp) {
if (var_sp && var_sp->GetDeclaration().GetFile()) {
StreamString ss;
// True to show fullpath for declaration file.
var_sp->GetDeclaration().DumpStopContext(&ss, true);
wp->SetDeclInfo(ss.GetString());
}
StreamString ss;
output_stream.Printf("Watchpoint created: ");
wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
output_stream.EOL();
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n",
addr, size);
result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
}

View File

@ -247,45 +247,27 @@ private:
// CommandObjectWatchpointSet
//-------------------------------------------------------------------------
class CommandObjectWatchpointSet : public CommandObject
class CommandObjectWatchpointSet : public CommandObjectMultiword
{
public:
class CommandOptions : public OptionGroup
{
public:
CommandOptions ();
virtual
~CommandOptions ();
virtual uint32_t
GetNumDefinitions ();
virtual const OptionDefinition*
GetDefinitions ();
virtual Error
SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_value);
virtual void
OptionParsingStarting (CommandInterpreter &interpreter);
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
bool m_do_expression;
bool m_do_variable;
};
CommandObjectWatchpointSet (CommandInterpreter &interpreter);
virtual
~CommandObjectWatchpointSet ();
};
class CommandObjectWatchpointSetVariable : public CommandObject
{
public:
CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter);
virtual
~CommandObjectWatchpointSetVariable ();
virtual bool
Execute (Args& command,
CommandReturnObject &result);
@ -296,7 +278,39 @@ public:
private:
OptionGroupOptions m_option_group;
OptionGroupWatchpoint m_option_watchpoint;
CommandOptions m_command_options;
};
class CommandObjectWatchpointSetExpression : public CommandObject
{
public:
CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter);
virtual
~CommandObjectWatchpointSetExpression ();
virtual bool
Execute (Args& command,
CommandReturnObject &result)
{ return false; }
virtual bool
WantsRawCommandString() { return true; }
// Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
virtual bool
WantsCompletion() { return true; }
virtual bool
ExecuteRawCommandString (const char *raw_command,
CommandReturnObject &result);
virtual Options *
GetOptions ();
private:
OptionGroupOptions m_option_group;
OptionGroupWatchpoint m_option_watchpoint;
};
} // namespace lldb_private

View File

@ -66,7 +66,7 @@ OptionGroupWatchpoint::SetOptionValue (CommandInterpreter &interpreter,
case 'w':
watch_type = (WatchType) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
if (error.Success())
watch_variable = true;
watch_type_specified = true;
break;
case 'x':
@ -84,7 +84,7 @@ OptionGroupWatchpoint::SetOptionValue (CommandInterpreter &interpreter,
void
OptionGroupWatchpoint::OptionParsingStarting (CommandInterpreter &interpreter)
{
watch_variable = false;
watch_type_specified = false;
watch_type = eWatchInvalid;
watch_size = 0;
}

View File

@ -26,13 +26,17 @@ class CommandLineCompletionTestCase(TestBase):
"""Test that 'frame variable -w ' completes to ['Available completions:', 'read', 'write', 'read_write']."""
self.complete_from_to('frame variable -w ', ['Available completions:', 'read', 'write', 'read_write'])
def test_watchpoint_set_dash_x(self):
"""Test that 'watchpoint set -x' completes to 'watchpoint set -x '."""
self.complete_from_to('watchpoint set -x', 'watchpoint set -x ')
def test_watchpoint_set_ex(self):
"""Test that 'watchpoint set ex' completes to 'watchpoint set expression '."""
self.complete_from_to('watchpoint set ex', 'watchpoint set expression ')
def test_watchpoint_set_dash_w_read_underbar(self):
"""Test that 'watchpoint set -w read_' completes to 'watchpoint set -w read_write'."""
self.complete_from_to('watchpoint set -w read_', 'watchpoint set -w read_write')
def test_watchpoint_set_var(self):
"""Test that 'watchpoint set var' completes to 'watchpoint set variable '."""
self.complete_from_to('watchpoint set var', 'watchpoint set variable ')
def test_watchpoint_set_variable_dash_w_read_underbar(self):
"""Test that 'watchpoint set variable -w read_' completes to 'watchpoint set variable -w read_write'."""
self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write')
def test_help_fi(self):
"""Test that 'help fi' completes to ['Available completions:', 'file', 'finish']."""

View File

@ -75,7 +75,7 @@ class HelloWatchpointTestCase(TestBase):
substrs = ['Watchpoint created', 'size = 4', 'type = w',
'%s:%d' % (self.source, self.decl)])
else:
self.expect("watchpoint set -w write -v global", WATCHPOINT_CREATED,
self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
substrs = ['Watchpoint created', 'size = 4', 'type = w',
'%s:%d' % (self.source, self.decl)])

View File

@ -13,13 +13,13 @@ class WatchLocationUsingWatchpointSetTestCase(TestBase):
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
def test_watchlocation_with_dsym_using_watchpoint_set(self):
"""Test watching a location with 'watchpoint set -w write -x size' option."""
"""Test watching a location with 'watchpoint set expression -w write -x size' option."""
self.buildDsym(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.watchlocation_using_watchpoint_set()
def test_watchlocation_with_dwarf_using_watchpoint_set(self):
"""Test watching a location with 'watchpoint set -w write -x size' option."""
"""Test watching a location with 'watchpoint set expression -w write -x size' option."""
self.buildDwarf(dictionary=self.d)
self.setTearDownCleanup(dictionary=self.d)
self.watchlocation_using_watchpoint_set()
@ -60,7 +60,7 @@ class WatchLocationUsingWatchpointSetTestCase(TestBase):
# with offset as 7.
# The main.cpp, by design, misbehaves by not following the agreed upon
# protocol of only accessing the allowable index range of [0, 6].
self.expect("watchpoint set -w write -x 1 -e g_char_ptr + 7", WATCHPOINT_CREATED,
self.expect("watchpoint set expression -w write -x 1 -- g_char_ptr + 7", WATCHPOINT_CREATED,
substrs = ['Watchpoint created', 'size = 1', 'type = w'])
self.runCmd("expr unsigned val = g_char_ptr[7]; val")
self.expect(self.res.GetOutput().splitlines()[0], exe=False,

View File

@ -49,18 +49,20 @@ class WatchpointSetErrorTestCase(TestBase):
# Try some error conditions:
# No argument is an error.
self.expect("watchpoint set", error=True,
startstr = 'error: invalid combination of options for the given command')
self.runCmd("watchpoint set -v -w read_write", check=False)
# 'watchpoint set' is now a multiword command.
self.expect("watchpoint set",
substrs = ['The following subcommands are supported:',
'expression',
'variable'])
self.runCmd("watchpoint set variable -w read_write", check=False)
# 'watchpoint set' now takes a mandatory '-v' or '-e' option to
# indicate watching for either variable or address.
self.expect("watchpoint set -w write global", error=True,
startstr = 'error: invalid combination of options for the given command')
# 'watchpoint set expression' with '-w' or '-x' specified now needs
# an option terminator and a raw expression after that.
self.expect("watchpoint set expression -w write --", error=True,
startstr = 'error: required argument missing; specify an expression to evaulate into the addres to watch for')
# Wrong size parameter is an error.
self.expect("watchpoint set -x -128", error=True,
self.expect("watchpoint set variable -x -128", error=True,
substrs = ['invalid enumeration value'])

View File

@ -122,11 +122,12 @@ class HelpCommandTestCase(TestBase):
substrs = ['<watchpt-id-list>'])
def test_help_watchpoint_set(self):
"""Test that 'help watchpoint set' prints out <expr> for the '-e' option
and <variable-name> for the '-v' option."""
"""Test that 'help watchpoint set' prints out 'expression' and 'variable'
as the possible subcommands."""
self.expect("help watchpoint set",
patterns = ['watchpoint set -e.*<expr>',
'watchpoint set -v.*<variable-name>'])
substrs = ['The following subcommands are supported:'],
patterns = ['expression +--',
'variable +--'])
if __name__ == '__main__':