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 | |
parent | eb9ae768647ee4280e4f25d58180067e1ed3c5ab (diff) | |
download | bcm5719-llvm-f9fc609fe7e246f98ba72818af1827a269cf71ee.tar.gz bcm5719-llvm-f9fc609fe7e246f98ba72818af1827a269cf71ee.zip |
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')
-rw-r--r-- | lldb/source/Commands/CommandObjectArgs.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpoint.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectDisassemble.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectFrame.cpp | 197 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectMemory.cpp | 36 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectPlatform.cpp | 13 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectProcess.cpp | 130 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectRegister.cpp | 202 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectSettings.cpp | 33 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectSource.cpp | 20 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 691 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectThread.cpp | 392 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectWatchpoint.cpp | 75 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandObject.cpp | 101 |
15 files changed, 925 insertions, 990 deletions
diff --git a/lldb/source/Commands/CommandObjectArgs.cpp b/lldb/source/Commands/CommandObjectArgs.cpp index 4450aeb915c..891c368ae46 100644 --- a/lldb/source/Commands/CommandObjectArgs.cpp +++ b/lldb/source/Commands/CommandObjectArgs.cpp @@ -104,7 +104,7 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) ConstString target_triple; - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); if (!process) { result.AppendError ("Args found no process."); @@ -130,7 +130,7 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) return false; } - Thread *thread = m_interpreter.GetExecutionContext ().GetThreadPtr(); + Thread *thread = m_exe_ctx.GetThreadPtr(); if (!thread) { diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index 2bd768901eb..831b6935cc4 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -561,7 +561,7 @@ private: // Then use the current stack frame's file. if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) { - StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr(); + StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); if (cur_frame == NULL) { result.AppendError ("No selected frame to use to find the default file."); diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp index ae3ff345444..9f131ac2db2 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -273,7 +273,6 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) if (m_options.show_mixed && m_options.num_lines_context == 0) m_options.num_lines_context = 1; - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); // Always show the PC in the disassembly uint32_t options = Disassembler::eOptionMarkPCAddress; @@ -294,7 +293,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) if (Disassembler::Disassemble (m_interpreter.GetDebugger(), m_options.arch, plugin_name, - exe_ctx, + m_exe_ctx, name, NULL, // Module * m_options.num_instructions, @@ -313,7 +312,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) else { AddressRange range; - StackFrame *frame = exe_ctx.GetFramePtr(); + StackFrame *frame = m_exe_ctx.GetFramePtr(); if (m_options.frame_line) { if (frame == NULL) @@ -414,7 +413,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) if (Disassembler::Disassemble (m_interpreter.GetDebugger(), m_options.arch, plugin_name, - exe_ctx, + m_exe_ctx, range.GetBaseAddress(), m_options.num_instructions, m_options.show_mixed ? m_options.num_lines_context : 0, @@ -460,7 +459,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) if (Disassembler::Disassemble (m_interpreter.GetDebugger(), m_options.arch, plugin_name, - exe_ctx, + m_exe_ctx, range, m_options.num_instructions, m_options.show_mixed ? m_options.num_lines_context : 0, diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index dc534f1e037..39f22fd747c 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -168,7 +168,7 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete "expression", "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.", NULL, - eFlagProcessMustBePaused), + eFlagProcessMustBePaused | eFlagTryTargetAPILock), m_option_group (interpreter), m_format_options (eFormatDefault), m_command_options (), @@ -315,7 +315,7 @@ CommandObjectExpression::EvaluateExpression CommandReturnObject *result ) { - Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); + Target *target = m_exe_ctx.GetTargetPtr(); if (!target) target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get(); @@ -351,7 +351,7 @@ CommandObjectExpression::EvaluateExpression .SetTimeoutUsec(m_command_options.timeout); exe_results = target->EvaluateExpression (expr, - m_interpreter.GetExecutionContext().GetFramePtr(), + m_exe_ctx.GetFramePtr(), result_valobj_sp, options); @@ -360,7 +360,7 @@ CommandObjectExpression::EvaluateExpression uint32_t start_frame = 0; uint32_t num_frames = 1; uint32_t num_frames_with_source = 0; - Thread *thread = m_interpreter.GetExecutionContext().GetThreadPtr(); + Thread *thread = m_exe_ctx.GetThreadPtr(); if (thread) { thread->GetStatus (result->GetOutputStream(), @@ -370,7 +370,7 @@ CommandObjectExpression::EvaluateExpression } else { - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); if (process) { bool only_threads_with_stop_reason = true; diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 6a5c1325e24..f2ff3cfef88 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(); diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index 8369d859303..947fc27a3c0 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -298,7 +298,7 @@ public: "memory read", "Read from the memory of the process being debugged.", NULL, - eFlagProcessMustBePaused), + eFlagRequiresTarget | eFlagProcessMustBePaused), m_option_group (interpreter), m_format_options (eFormatBytesWithASCII, 1, 8), m_memory_options (), @@ -371,17 +371,11 @@ protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - if (target == NULL) - { - result.AppendError("need at least a target to read memory"); - result.SetStatus(eReturnStatusFailed); - return false; - } + // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid + Target *target = m_exe_ctx.GetTargetPtr(); + const size_t argc = command.GetArgumentCount(); - if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2) { result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str()); @@ -496,7 +490,7 @@ protected: } ConstString lookup_type_name(type_str.c_str()); - StackFrame *frame = exe_ctx.GetFramePtr(); + StackFrame *frame = m_exe_ctx.GetFramePtr(); if (frame) { sc = frame->GetSymbolContext (eSymbolContextModule); @@ -603,7 +597,7 @@ protected: } if (argc > 0) - addr = Args::StringToAddress(&exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error); + addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error); if (addr == LLDB_INVALID_ADDRESS) { @@ -615,7 +609,7 @@ protected: if (argc == 2) { - lldb::addr_t end_addr = Args::StringToAddress(&exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0); + lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0); if (end_addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid end address expression."); @@ -742,7 +736,7 @@ protected: } - ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); + ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope(); if (clang_ast_type.GetOpaqueQualType()) { for (uint32_t i = 0; i<item_count; ++i) @@ -922,7 +916,7 @@ public: "memory write", "Write to the memory of the process being debugged.", NULL, - eFlagProcessMustBeLaunched), + eFlagRequiresProcess | eFlagProcessMustBeLaunched), m_option_group (interpreter), m_format_options (eFormatBytes, 1, UINT64_MAX), m_memory_options () @@ -999,14 +993,8 @@ protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Process *process = exe_ctx.GetProcessPtr(); - if (process == NULL) - { - result.AppendError("need a process to read memory"); - result.SetStatus(eReturnStatusFailed); - return false; - } + // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid + Process *process = m_exe_ctx.GetProcessPtr(); const size_t argc = command.GetArgumentCount(); @@ -1034,7 +1022,7 @@ protected: size_t item_byte_size = byte_size_value.GetCurrentValue(); Error error; - lldb::addr_t addr = Args::StringToAddress (&exe_ctx, + lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error); diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index e7b9ab1886c..cd6a9e28258 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -357,11 +357,11 @@ class CommandObjectPlatformProcessLaunch : public CommandObjectParsed { public: CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) : - CommandObjectParsed (interpreter, + CommandObjectParsed (interpreter, "platform process launch", "Launch a new process on a remote platform.", "platform process launch program", - 0), + eFlagRequiresTarget | eFlagTryTargetAPILock), m_options (interpreter) { } @@ -387,14 +387,7 @@ protected: { Error error; const uint32_t argc = args.GetArgumentCount(); - Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); - if (target == NULL) - { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - + Target *target = m_exe_ctx.GetTargetPtr(); Module *exe_module = target->GetExecutableModulePointer(); if (exe_module) { diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index c1f5edff0a3..64e0c73b439 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(); } }; diff --git a/lldb/source/Commands/CommandObjectRegister.cpp b/lldb/source/Commands/CommandObjectRegister.cpp index e3e6f894128..db1c3af1862 100644 --- a/lldb/source/Commands/CommandObjectRegister.cpp +++ b/lldb/source/Commands/CommandObjectRegister.cpp @@ -45,7 +45,10 @@ public: "register read", "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + eFlagRequiresFrame | + eFlagRequiresRegContext | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ), m_option_group (interpreter), m_format_options (eFormatDefault), m_command_options () @@ -165,89 +168,80 @@ protected: DoExecute (Args& command, CommandReturnObject &result) { Stream &strm = result.GetOutputStream(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); + RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); - if (reg_ctx) + const RegisterInfo *reg_info = NULL; + if (command.GetArgumentCount() == 0) { - const RegisterInfo *reg_info = NULL; - if (command.GetArgumentCount() == 0) + uint32_t set_idx; + + uint32_t num_register_sets = 1; + const uint32_t set_array_size = m_command_options.set_indexes.GetSize(); + if (set_array_size > 0) { - uint32_t set_idx; - - uint32_t num_register_sets = 1; - const uint32_t set_array_size = m_command_options.set_indexes.GetSize(); - if (set_array_size > 0) + for (uint32_t i=0; i<set_array_size; ++i) { - for (uint32_t i=0; i<set_array_size; ++i) + set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); + if (set_idx != UINT32_MAX) { - set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); - if (set_idx != UINT32_MAX) - { - if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx)) - { - result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); - result.SetStatus (eReturnStatusFailed); - break; - } - } - else + if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx)) { - result.AppendError ("invalid register set index\n"); + result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); result.SetStatus (eReturnStatusFailed); break; } } - } - else - { - if (m_command_options.dump_all_sets) - num_register_sets = reg_ctx->GetRegisterSetCount(); - - for (set_idx = 0; set_idx < num_register_sets; ++set_idx) + else { - // When dump_all_sets option is set, dump primitive as well as derived registers. - DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); + result.AppendError ("invalid register set index\n"); + result.SetStatus (eReturnStatusFailed); + break; } } } else { if (m_command_options.dump_all_sets) + num_register_sets = reg_ctx->GetRegisterSetCount(); + + for (set_idx = 0; set_idx < num_register_sets; ++set_idx) { - result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); - result.SetStatus (eReturnStatusFailed); - } - else if (m_command_options.set_indexes.GetSize() > 0) - { - result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); - result.SetStatus (eReturnStatusFailed); + // When dump_all_sets option is set, dump primitive as well as derived registers. + DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); } - else + } + } + else + { + if (m_command_options.dump_all_sets) + { + result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); + result.SetStatus (eReturnStatusFailed); + } + else if (m_command_options.set_indexes.GetSize() > 0) + { + result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); + result.SetStatus (eReturnStatusFailed); + } + else + { + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) { - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) - { - reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); + reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); - if (reg_info) - { - if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) - strm.Printf("%-12s = error: unavailable\n", reg_info->name); - } - else - { - result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); - } + if (reg_info) + { + if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info)) + strm.Printf("%-12s = error: unavailable\n", reg_info->name); + } + else + { + result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); } } } } - else - { - result.AppendError ("no current frame"); - result.SetStatus (eReturnStatusFailed); - } return result.Succeeded(); } @@ -366,7 +360,10 @@ public: "register write", "Modify a single register value.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) + eFlagRequiresFrame | + eFlagRequiresRegContext | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused) { CommandArgumentEntry arg1; CommandArgumentEntry arg2; @@ -402,64 +399,55 @@ protected: DoExecute(Args& command, CommandReturnObject &result) { DataExtractor reg_data; - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); + RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); - if (reg_ctx) + if (command.GetArgumentCount() != 2) { - if (command.GetArgumentCount() != 2) - { - result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); - result.SetStatus (eReturnStatusFailed); - } - else - { - const char *reg_name = command.GetArgumentAtIndex(0); - const char *value_str = command.GetArgumentAtIndex(1); - const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); + result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); + result.SetStatus (eReturnStatusFailed); + } + else + { + const char *reg_name = command.GetArgumentAtIndex(0); + const char *value_str = command.GetArgumentAtIndex(1); + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); - if (reg_info) + if (reg_info) + { + RegisterValue reg_value; + + Error error (reg_value.SetValueFromCString (reg_info, value_str)); + if (error.Success()) { - RegisterValue reg_value; - - Error error (reg_value.SetValueFromCString (reg_info, value_str)); - if (error.Success()) - { - if (reg_ctx->WriteRegister (reg_info, reg_value)) - { - // Toss all frames and anything else in the thread - // after a register has been written. - exe_ctx.GetThreadRef().Flush(); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return true; - } - } - if (error.AsCString()) + if (reg_ctx->WriteRegister (reg_info, reg_value)) { - result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", - reg_name, - value_str, - error.AsCString()); + // Toss all frames and anything else in the thread + // after a register has been written. + m_exe_ctx.GetThreadRef().Flush(); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + return true; } - else - { - result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", - reg_name, - value_str); - } - result.SetStatus (eReturnStatusFailed); + } + if (error.AsCString()) + { + result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", + reg_name, + value_str, + error.AsCString()); } else { - result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); - result.SetStatus (eReturnStatusFailed); + result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", + reg_name, + value_str); } + result.SetStatus (eReturnStatusFailed); + } + else + { + result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); + result.SetStatus (eReturnStatusFailed); } - } - else - { - result.AppendError ("no current frame"); - result.SetStatus (eReturnStatusFailed); } return result.Succeeded(); } diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp index 6a6e8a63627..c7502d14501 100644 --- a/lldb/source/Commands/CommandObjectSettings.cpp +++ b/lldb/source/Commands/CommandObjectSettings.cpp @@ -202,12 +202,10 @@ insert-before or insert-after.\n"); } else { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - // Complete setting value const char *setting_var_name = input.GetArgumentAtIndex(setting_var_idx); Error error; - lldb::OptionValueSP value_sp (m_interpreter.GetDebugger().GetPropertyValue(&exe_ctx, setting_var_name, false, error)); + lldb::OptionValueSP value_sp (m_interpreter.GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, false, error)); if (value_sp) { value_sp->AutoComplete (m_interpreter, @@ -256,7 +254,6 @@ protected: StripLeadingSpaces(var_value_str); std::string var_value_string = var_value_str.str(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); Error error; if (m_options.m_global) { @@ -268,7 +265,7 @@ protected: if (error.Success()) { - error = m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx, + error = m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx, eVarSetOperationAssign, var_name, var_value_string.c_str()); @@ -357,7 +354,6 @@ protected: virtual bool DoExecute (Args& args, CommandReturnObject &result) { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); result.SetStatus (eReturnStatusSuccessFinishResult); const size_t argc = args.GetArgumentCount (); @@ -367,7 +363,7 @@ protected: { const char *property_path = args.GetArgumentAtIndex (i); - Error error(m_interpreter.GetDebugger().DumpPropertyValue (&exe_ctx, result.GetOutputStream(), property_path, OptionValue::eDumpGroupValue)); + Error error(m_interpreter.GetDebugger().DumpPropertyValue (&m_exe_ctx, result.GetOutputStream(), property_path, OptionValue::eDumpGroupValue)); if (error.Success()) { result.GetOutputStream().EOL(); @@ -381,7 +377,7 @@ protected: } else { - m_interpreter.GetDebugger().DumpAllPropertyValues (& exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue); + m_interpreter.GetDebugger().DumpAllPropertyValues (&m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue); } return result.Succeeded(); @@ -450,7 +446,6 @@ protected: virtual bool DoExecute (Args& args, CommandReturnObject &result) { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); result.SetStatus (eReturnStatusSuccessFinishResult); const bool will_modify = false; @@ -463,7 +458,7 @@ protected: { const char *property_path = args.GetArgumentAtIndex (i); - const Property *property = m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath (&exe_ctx, will_modify, property_path); + const Property *property = m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath (&m_exe_ctx, will_modify, property_path); if (property) { @@ -592,8 +587,7 @@ protected: StripLeadingSpaces(var_value_str); std::string var_value_string = var_value_str.str(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Error error (m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx, + Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx, eVarSetOperationRemove, var_name, var_value_string.c_str())); @@ -719,8 +713,7 @@ protected: StripLeadingSpaces(var_value_str); std::string var_value_string = var_value_str.str(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx, + Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx, eVarSetOperationReplace, var_name, var_value_string.c_str())); @@ -853,8 +846,7 @@ protected: StripLeadingSpaces(var_value_str); std::string var_value_string = var_value_str.str(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx, + Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_string.c_str())); @@ -982,8 +974,7 @@ protected: StripLeadingSpaces(var_value_str); std::string var_value_string = var_value_str.str(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx, + Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_string.c_str())); @@ -1102,8 +1093,7 @@ protected: StripLeadingSpaces(var_value_str); std::string var_value_string = var_value_str.str(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx, + Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx, eVarSetOperationAppend, var_name, var_value_string.c_str())); @@ -1196,8 +1186,7 @@ protected: return false; } - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Error error (m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx, + Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx, eVarSetOperationClear, var_name, NULL)); diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 9915d705ce6..576519a39a0 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -250,7 +250,8 @@ public: CommandObjectParsed (interpreter, "source list", "Display source code (as specified) based on the current executable's debug info.", - NULL), + NULL, + eFlagRequiresTarget), m_options (interpreter) { } @@ -307,18 +308,7 @@ protected: return false; } - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - - if (target == NULL) - target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - - if (target == NULL) - { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } + Target *target = m_exe_ctx.GetTargetPtr(); SymbolContextList sc_list; if (!m_options.symbol_name.empty()) @@ -455,7 +445,7 @@ protected: { const bool show_inlines = true; m_breakpoint_locations.Reset (start_file, 0, show_inlines); - SearchFilter target_search_filter (exe_ctx.GetTargetSP()); + SearchFilter target_search_filter (m_exe_ctx.GetTargetSP()); target_search_filter.Search (m_breakpoint_locations); } else @@ -556,7 +546,7 @@ protected: bool show_module = true; bool show_inlined_frames = true; sc.DumpStopContext(&result.GetOutputStream(), - exe_ctx.GetBestExecutionContextScope(), + m_exe_ctx.GetBestExecutionContextScope(), sc.line_entry.range.GetBaseAddress(), show_fullpaths, show_module, diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 391cbc42cd1..1a6f3be79ce 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -600,7 +600,7 @@ public: "target variable", "Read global variable(s) prior to, or while running your binary.", NULL, - 0), + eFlagRequiresTarget), m_option_group (interpreter), m_option_variable (false), // Don't include frame options m_option_format (eFormatDefault), @@ -769,200 +769,190 @@ protected: virtual bool DoExecute (Args& args, CommandReturnObject &result) { - ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) + Target *target = m_exe_ctx.GetTargetPtr(); + const size_t argc = args.GetArgumentCount(); + Stream &s = result.GetOutputStream(); + + if (argc > 0) { - const size_t argc = args.GetArgumentCount(); - Stream &s = result.GetOutputStream(); - - if (argc > 0) + + for (size_t idx = 0; idx < argc; ++idx) { + VariableList variable_list; + ValueObjectList valobj_list; - for (size_t idx = 0; idx < argc; ++idx) + const char *arg = args.GetArgumentAtIndex(idx); + uint32_t matches = 0; + bool use_var_name = false; + if (m_option_variable.use_regex) { - VariableList variable_list; - ValueObjectList valobj_list; - - const char *arg = args.GetArgumentAtIndex(idx); - uint32_t matches = 0; - bool use_var_name = false; - if (m_option_variable.use_regex) + RegularExpression regex(arg); + if (!regex.IsValid ()) { - RegularExpression regex(arg); - if (!regex.IsValid ()) - { - result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg); - result.SetStatus (eReturnStatusFailed); - return false; - } - use_var_name = true; - matches = target->GetImages().FindGlobalVariables (regex, - true, - UINT32_MAX, - variable_list); - } - else - { - Error error (Variable::GetValuesForVariableExpressionPath (arg, - exe_ctx.GetBestExecutionContextScope(), - GetVariableCallback, - target, - variable_list, - valobj_list)); - matches = variable_list.GetSize(); - } - - if (matches == 0) - { - result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); + result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg); result.SetStatus (eReturnStatusFailed); return false; } - else + use_var_name = true; + matches = target->GetImages().FindGlobalVariables (regex, + true, + UINT32_MAX, + variable_list); + } + else + { + Error error (Variable::GetValuesForVariableExpressionPath (arg, + m_exe_ctx.GetBestExecutionContextScope(), + GetVariableCallback, + target, + variable_list, + valobj_list)); + matches = variable_list.GetSize(); + } + + if (matches == 0) + { + result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + for (uint32_t global_idx=0; global_idx<matches; ++global_idx) { - for (uint32_t global_idx=0; global_idx<matches; ++global_idx) + VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); + if (var_sp) { - VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); - if (var_sp) - { - ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); - if (!valobj_sp) - valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp); - - if (valobj_sp) - DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); - } + ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); + if (!valobj_sp) + valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp); + + if (valobj_sp) + DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); } } } } - else + } + else + { + const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue(); + const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue(); + SymbolContextList sc_list; + const size_t num_compile_units = compile_units.GetSize(); + const size_t num_shlibs = shlibs.GetSize(); + if (num_compile_units == 0 && num_shlibs == 0) { - const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue(); - const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue(); - SymbolContextList sc_list; - const size_t num_compile_units = compile_units.GetSize(); - const size_t num_shlibs = shlibs.GetSize(); - if (num_compile_units == 0 && num_shlibs == 0) + bool success = false; + StackFrame *frame = m_exe_ctx.GetFramePtr(); + CompileUnit *comp_unit = NULL; + if (frame) { - bool success = false; - StackFrame *frame = exe_ctx.GetFramePtr(); - CompileUnit *comp_unit = NULL; - if (frame) + SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit); + if (sc.comp_unit) { - SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit); - if (sc.comp_unit) + const bool can_create = true; + VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); + if (comp_unit_varlist_sp) { - const bool can_create = true; - VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); - if (comp_unit_varlist_sp) + size_t count = comp_unit_varlist_sp->GetSize(); + if (count > 0) { - size_t count = comp_unit_varlist_sp->GetSize(); - if (count > 0) - { - DumpGlobalVariableList(exe_ctx, sc, *comp_unit_varlist_sp, s); - success = true; - } + DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); + success = true; } } } - if (!success) + } + if (!success) + { + if (frame) { - if (frame) - { - if (comp_unit) - result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n", - comp_unit->GetDirectory().GetCString(), - comp_unit->GetFilename().GetCString()); - else - result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex()); - } + if (comp_unit) + result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n", + comp_unit->GetDirectory().GetCString(), + comp_unit->GetFilename().GetCString()); else - result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); - result.SetStatus (eReturnStatusFailed); - } + result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex()); + } + else + result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); + result.SetStatus (eReturnStatusFailed); } - else + } + else + { + SymbolContextList sc_list; + const bool append = true; + // We have one or more compile unit or shlib + if (num_shlibs > 0) { - SymbolContextList sc_list; - const bool append = true; - // We have one or more compile unit or shlib - if (num_shlibs > 0) + for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx) { - for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx) + const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx)); + ModuleSpec module_spec (module_file); + + ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); + if (module_sp) { - const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx)); - ModuleSpec module_spec (module_file); - - ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); - if (module_sp) + if (num_compile_units > 0) { - if (num_compile_units > 0) - { - for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) - module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); - } - else - { - SymbolContext sc; - sc.module_sp = module_sp; - sc_list.Append(sc); - } + for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) + module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); } else { - // Didn't find matching shlib/module in target... - result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s%s%s\n", - module_file.GetDirectory().GetCString(), - module_file.GetDirectory() ? "/" : "", - module_file.GetFilename().GetCString()); + SymbolContext sc; + sc.module_sp = module_sp; + sc_list.Append(sc); } } + else + { + // Didn't find matching shlib/module in target... + result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s%s%s\n", + module_file.GetDirectory().GetCString(), + module_file.GetDirectory() ? "/" : "", + module_file.GetFilename().GetCString()); + } } - else - { - // No shared libraries, we just want to find globals for the compile units files that were specified - for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) - target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); - } - - const uint32_t num_scs = sc_list.GetSize(); - if (num_scs > 0) + } + else + { + // No shared libraries, we just want to find globals for the compile units files that were specified + for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) + target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); + } + + const uint32_t num_scs = sc_list.GetSize(); + if (num_scs > 0) + { + SymbolContext sc; + for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx) { - SymbolContext sc; - for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx) + if (sc_list.GetContextAtIndex(sc_idx, sc)) { - if (sc_list.GetContextAtIndex(sc_idx, sc)) + if (sc.comp_unit) { - if (sc.comp_unit) - { - const bool can_create = true; - VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); - if (comp_unit_varlist_sp) - DumpGlobalVariableList(exe_ctx, sc, *comp_unit_varlist_sp, s); - } - else if (sc.module_sp) - { - // Get all global variables for this module - lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character - VariableList variable_list; - sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list); - DumpGlobalVariableList(exe_ctx, sc, variable_list, s); - } + const bool can_create = true; + VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); + if (comp_unit_varlist_sp) + DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); + } + else if (sc.module_sp) + { + // Get all global variables for this module + lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character + VariableList variable_list; + sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list); + DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s); } } } } } } - else - { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - + if (m_interpreter.TruncationWarningNecessary()) { result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), @@ -1997,10 +1987,11 @@ class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectPar public: CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, - const char *name, - const char *help, - const char *syntax) : - CommandObjectParsed (interpreter, name, help, syntax) + const char *name, + const char *help, + const char *syntax, + uint32_t flags) : + CommandObjectParsed (interpreter, name, help, syntax, flags) { CommandArgumentEntry arg; CommandArgumentData source_file_arg; @@ -2461,9 +2452,10 @@ class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModule public: CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : CommandObjectTargetModulesSourceFileAutoComplete (interpreter, - "target modules dump line-table", - "Dump the debug symbol file for one or more target modules.", - NULL) + "target modules dump line-table", + "Dump the debug symbol file for one or more target modules.", + NULL, + eFlagRequiresTarget) { } @@ -2477,65 +2469,55 @@ protected: DoExecute (Args& command, CommandReturnObject &result) { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) + Target *target = m_exe_ctx.GetTargetPtr(); + uint32_t total_num_dumped = 0; + + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + + if (command.GetArgumentCount() == 0) { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); result.SetStatus (eReturnStatusFailed); - return false; } else { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - uint32_t total_num_dumped = 0; - - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - - if (command.GetArgumentCount() == 0) - { - result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); - result.SetStatus (eReturnStatusFailed); - } - else + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) + FileSpec file_spec(arg_cstr, false); + + const ModuleList &target_modules = target->GetImages(); + Mutex::Locker modules_locker(target_modules.GetMutex()); + const uint32_t num_modules = target_modules.GetSize(); + if (num_modules > 0) { - FileSpec file_spec(arg_cstr, false); - - const ModuleList &target_modules = target->GetImages(); - Mutex::Locker modules_locker(target_modules.GetMutex()); - const uint32_t num_modules = target_modules.GetSize(); - if (num_modules > 0) + uint32_t num_dumped = 0; + for (uint32_t i = 0; i<num_modules; ++i) { - uint32_t num_dumped = 0; - for (uint32_t i = 0; i<num_modules; ++i) - { - if (DumpCompileUnitLineTable (m_interpreter, - result.GetOutputStream(), - target_modules.GetModulePointerAtIndexUnlocked(i), - file_spec, - exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) - num_dumped++; - } - if (num_dumped == 0) - result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); - else - total_num_dumped += num_dumped; + if (DumpCompileUnitLineTable (m_interpreter, + result.GetOutputStream(), + target_modules.GetModulePointerAtIndexUnlocked(i), + file_spec, + m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive())) + num_dumped++; } + if (num_dumped == 0) + result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); + else + total_num_dumped += num_dumped; } } - - if (total_num_dumped > 0) - result.SetStatus (eReturnStatusSuccessFinishResult); - else - { - result.AppendError ("no source filenames matched any command arguments"); - result.SetStatus (eReturnStatusFailed); - } + } + + if (total_num_dumped > 0) + result.SetStatus (eReturnStatusSuccessFinishResult); + else + { + result.AppendError ("no source filenames matched any command arguments"); + result.SetStatus (eReturnStatusFailed); } return result.Succeeded(); } @@ -3475,10 +3457,10 @@ public: public: CommandOptions (CommandInterpreter &interpreter) : - Options(interpreter), - m_type(eLookupTypeInvalid), - m_str(), - m_addr(LLDB_INVALID_ADDRESS) + Options(interpreter), + m_type(eLookupTypeInvalid), + m_str(), + m_addr(LLDB_INVALID_ADDRESS) { } @@ -3541,7 +3523,11 @@ public: CommandObjectParsed (interpreter, "target modules show-unwind", "Show synthesized unwind instructions for a function.", - NULL), + NULL, + eFlagRequiresTarget | + eFlagRequiresProcess | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ), m_options (interpreter) { } @@ -3563,16 +3549,8 @@ protected: DoExecute (Args& command, CommandReturnObject &result) { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (!target) - { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext(); - Process *process = exe_ctx.GetProcessPtr(); + Target *target = m_exe_ctx.GetTargetPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); ABI *abi = NULL; if (process) abi = process->GetABI().get(); @@ -3837,7 +3815,8 @@ public: CommandObjectParsed (interpreter, "target modules lookup", "Look up information within executable and dependent shared library images.", - NULL), + NULL, + eFlagRequiresTarget), m_options (interpreter) { CommandArgumentEntry arg; @@ -3881,9 +3860,7 @@ public: break; } - ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext(); - - StackFrameSP frame = exe_ctx.GetFrameSP(); + StackFrameSP frame = m_exe_ctx.GetFrameSP(); if (!frame) return false; @@ -4375,198 +4352,190 @@ protected: DoExecute (Args& args, CommandReturnObject &result) { - ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); + Target *target = m_exe_ctx.GetTargetPtr(); result.SetStatus (eReturnStatusFailed); - if (target == NULL) - { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); - } - else - { - bool flush = false; - ModuleSpec module_spec; - const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); - const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); - const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); + bool flush = false; + ModuleSpec module_spec; + const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); + const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); + const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); - const size_t argc = args.GetArgumentCount(); - if (argc == 0) + const size_t argc = args.GetArgumentCount(); + if (argc == 0) + { + if (uuid_option_set || file_option_set || frame_option_set) { - if (uuid_option_set || file_option_set || frame_option_set) + bool success = false; + bool error_set = false; + if (frame_option_set) { - bool success = false; - bool error_set = false; - if (frame_option_set) + Process *process = m_exe_ctx.GetProcessPtr(); + if (process) { - Process *process = exe_ctx.GetProcessPtr(); - if (process) + const StateType process_state = process->GetState(); + if (StateIsStoppedState (process_state, true)) { - const StateType process_state = process->GetState(); - if (StateIsStoppedState (process_state, true)) + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (frame) { - StackFrame *frame = exe_ctx.GetFramePtr(); - if (frame) + ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); + if (frame_module_sp) { - ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); - if (frame_module_sp) - { - if (frame_module_sp->GetPlatformFileSpec().Exists()) - { - module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); - module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); - } - module_spec.GetUUID() = frame_module_sp->GetUUID(); - success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec(); - } - else + if (frame_module_sp->GetPlatformFileSpec().Exists()) { - result.AppendError ("frame has no module"); - error_set = true; + module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); + module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); } + module_spec.GetUUID() = frame_module_sp->GetUUID(); + success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec(); } else { - result.AppendError ("invalid current frame"); + result.AppendError ("frame has no module"); error_set = true; } } else { - result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); + result.AppendError ("invalid current frame"); error_set = true; } } else { - result.AppendError ("a process must exist in order to use the --frame option"); + result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); error_set = true; } } else { - if (uuid_option_set) - { - module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); - success |= module_spec.GetUUID().IsValid(); - } - else if (file_option_set) - { - module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); - ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); - if (module_sp) - { - module_spec.GetFileSpec() = module_sp->GetFileSpec(); - module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); - module_spec.GetUUID() = module_sp->GetUUID(); - module_spec.GetArchitecture() = module_sp->GetArchitecture(); - } - else - { - module_spec.GetArchitecture() = target->GetArchitecture(); - } - success |= module_spec.GetFileSpec().Exists(); - } + result.AppendError ("a process must exist in order to use the --frame option"); + error_set = true; } - - if (success) + } + else + { + if (uuid_option_set) { - if (Symbols::DownloadObjectAndSymbolFile (module_spec)) - { - if (module_spec.GetSymbolFileSpec()) - success = AddModuleSymbols (target, module_spec, flush, result); - } + module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); + success |= module_spec.GetUUID().IsValid(); } - - if (!success && !error_set) + else if (file_option_set) { - StreamString error_strm; - if (uuid_option_set) - { - error_strm.PutCString("unable to find debug symbols for UUID "); - module_spec.GetUUID().Dump (&error_strm); - } - else if (file_option_set) + module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); + ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); + if (module_sp) { - error_strm.PutCString("unable to find debug symbols for the executable file "); - error_strm << module_spec.GetFileSpec(); + module_spec.GetFileSpec() = module_sp->GetFileSpec(); + module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); + module_spec.GetUUID() = module_sp->GetUUID(); + module_spec.GetArchitecture() = module_sp->GetArchitecture(); } - else if (frame_option_set) + else { - error_strm.PutCString("unable to find debug symbols for the current frame"); + module_spec.GetArchitecture() = target->GetArchitecture(); } - result.AppendError (error_strm.GetData()); + success |= module_spec.GetFileSpec().Exists(); } } - else + + if (success) + { + if (Symbols::DownloadObjectAndSymbolFile (module_spec)) + { + if (module_spec.GetSymbolFileSpec()) + success = AddModuleSymbols (target, module_spec, flush, result); + } + } + + if (!success && !error_set) { - result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); + StreamString error_strm; + if (uuid_option_set) + { + error_strm.PutCString("unable to find debug symbols for UUID "); + module_spec.GetUUID().Dump (&error_strm); + } + else if (file_option_set) + { + error_strm.PutCString("unable to find debug symbols for the executable file "); + error_strm << module_spec.GetFileSpec(); + } + else if (frame_option_set) + { + error_strm.PutCString("unable to find debug symbols for the current frame"); + } + result.AppendError (error_strm.GetData()); } } else { - if (uuid_option_set) - { - result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); - } - else if (file_option_set) - { - result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); - } - else if (frame_option_set) - { - result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); - } - else - { - PlatformSP platform_sp (target->GetPlatform()); + result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); + } + } + else + { + if (uuid_option_set) + { + result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); + } + else if (file_option_set) + { + result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); + } + else if (frame_option_set) + { + result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); + } + else + { + PlatformSP platform_sp (target->GetPlatform()); - for (size_t i=0; i<argc; ++i) + for (size_t i=0; i<argc; ++i) + { + const char *symfile_path = args.GetArgumentAtIndex(i); + if (symfile_path) { - const char *symfile_path = args.GetArgumentAtIndex(i); - if (symfile_path) + module_spec.GetSymbolFileSpec().SetFile(symfile_path, true); + if (platform_sp) { - module_spec.GetSymbolFileSpec().SetFile(symfile_path, true); - if (platform_sp) - { - FileSpec symfile_spec; - if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) - module_spec.GetSymbolFileSpec() = symfile_spec; - } - - ArchSpec arch; - bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); + FileSpec symfile_spec; + if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) + module_spec.GetSymbolFileSpec() = symfile_spec; + } + + ArchSpec arch; + bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); - if (symfile_exists) - { - if (!AddModuleSymbols (target, module_spec, flush, result)) - break; - } - else + if (symfile_exists) + { + if (!AddModuleSymbols (target, module_spec, flush, result)) + break; + } + else + { + char resolved_symfile_path[PATH_MAX]; + if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) { - char resolved_symfile_path[PATH_MAX]; - if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) + if (strcmp (resolved_symfile_path, symfile_path) != 0) { - if (strcmp (resolved_symfile_path, symfile_path) != 0) - { - result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); - break; - } + result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); + break; } - result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); - break; } + result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); + break; } } } } + } - if (flush) - { - Process *process = exe_ctx.GetProcessPtr(); - if (process) - process->Flush(); - } + if (flush) + { + Process *process = m_exe_ctx.GetProcessPtr(); + if (process) + process->Flush(); } return result.Succeeded(); } diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 7a58441fb3c..8a978d3a10f 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -125,10 +125,14 @@ public: CommandObjectThreadBacktrace (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, - "thread backtrace", - "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.", - NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + "thread backtrace", + "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.", + NULL, + eFlagRequiresProcess | + eFlagRequiresThread | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ), m_options(interpreter) { CommandArgumentEntry arg; @@ -166,28 +170,19 @@ protected: const uint32_t num_frames_with_source = 0; if (command.GetArgumentCount() == 0) { - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - Thread *thread = exe_ctx.GetThreadPtr(); - if (thread) + Thread *thread = m_exe_ctx.GetThreadPtr(); + // Thread::GetStatus() returns the number of frames shown. + if (thread->GetStatus (strm, + m_options.m_start, + m_options.m_count, + num_frames_with_source)) { - // Thread::GetStatus() returns the number of frames shown. - if (thread->GetStatus (strm, - m_options.m_start, - m_options.m_count, - num_frames_with_source)) - { - result.SetStatus (eReturnStatusSuccessFinishResult); - } - } - else - { - result.AppendError ("invalid thread"); - result.SetStatus (eReturnStatusFailed); + result.SetStatus (eReturnStatusSuccessFinishResult); } } else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) { - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); Mutex::Locker locker (process->GetThreadList().GetMutex()); uint32_t num_threads = process->GetThreadList().GetSize(); for (uint32_t i = 0; i < num_threads; i++) @@ -211,7 +206,7 @@ protected: else { uint32_t num_args = command.GetArgumentCount(); - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); Mutex::Locker locker (process->GetThreadList().GetMutex()); std::vector<ThreadSP> thread_sps; @@ -370,10 +365,14 @@ public: const char *name, const char *help, const char *syntax, - uint32_t flags, StepType step_type, StepScope step_scope) : - CommandObjectParsed (interpreter, name, help, syntax, flags), + CommandObjectParsed (interpreter, name, help, syntax, + eFlagRequiresProcess | + eFlagRequiresThread | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ), m_step_type (step_type), m_step_scope (step_scope), m_options (interpreter) @@ -408,170 +407,161 @@ protected: virtual bool 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 ("need a valid process to step"); - result.SetStatus (eReturnStatusFailed); + const uint32_t num_threads = process->GetThreadList().GetSize(); + Thread *thread = NULL; + if (command.GetArgumentCount() == 0) + { + thread = process->GetThreadList().GetSelectedThread().get(); + if (thread == NULL) + { + result.AppendError ("no selected thread in process"); + result.SetStatus (eReturnStatusFailed); + return false; + } } else { - const uint32_t num_threads = process->GetThreadList().GetSize(); - Thread *thread = NULL; - - if (command.GetArgumentCount() == 0) + const char *thread_idx_cstr = command.GetArgumentAtIndex(0); + uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32); + if (step_thread_idx == LLDB_INVALID_INDEX32) { - thread = process->GetThreadList().GetSelectedThread().get(); - if (thread == NULL) - { - result.AppendError ("no selected thread in process"); - result.SetStatus (eReturnStatusFailed); - return false; - } + result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr); + result.SetStatus (eReturnStatusFailed); + return false; } - else + thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get(); + if (thread == NULL) { - const char *thread_idx_cstr = command.GetArgumentAtIndex(0); - uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32); - if (step_thread_idx == LLDB_INVALID_INDEX32) - { - result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr); - result.SetStatus (eReturnStatusFailed); - return false; - } - thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get(); - if (thread == NULL) - { - result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", - step_thread_idx, num_threads); - result.SetStatus (eReturnStatusFailed); - return false; - } + result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", + step_thread_idx, num_threads); + result.SetStatus (eReturnStatusFailed); + return false; } + } - const bool abort_other_plans = false; - const lldb::RunMode stop_other_threads = m_options.m_run_mode; - - // This is a bit unfortunate, but not all the commands in this command object support - // only while stepping, so I use the bool for them. - bool bool_stop_other_threads; - if (m_options.m_run_mode == eAllThreads) + const bool abort_other_plans = false; + const lldb::RunMode stop_other_threads = m_options.m_run_mode; + + // This is a bit unfortunate, but not all the commands in this command object support + // only while stepping, so I use the bool for them. + bool bool_stop_other_threads; + if (m_options.m_run_mode == eAllThreads) + bool_stop_other_threads = false; + else if (m_options.m_run_mode == eOnlyDuringStepping) + { + if (m_step_type == eStepTypeOut) bool_stop_other_threads = false; - else if (m_options.m_run_mode == eOnlyDuringStepping) - { - if (m_step_type == eStepTypeOut) - bool_stop_other_threads = false; - else - bool_stop_other_threads = true; - } else bool_stop_other_threads = true; + } + else + bool_stop_other_threads = true; - ThreadPlan *new_plan = NULL; - - if (m_step_type == eStepTypeInto) - { - StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); + ThreadPlan *new_plan = NULL; + + if (m_step_type == eStepTypeInto) + { + StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); - if (frame->HasDebugInformation ()) + if (frame->HasDebugInformation ()) + { + new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans, + frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, + frame->GetSymbolContext(eSymbolContextEverything), + m_options.m_step_in_target.c_str(), + stop_other_threads, + m_options.m_avoid_no_debug); + if (new_plan && !m_options.m_avoid_regexp.empty()) { - new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans, - frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, - frame->GetSymbolContext(eSymbolContextEverything), - m_options.m_step_in_target.c_str(), - stop_other_threads, - m_options.m_avoid_no_debug); - if (new_plan && !m_options.m_avoid_regexp.empty()) - { - ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan); - step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); - } + ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan); + step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str()); } - else - new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); - - } - else if (m_step_type == eStepTypeOver) - { - StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); - - if (frame->HasDebugInformation()) - new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans, - frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, - frame->GetSymbolContext(eSymbolContextEverything), - stop_other_threads); - else - new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, - abort_other_plans, - bool_stop_other_threads); - } - else if (m_step_type == eStepTypeTrace) - { + else new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); - } - else if (m_step_type == eStepTypeTraceOver) - { - new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); - } - else if (m_step_type == eStepTypeOut) - { - new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, - NULL, - false, - bool_stop_other_threads, - eVoteYes, - eVoteNoOpinion, - thread->GetSelectedFrameIndex()); - } + + } + else if (m_step_type == eStepTypeOver) + { + StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); + + if (frame->HasDebugInformation()) + new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans, + frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, + frame->GetSymbolContext(eSymbolContextEverything), + stop_other_threads); else - { - result.AppendError ("step type is not supported"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - // If we got a new plan, then set it to be a master plan (User level Plans should be master plans - // so that they can be interruptible). Then resume the process. - - if (new_plan != NULL) - { - new_plan->SetIsMasterPlan (true); - new_plan->SetOkayToDiscard (false); + new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, + abort_other_plans, + bool_stop_other_threads); - process->GetThreadList().SetSelectedThreadByID (thread->GetID()); - process->Resume (); - + } + else if (m_step_type == eStepTypeTrace) + { + new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); + } + else if (m_step_type == eStepTypeTraceOver) + { + new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); + } + else if (m_step_type == eStepTypeOut) + { + new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, + NULL, + false, + bool_stop_other_threads, + eVoteYes, + eVoteNoOpinion, + thread->GetSelectedFrameIndex()); + } + else + { + result.AppendError ("step type is not supported"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + // If we got a new plan, then set it to be a master plan (User level Plans should be master plans + // so that they can be interruptible). Then resume the process. + + if (new_plan != NULL) + { + new_plan->SetIsMasterPlan (true); + new_plan->SetOkayToDiscard (false); - if (synchronous_execution) - { - StateType state = process->WaitForProcessToStop (NULL); - - //EventSP event_sp; - //StateType state = process->WaitForStateChangedEvents (NULL, event_sp); - //while (! StateIsStoppedState (state)) - // { - // state = process->WaitForStateChangedEvents (NULL, event_sp); - // } - process->GetThreadList().SetSelectedThreadByID (thread->GetID()); - result.SetDidChangeProcessState (true); - result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.SetStatus (eReturnStatusSuccessContinuingNoResult); - } + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); + process->Resume (); + + + if (synchronous_execution) + { + StateType state = process->WaitForProcessToStop (NULL); + + //EventSP event_sp; + //StateType state = process->WaitForStateChangedEvents (NULL, event_sp); + //while (! StateIsStoppedState (state)) + // { + // state = process->WaitForStateChangedEvents (NULL, event_sp); + // } + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); + result.SetDidChangeProcessState (true); + result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); + result.SetStatus (eReturnStatusSuccessFinishNoResult); } else { - result.AppendError ("Couldn't find thread plan to implement step type."); - result.SetStatus (eReturnStatusFailed); + result.SetStatus (eReturnStatusSuccessContinuingNoResult); } } + else + { + result.AppendError ("Couldn't find thread plan to implement step type."); + result.SetStatus (eReturnStatusFailed); + } return result.Succeeded(); } @@ -622,7 +612,10 @@ public: "thread continue", "Continue execution of one or more threads in an active process.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) + eFlagRequiresThread | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused) { CommandArgumentEntry arg; CommandArgumentData thread_idx_arg; @@ -656,7 +649,7 @@ public: return false; } - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); if (process == NULL) { result.AppendError ("no process exists. Cannot continue"); @@ -902,7 +895,10 @@ public: "thread until", "Run the current or specified thread until it reaches a given line number or leaves the current function.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + eFlagRequiresThread | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ), m_options (interpreter) { CommandArgumentEntry arg; @@ -946,7 +942,7 @@ protected: return false; } - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); if (process == NULL) { result.AppendError ("need a valid process to step"); @@ -1144,7 +1140,10 @@ public: "thread select", "Select a thread as the currently active thread.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) + eFlagRequiresProcess | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ) { CommandArgumentEntry arg; CommandArgumentData thread_idx_arg; @@ -1170,7 +1169,7 @@ protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + Process *process = m_exe_ctx.GetProcessPtr(); if (process == NULL) { result.AppendError ("no process"); @@ -1217,7 +1216,10 @@ public: "thread list", "Show a summary of all current threads in a process.", "thread list", - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) + eFlagRequiresProcess | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ) { } @@ -1231,26 +1233,17 @@ protected: { 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 = false; - const uint32_t start_frame = 0; - const uint32_t num_frames = 0; - const uint32_t num_frames_with_source = 0; - process->GetStatus(strm); - process->GetThreadStatus (strm, - only_threads_with_stop_reason, - start_frame, - num_frames, - num_frames_with_source); - } - else - { - result.AppendError ("no current location or status available"); - result.SetStatus (eReturnStatusFailed); - } + Process *process = m_exe_ctx.GetProcessPtr(); + const bool only_threads_with_stop_reason = false; + const uint32_t start_frame = 0; + const uint32_t num_frames = 0; + const uint32_t num_frames_with_source = 0; + process->GetStatus(strm); + process->GetThreadStatus (strm, + only_threads_with_stop_reason, + start_frame, + num_frames, + num_frames_with_source); return result.Succeeded(); } }; @@ -1263,7 +1256,10 @@ public: "thread return", "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value.", "thread return", - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) + eFlagRequiresFrame | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ) { CommandArgumentEntry arg; CommandArgumentData expression_arg; @@ -1293,18 +1289,9 @@ protected: CommandReturnObject &result ) { - // If there is a command string, pass it to the expression parser: - ExecutionContext exe_ctx = m_interpreter.GetExecutionContext(); - if (!(exe_ctx.HasProcessScope() && exe_ctx.HasThreadScope() && exe_ctx.HasFrameScope())) - { - result.AppendError("Must have selected process, thread and frame for thread return."); - result.SetStatus (eReturnStatusFailed); - return false; - } - ValueObjectSP return_valobj_sp; - StackFrameSP frame_sp = exe_ctx.GetFrameSP(); + StackFrameSP frame_sp = m_exe_ctx.GetFrameSP(); uint32_t frame_idx = frame_sp->GetFrameIndex(); if (frame_sp->IsInlined()) @@ -1316,7 +1303,7 @@ protected: if (command && command[0] != '\0') { - Target *target = exe_ctx.GetTargetPtr(); + Target *target = m_exe_ctx.GetTargetPtr(); EvaluateExpressionOptions options; options.SetUnwindOnError(true); @@ -1340,7 +1327,7 @@ protected: } Error error; - ThreadSP thread_sp = exe_ctx.GetThreadSP(); + ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); const bool broadcast = true; error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast); if (!error.Success()) @@ -1377,7 +1364,6 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter & "thread step-in", "Source level single step in specified thread (current thread, if none specified).", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, eStepTypeInto, eStepScopeSource))); @@ -1386,7 +1372,6 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter & "thread step-out", "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, eStepTypeOut, eStepScopeSource))); @@ -1395,7 +1380,6 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter & "thread step-over", "Source level single step in specified thread (current thread, if none specified), stepping over calls.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, eStepTypeOver, eStepScopeSource))); @@ -1404,7 +1388,6 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter & "thread step-inst", "Single step one instruction in specified thread (current thread, if none specified).", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, eStepTypeTrace, eStepScopeInstruction))); @@ -1413,7 +1396,6 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter & "thread step-inst-over", "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused, eStepTypeTraceOver, eStepScopeInstruction))); } diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index f63e4a85012..f4d3c1340ba 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -934,7 +934,10 @@ public: "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 @@ protected: } 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ public: "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 @@ protected: 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 @@ protected: 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 @@ protected: // 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 @@ protected: 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 @@ protected: 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)) diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp index e90ae8f2b66..784187f8763 100644 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -208,8 +208,77 @@ CommandObject::ParseOptions bool -CommandObject::CheckFlags (CommandReturnObject &result) +CommandObject::CheckRequirements (CommandReturnObject &result) { +#ifdef LLDB_CONFIGURATION_DEBUG + // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx + // has shared pointers to the target, process, thread and frame and we don't + // want any CommandObject instances to keep any of these objects around + // longer than for a single command. Every command should call + // CommandObject::Cleanup() after it has completed + assert (m_exe_ctx.GetTargetPtr() == NULL); + assert (m_exe_ctx.GetProcessPtr() == NULL); + assert (m_exe_ctx.GetThreadPtr() == NULL); + assert (m_exe_ctx.GetFramePtr() == NULL); +#endif + + // Lock down the interpreter's execution context prior to running the + // command so we guarantee the selected target, process, thread and frame + // can't go away during the execution + m_exe_ctx = m_interpreter.GetExecutionContext(); + + const uint32_t flags = GetFlags().Get(); + if (flags & (eFlagRequiresTarget | + eFlagRequiresProcess | + eFlagRequiresThread | + eFlagRequiresFrame | + eFlagTryTargetAPILock )) + { + + if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope()) + { + result.AppendError (GetInvalidTargetDescription()); + return false; + } + + if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope()) + { + result.AppendError (GetInvalidProcessDescription()); + return false; + } + + if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope()) + { + result.AppendError (GetInvalidThreadDescription()); + return false; + } + + if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope()) + { + result.AppendError (GetInvalidFrameDescription()); + return false; + } + + if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == NULL)) + { + result.AppendError (GetInvalidRegContextDescription()); + return false; + } + + if (flags & eFlagTryTargetAPILock) + { + Target *target = m_exe_ctx.GetTargetPtr(); + if (target) + { + if (m_api_locker.TryLock (target->GetAPIMutex(), NULL) == false) + { + result.AppendError ("failed to get API lock"); + return false; + } + } + } + } + if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused)) { Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); @@ -263,6 +332,14 @@ CommandObject::CheckFlags (CommandReturnObject &result) return true; } +void +CommandObject::Cleanup () +{ + m_exe_ctx.Clear(); + m_api_locker.Unlock(); +} + + class CommandDictCommandPartialMatch { public: @@ -888,14 +965,16 @@ CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &resu cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str)); } - if (!CheckFlags(result)) - return false; - - if (!ParseOptions (cmd_args, result)) - return false; + if (CheckRequirements(result)) + { + if (ParseOptions (cmd_args, result)) + { + // Call the command-specific version of 'Execute', passing it the already processed arguments. + handled = DoExecute (cmd_args, result); + } + } - // Call the command-specific version of 'Execute', passing it the already processed arguments. - handled = DoExecute (cmd_args, result); + Cleanup(); } return handled; } @@ -916,10 +995,10 @@ CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result) } if (!handled) { - if (!CheckFlags(result)) - return false; - else + if (CheckRequirements(result)) handled = DoExecute (args_string, result); + + Cleanup(); } return handled; } |