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.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@171990 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index f63e4a8..f4d3c13 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -934,7 +934,10 @@
"If watchpoint setting fails, consider disable/delete existing ones "
"to free up resources.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
@@ -988,18 +991,10 @@
}
virtual bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (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)
- {
- result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
// If no argument is present, issue an error message. There's no way to set a watchpoint.
if (command.GetArgumentCount() <= 0)
@@ -1025,7 +1020,8 @@
Stream &output_stream = result.GetOutputStream();
// A simple watch variable gesture allows only one argument.
- if (command.GetArgumentCount() != 1) {
+ if (command.GetArgumentCount() != 1)
+ {
result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -1041,14 +1037,15 @@
var_sp,
error);
- if (!valobj_sp) {
+ if (!valobj_sp)
+ {
// Not in the frame; let's check the globals.
VariableList variable_list;
ValueObjectList valobj_list;
Error error (Variable::GetValuesForVariableExpressionPath (command.GetArgumentAtIndex(0),
- exe_ctx.GetBestExecutionContextScope(),
+ m_exe_ctx.GetBestExecutionContextScope(),
GetVariableCallback,
target,
variable_list,
@@ -1060,17 +1057,21 @@
ClangASTType type;
- if (valobj_sp) {
+ if (valobj_sp)
+ {
AddressType addr_type;
addr = valobj_sp->GetAddressOf(false, &addr_type);
- if (addr_type == eAddressTypeLoad) {
+ 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;
}
type.SetClangType(valobj_sp->GetClangAST(), valobj_sp->GetClangType());
- } else {
+ }
+ else
+ {
const char *error_cstr = error.AsCString(NULL);
if (error_cstr)
result.GetErrorStream().Printf("error: %s\n", error_cstr);
@@ -1084,10 +1085,12 @@
uint32_t watch_type = m_option_watchpoint.watch_type;
error.Clear();
Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
- if (wp) {
+ if (wp)
+ {
wp->SetWatchSpec(command.GetArgumentAtIndex(0));
wp->SetWatchVariable(true);
- if (var_sp && var_sp->GetDeclaration().GetFile()) {
+ if (var_sp && var_sp->GetDeclaration().GetFile())
+ {
StreamString ss;
// True to show fullpath for declaration file.
var_sp->GetDeclaration().DumpStopContext(&ss, true);
@@ -1097,7 +1100,9 @@
wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
output_stream.EOL();
result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
+ }
+ else
+ {
result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu, variable expression='%s').\n",
addr, size, command.GetArgumentAtIndex(0));
if (error.AsCString(NULL))
@@ -1135,7 +1140,10 @@
"If watchpoint setting fails, consider disable/delete existing ones "
"to free up resources.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
@@ -1182,14 +1190,7 @@
DoExecute (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;
- }
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
Args command(raw_command);
@@ -1247,7 +1248,8 @@
frame,
valobj_sp,
options);
- if (expr_result != eExecutionCompleted) {
+ 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);
@@ -1257,7 +1259,8 @@
// Get the address to watch.
bool success = false;
addr = valobj_sp->GetValueAsUnsigned(0, &success);
- if (!success) {
+ if (!success)
+ {
result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -1276,8 +1279,10 @@
Error error;
Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
- if (wp) {
- if (var_sp && var_sp->GetDeclaration().GetFile()) {
+ if (wp)
+ {
+ if (var_sp && var_sp->GetDeclaration().GetFile())
+ {
StreamString ss;
// True to show fullpath for declaration file.
var_sp->GetDeclaration().DumpStopContext(&ss, true);
@@ -1287,7 +1292,9 @@
wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
output_stream.EOL();
result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
+ }
+ else
+ {
result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu).\n",
addr, size);
if (error.AsCString(NULL))