aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectProcess.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2013-01-09 19:44:40 +0000
committerGreg Clayton <gclayton@apple.com>2013-01-09 19:44:40 +0000
commitf9fc609fe7e246f98ba72818af1827a269cf71ee (patch)
tree676a461898bf2f4feef048d3254f326973b68064 /lldb/source/Commands/CommandObjectProcess.cpp
parenteb9ae768647ee4280e4f25d58180067e1ed3c5ab (diff)
downloadllvm-f9fc609fe7e246f98ba72818af1827a269cf71ee.zip
llvm-f9fc609fe7e246f98ba72818af1827a269cf71ee.tar.gz
llvm-f9fc609fe7e246f98ba72818af1827a269cf71ee.tar.bz2
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
Diffstat (limited to 'lldb/source/Commands/CommandObjectProcess.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp130
1 files changed, 48 insertions, 82 deletions
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index c1f5edf..64e0c73 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -46,7 +46,8 @@ public:
CommandObjectParsed (interpreter,
"process launch",
"Launch the executable in the debugger.",
- NULL),
+ NULL,
+ eFlagRequiresTarget),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -111,13 +112,6 @@ protected:
Debugger &debugger = m_interpreter.GetDebugger();
Target *target = debugger.GetSelectedTarget().get();
Error error;
-
- if (target == NULL)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
// If our listener is NULL, users aren't allows to launch
char filename[PATH_MAX];
const Module *exe_module = target->GetExecutableModulePointer();
@@ -130,7 +124,7 @@ protected:
}
StateType state = eStateInvalid;
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process)
{
state = process->GetState();
@@ -505,7 +499,7 @@ protected:
// and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop
// ourselves here.
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
StateType state = eStateInvalid;
if (process)
{
@@ -686,7 +680,10 @@ public:
"process continue",
"Continue execution of all threads in the current process.",
"process continue",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_options(interpreter)
{
}
@@ -754,19 +751,10 @@ protected:
};
bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
bool synchronous_execution = m_interpreter.GetSynchronous ();
-
- if (process == NULL)
- {
- result.AppendError ("no process to continue");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
StateType state = process->GetState();
if (state == eStateStopped)
{
@@ -878,6 +866,8 @@ public:
"process detach",
"Detach from the current process being debugged.",
"process detach",
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
eFlagProcessMustBeLaunched)
{
}
@@ -888,17 +878,9 @@ public:
protected:
bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("must have a valid process in order to detach");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
+ Process *process = m_exe_ctx.GetProcessPtr();
result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
Error error (process->Detach());
if (error.Success())
@@ -1008,7 +990,7 @@ protected:
TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
Error error;
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process)
{
if (process->IsAlive())
@@ -1112,7 +1094,7 @@ public:
virtual CommandObject *
GetProxyCommandObject()
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process)
return process->GetPluginCommandObject();
return NULL;
@@ -1134,7 +1116,10 @@ public:
"process load",
"Load a shared library into the current process.",
"process load <filename> [<filename> ...]",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
{
}
@@ -1147,13 +1132,7 @@ protected:
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("must have a valid process in order to load a shared library");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Process *process = m_exe_ctx.GetProcessPtr();
const uint32_t argc = command.GetArgumentCount();
@@ -1194,7 +1173,10 @@ public:
"process unload",
"Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
"process unload <index>",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
{
}
@@ -1207,13 +1189,7 @@ protected:
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("must have a valid process in order to load a shared library");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Process *process = m_exe_ctx.GetProcessPtr();
const uint32_t argc = command.GetArgumentCount();
@@ -1260,7 +1236,8 @@ public:
CommandObjectParsed (interpreter,
"process signal",
"Send a UNIX signal to the current process being debugged.",
- NULL)
+ NULL,
+ eFlagRequiresProcess | eFlagTryTargetAPILock)
{
CommandArgumentEntry arg;
CommandArgumentData signal_arg;
@@ -1285,13 +1262,7 @@ protected:
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("no process to signal");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Process *process = m_exe_ctx.GetProcessPtr();
if (command.GetArgumentCount() == 1)
{
@@ -1348,6 +1319,8 @@ public:
"process interrupt",
"Interrupt the current process being debugged.",
"process interrupt",
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
eFlagProcessMustBeLaunched)
{
}
@@ -1361,7 +1334,7 @@ protected:
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process == NULL)
{
result.AppendError ("no process to halt");
@@ -1411,6 +1384,8 @@ public:
"process kill",
"Terminate the current process being debugged.",
"process kill",
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
eFlagProcessMustBeLaunched)
{
}
@@ -1424,7 +1399,7 @@ protected:
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process == NULL)
{
result.AppendError ("no process to kill");
@@ -1469,7 +1444,7 @@ public:
"process status",
"Show the current status and location of executing process.",
"process status",
- 0)
+ eFlagRequiresProcess | eFlagTryTargetAPILock)
{
}
@@ -1483,27 +1458,18 @@ public:
{
Stream &strm = result.GetOutputStream();
result.SetStatus (eReturnStatusSuccessFinishNoResult);
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- const bool only_threads_with_stop_reason = true;
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 1;
- const uint32_t num_frames_with_source = 1;
- process->GetStatus(strm);
- process->GetThreadStatus (strm,
- only_threads_with_stop_reason,
- start_frame,
- num_frames,
- num_frames_with_source);
-
- }
- else
- {
- result.AppendError ("No process.");
- result.SetStatus (eReturnStatusFailed);
- }
+ // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+ Process *process = m_exe_ctx.GetProcessPtr();
+ const bool only_threads_with_stop_reason = true;
+ const uint32_t start_frame = 0;
+ const uint32_t num_frames = 1;
+ const uint32_t num_frames_with_source = 1;
+ process->GetStatus(strm);
+ process->GetThreadStatus (strm,
+ only_threads_with_stop_reason,
+ start_frame,
+ num_frames,
+ num_frames_with_source);
return result.Succeeded();
}
};