diff options
author | Greg Clayton <gclayton@apple.com> | 2013-01-09 19:44:40 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-01-09 19:44:40 +0000 |
commit | f9fc609fe7e246f98ba72818af1827a269cf71ee (patch) | |
tree | 676a461898bf2f4feef048d3254f326973b68064 /lldb/source/Commands/CommandObjectProcess.cpp | |
parent | eb9ae768647ee4280e4f25d58180067e1ed3c5ab (diff) | |
download | llvm-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.cpp | 130 |
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(); } }; |