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/CommandObjectFrame.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/CommandObjectFrame.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectFrame.cpp | 197 |
1 files changed, 91 insertions, 106 deletions
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 6a5c132..f2ff3cf 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -63,7 +63,10 @@ public: "frame info", "List information about the currently selected frame in the current thread.", "frame info", - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) + eFlagRequiresFrame | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ) { } @@ -73,21 +76,10 @@ public: protected: bool - DoExecute (Args& command, - CommandReturnObject &result) + DoExecute (Args& command, CommandReturnObject &result) { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - StackFrame *frame = exe_ctx.GetFramePtr(); - if (frame) - { - frame->DumpUsingSettingsFormat (&result.GetOutputStream()); - result.SetStatus (eReturnStatusSuccessFinishResult); - } - else - { - result.AppendError ("no current frame"); - result.SetStatus (eReturnStatusFailed); - } + m_exe_ctx.GetFrameRef().DumpUsingSettingsFormat (&result.GetOutputStream()); + result.SetStatus (eReturnStatusSuccessFinishResult); return result.Succeeded(); } }; @@ -162,7 +154,10 @@ public: "frame select", "Select a frame by index from within the current thread and make it the current frame.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + eFlagRequiresThread | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ), m_options (interpreter) { CommandArgumentEntry arg; @@ -193,111 +188,104 @@ public: protected: bool - DoExecute (Args& command, - CommandReturnObject &result) + DoExecute (Args& command, CommandReturnObject &result) { - ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); - Thread *thread = exe_ctx.GetThreadPtr(); - if (thread) + // No need to check "thread" for validity as eFlagRequiresThread ensures it is valid + Thread *thread = m_exe_ctx.GetThreadPtr(); + + uint32_t frame_idx = UINT32_MAX; + if (m_options.relative_frame_offset != INT32_MIN) { - uint32_t frame_idx = UINT32_MAX; - if (m_options.relative_frame_offset != INT32_MIN) + // The one and only argument is a signed relative frame index + frame_idx = thread->GetSelectedFrameIndex (); + if (frame_idx == UINT32_MAX) + frame_idx = 0; + + if (m_options.relative_frame_offset < 0) { - // The one and only argument is a signed relative frame index - frame_idx = thread->GetSelectedFrameIndex (); - if (frame_idx == UINT32_MAX) - frame_idx = 0; - - if (m_options.relative_frame_offset < 0) + if (frame_idx >= -m_options.relative_frame_offset) + frame_idx += m_options.relative_frame_offset; + else { - if (frame_idx >= -m_options.relative_frame_offset) - frame_idx += m_options.relative_frame_offset; - else + if (frame_idx == 0) { - if (frame_idx == 0) - { - //If you are already at the bottom of the stack, then just warn and don't reset the frame. - result.AppendError("Already at the bottom of the stack"); - result.SetStatus(eReturnStatusFailed); - return false; - } - else - frame_idx = 0; + //If you are already at the bottom of the stack, then just warn and don't reset the frame. + result.AppendError("Already at the bottom of the stack"); + result.SetStatus(eReturnStatusFailed); + return false; } - } - else if (m_options.relative_frame_offset > 0) - { - // I don't want "up 20" where "20" takes you past the top of the stack to produce - // an error, but rather to just go to the top. So I have to count the stack here... - const uint32_t num_frames = thread->GetStackFrameCount(); - if (num_frames - frame_idx > m_options.relative_frame_offset) - frame_idx += m_options.relative_frame_offset; else - { - if (frame_idx == num_frames - 1) - { - //If we are already at the top of the stack, just warn and don't reset the frame. - result.AppendError("Already at the top of the stack"); - result.SetStatus(eReturnStatusFailed); - return false; - } - else - frame_idx = num_frames - 1; - } + frame_idx = 0; } } - else + else if (m_options.relative_frame_offset > 0) { - if (command.GetArgumentCount() == 1) - { - const char *frame_idx_cstr = command.GetArgumentAtIndex(0); - frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); - } - else if (command.GetArgumentCount() == 0) + // I don't want "up 20" where "20" takes you past the top of the stack to produce + // an error, but rather to just go to the top. So I have to count the stack here... + const uint32_t num_frames = thread->GetStackFrameCount(); + if (num_frames - frame_idx > m_options.relative_frame_offset) + frame_idx += m_options.relative_frame_offset; + else { - frame_idx = thread->GetSelectedFrameIndex (); - if (frame_idx == UINT32_MAX) + if (frame_idx == num_frames - 1) { - frame_idx = 0; + //If we are already at the top of the stack, just warn and don't reset the frame. + result.AppendError("Already at the top of the stack"); + result.SetStatus(eReturnStatusFailed); + return false; } + else + frame_idx = num_frames - 1; } - else + } + } + else + { + if (command.GetArgumentCount() == 1) + { + const char *frame_idx_cstr = command.GetArgumentAtIndex(0); + frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); + } + else if (command.GetArgumentCount() == 0) + { + frame_idx = thread->GetSelectedFrameIndex (); + if (frame_idx == UINT32_MAX) { - result.AppendError ("invalid arguments.\n"); - m_options.GenerateOptionUsage (result.GetErrorStream(), this); + frame_idx = 0; } } + else + { + result.AppendError ("invalid arguments.\n"); + m_options.GenerateOptionUsage (result.GetErrorStream(), this); + } + } - const bool broadcast = true; - bool success = thread->SetSelectedFrameByIndex (frame_idx, broadcast); - if (success) + const bool broadcast = true; + bool success = thread->SetSelectedFrameByIndex (frame_idx, broadcast); + if (success) + { + m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ()); + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (frame) { - exe_ctx.SetFrameSP(thread->GetSelectedFrame ()); - StackFrame *frame = exe_ctx.GetFramePtr(); - if (frame) + bool already_shown = false; + SymbolContext frame_sc(frame->GetSymbolContext(eSymbolContextLineEntry)); + if (m_interpreter.GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0) { - bool already_shown = false; - SymbolContext frame_sc(frame->GetSymbolContext(eSymbolContextLineEntry)); - if (m_interpreter.GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0) - { - already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); - } + already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); + } - bool show_frame_info = true; - bool show_source = !already_shown; - if (frame->GetStatus (result.GetOutputStream(), show_frame_info, show_source)) - { - result.SetStatus (eReturnStatusSuccessFinishResult); - return result.Succeeded(); - } + bool show_frame_info = true; + bool show_source = !already_shown; + if (frame->GetStatus (result.GetOutputStream(), show_frame_info, show_source)) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + return result.Succeeded(); } } - result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx); - } - else - { - result.AppendError ("no current thread"); } + result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx); result.SetStatus (eReturnStatusFailed); return false; } @@ -331,7 +319,10 @@ public: "Children of aggregate variables can be specified such as " "'var->child.x'.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + eFlagRequiresFrame | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused), m_option_group (interpreter), m_option_variable(true), // Include the frame specific options by passing "true" m_option_format (eFormatDefault), @@ -372,14 +363,8 @@ protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - 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 view frame variables."); - result.SetStatus (eReturnStatusFailed); - return false; - } + // No need to check "frame" for validity as eFlagRequiresFrame ensures it is valid + StackFrame *frame = m_exe_ctx.GetFramePtr(); Stream &s = result.GetOutputStream(); |