aboutsummaryrefslogtreecommitdiff
path: root/lldb/source
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2020-12-17 17:10:17 +0100
committerPavel Labath <pavel@labath.sk>2020-12-17 17:47:53 +0100
commit122a4ebde3f4394a84e9f93b9c7085f088be6dd7 (patch)
tree0cdf9c43e826c3e4d159e06b854520d837efe9ea /lldb/source
parentf50066292477fb26806336e5604615d0eddde399 (diff)
downloadllvm-122a4ebde3f4394a84e9f93b9c7085f088be6dd7.zip
llvm-122a4ebde3f4394a84e9f93b9c7085f088be6dd7.tar.gz
llvm-122a4ebde3f4394a84e9f93b9c7085f088be6dd7.tar.bz2
Revert "[lldb] Make CommandInterpreter's execution context the same as debugger's one."
This reverts commit a01b26fb51c710a3a8ef88cc83b0701461f5b9ab, because it breaks the "finish" command in some way -- the command does not terminate after it steps out, but continues running the target. The exact blast radius is not clear, but it at least affects the usage of the "finish" command in TestGuiBasicDebug.py. The error is *not* gui-related, as the same issue can be reproduced by running the same steps outside of the gui. There is some kind of a race going on, as the test fails only 20% of the time on the buildbot.
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBCommandInterpreter.cpp37
-rw-r--r--lldb/source/Breakpoint/BreakpointOptions.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectCommands.cpp14
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp14
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp1
-rw-r--r--lldb/source/Commands/CommandObjectRegexCommand.cpp4
-rw-r--r--lldb/source/Commands/CommandObjectSettings.cpp3
-rw-r--r--lldb/source/Commands/CommandObjectWatchpointCommand.cpp2
-rw-r--r--lldb/source/Core/IOHandlerCursesGUI.cpp3
-rw-r--r--lldb/source/Interpreter/CommandInterpreter.cpp136
-rw-r--r--lldb/source/Target/Target.cpp2
11 files changed, 121 insertions, 97 deletions
diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp
index d28bc41..31e7da8 100644
--- a/lldb/source/API/SBCommandInterpreter.cpp
+++ b/lldb/source/API/SBCommandInterpreter.cpp
@@ -171,23 +171,27 @@ lldb::ReturnStatus SBCommandInterpreter::HandleCommand(
lldb::SBCommandReturnObject &, bool),
command_line, override_context, result, add_to_history);
+
+ ExecutionContext ctx, *ctx_ptr;
+ if (override_context.get()) {
+ ctx = override_context.get()->Lock(true);
+ ctx_ptr = &ctx;
+ } else
+ ctx_ptr = nullptr;
+
result.Clear();
if (command_line && IsValid()) {
result.ref().SetInteractive(false);
- auto do_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo;
- if (override_context.get())
- m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
- override_context.get()->Lock(true),
- result.ref());
- else
- m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
- result.ref());
+ m_opaque_ptr->HandleCommand(command_line,
+ add_to_history ? eLazyBoolYes : eLazyBoolNo,
+ result.ref(), ctx_ptr);
} else {
result->AppendError(
"SBCommandInterpreter or the command line is not valid");
result->SetStatus(eReturnStatusFailed);
}
+
return result.GetStatus();
}
@@ -215,14 +219,15 @@ void SBCommandInterpreter::HandleCommandsFromFile(
}
FileSpec tmp_spec = file.ref();
- if (override_context.get())
- m_opaque_ptr->HandleCommandsFromFile(tmp_spec,
- override_context.get()->Lock(true),
- options.ref(),
- result.ref());
-
- else
- m_opaque_ptr->HandleCommandsFromFile(tmp_spec, options.ref(), result.ref());
+ ExecutionContext ctx, *ctx_ptr;
+ if (override_context.get()) {
+ ctx = override_context.get()->Lock(true);
+ ctx_ptr = &ctx;
+ } else
+ ctx_ptr = nullptr;
+
+ m_opaque_ptr->HandleCommandsFromFile(tmp_spec, ctx_ptr, options.ref(),
+ result.ref());
}
int SBCommandInterpreter::HandleCompletion(
diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp
index 2fdb53e..f6bb763 100644
--- a/lldb/source/Breakpoint/BreakpointOptions.cpp
+++ b/lldb/source/Breakpoint/BreakpointOptions.cpp
@@ -649,7 +649,7 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction(
options.SetPrintErrors(true);
options.SetAddToHistory(false);
- debugger.GetCommandInterpreter().HandleCommands(commands, exe_ctx,
+ debugger.GetCommandInterpreter().HandleCommands(commands, &exe_ctx,
options, result);
result.GetImmediateOutputStream()->Flush();
result.GetImmediateErrorStream()->Flush();
diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp
index 49d8e8a..0c441dd 100644
--- a/lldb/source/Commands/CommandObjectCommands.cpp
+++ b/lldb/source/Commands/CommandObjectCommands.cpp
@@ -134,12 +134,15 @@ protected:
FileSpec cmd_file(command[0].ref());
FileSystem::Instance().Resolve(cmd_file);
+ ExecutionContext *exe_ctx = nullptr; // Just use the default context.
- CommandInterpreterRunOptions options;
// If any options were set, then use them
if (m_options.m_stop_on_error.OptionWasSet() ||
m_options.m_silent_run.OptionWasSet() ||
m_options.m_stop_on_continue.OptionWasSet()) {
+ // Use user set settings
+ CommandInterpreterRunOptions options;
+
if (m_options.m_stop_on_continue.OptionWasSet())
options.SetStopOnContinue(
m_options.m_stop_on_continue.GetCurrentValue());
@@ -156,9 +159,14 @@ protected:
options.SetEchoCommands(m_interpreter.GetEchoCommands());
options.SetEchoCommentCommands(m_interpreter.GetEchoCommentCommands());
}
- }
- m_interpreter.HandleCommandsFromFile(cmd_file, options, result);
+ m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
+ } else {
+ // No options were set, inherit any settings from nested "command source"
+ // commands, or set to sane default settings...
+ CommandInterpreterRunOptions options;
+ m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
+ }
return result.Succeeded();
}
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index c7866f9..58eaa3f 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -292,12 +292,18 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
options.SetAutoApplyFixIts(false);
options.SetGenerateDebugInfo(false);
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
-
- // Get out before we start doing things that expect a valid frame pointer.
- if (exe_ctx.GetFramePtr() == nullptr)
+ // We need a valid execution context with a frame pointer for this
+ // completion, so if we don't have one we should try to make a valid
+ // execution context.
+ if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr)
+ m_interpreter.UpdateExecutionContext(nullptr);
+
+ // This didn't work, so let's get out before we start doing things that
+ // expect a valid frame pointer.
+ if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr)
return;
+ ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Target *exe_target = exe_ctx.GetTargetPtr();
Target &target = exe_target ? *exe_target : GetDummyTarget();
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 8beabed..1eef280 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -380,6 +380,7 @@ protected:
return false;
}
+ m_interpreter.UpdateExecutionContext(nullptr);
StreamString stream;
const auto error = target->Attach(m_options.attach_info, &stream);
if (error.Success()) {
diff --git a/lldb/source/Commands/CommandObjectRegexCommand.cpp b/lldb/source/Commands/CommandObjectRegexCommand.cpp
index dcd05a12..1bf29d3 100644
--- a/lldb/source/Commands/CommandObjectRegexCommand.cpp
+++ b/lldb/source/Commands/CommandObjectRegexCommand.cpp
@@ -53,8 +53,8 @@ bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
// Pass in true for "no context switching". The command that called us
// should have set up the context appropriately, we shouldn't have to
// redo that.
- return m_interpreter.HandleCommand(new_command.c_str(),
- eLazyBoolCalculate, result);
+ return m_interpreter.HandleCommand(
+ new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true);
}
}
result.SetStatus(eReturnStatusFailed);
diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp
index d869377..87e0352 100644
--- a/lldb/source/Commands/CommandObjectSettings.cpp
+++ b/lldb/source/Commands/CommandObjectSettings.cpp
@@ -469,13 +469,14 @@ protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
FileSpec file(m_options.m_filename);
FileSystem::Instance().Resolve(file);
+ ExecutionContext clean_ctx;
CommandInterpreterRunOptions options;
options.SetAddToHistory(false);
options.SetEchoCommands(false);
options.SetPrintResults(true);
options.SetPrintErrors(true);
options.SetStopOnError(false);
- m_interpreter.HandleCommandsFromFile(file, options, result);
+ m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
return result.Succeeded();
}
diff --git a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
index 3df17a0..fe3052a 100644
--- a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -301,7 +301,7 @@ are no syntax errors may indicate that a function was declared but never called.
options.SetPrintErrors(true);
options.SetAddToHistory(false);
- debugger.GetCommandInterpreter().HandleCommands(commands, exe_ctx,
+ debugger.GetCommandInterpreter().HandleCommands(commands, &exe_ctx,
options, result);
result.GetImmediateOutputStream()->Flush();
result.GetImmediateErrorStream()->Flush();
diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp
index af9fb29..19066e6 100644
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -1390,6 +1390,8 @@ public:
ConstString broadcaster_class(
broadcaster->GetBroadcasterClass());
if (broadcaster_class == broadcaster_class_process) {
+ debugger.GetCommandInterpreter().UpdateExecutionContext(
+ nullptr);
m_update_screen = true;
continue; // Don't get any key, just update our view
}
@@ -1401,6 +1403,7 @@ public:
HandleCharResult key_result = m_window_sp->HandleChar(ch);
switch (key_result) {
case eKeyHandled:
+ debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr);
m_update_screen = true;
break;
case eKeyNotHandled:
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index f7b3589..4d33d17 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -1634,18 +1634,12 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) {
bool CommandInterpreter::HandleCommand(const char *command_line,
LazyBool lazy_add_to_history,
- const ExecutionContext &override_context,
- CommandReturnObject &result) {
-
- OverrideExecutionContext(override_context);
- bool status = HandleCommand(command_line, lazy_add_to_history, result);
- RestoreExecutionContext();
- return status;
-}
+ CommandReturnObject &result,
+ ExecutionContext *override_context,
+ bool repeat_on_empty_command,
+ bool no_context_switching)
-bool CommandInterpreter::HandleCommand(const char *command_line,
- LazyBool lazy_add_to_history,
- CommandReturnObject &result) {
+{
std::string command_string(command_line);
std::string original_command_string(command_line);
@@ -1659,6 +1653,9 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "Handling command: %s.", command_line);
+ if (!no_context_switching)
+ UpdateExecutionContext(override_context);
+
if (WasInterrupted()) {
result.AppendError("interrupted");
result.SetStatus(eReturnStatusFailed);
@@ -1704,22 +1701,26 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
}
if (empty_command) {
- if (m_command_history.IsEmpty()) {
- result.AppendError("empty command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- command_line = m_repeat_command.c_str();
- command_string = command_line;
- original_command_string = command_line;
- if (m_repeat_command.empty()) {
- result.AppendError("No auto repeat.");
- result.SetStatus(eReturnStatusFailed);
- return false;
+ if (repeat_on_empty_command) {
+ if (m_command_history.IsEmpty()) {
+ result.AppendError("empty command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ command_line = m_repeat_command.c_str();
+ command_string = command_line;
+ original_command_string = command_line;
+ if (m_repeat_command.empty()) {
+ result.AppendError("No auto repeat.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ add_to_history = false;
+ } else {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
}
-
- add_to_history = false;
} else if (comment_command) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return true;
@@ -1856,6 +1857,8 @@ void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
void CommandInterpreter::HandleCompletion(CompletionRequest &request) {
+ UpdateExecutionContext(nullptr);
+
// Don't complete comments, and if the line we are completing is just the
// history repeat character, substitute the appropriate history line.
llvm::StringRef first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
@@ -1887,6 +1890,8 @@ CommandInterpreter::GetAutoSuggestionForCommand(llvm::StringRef line) {
return llvm::None;
}
+CommandInterpreter::~CommandInterpreter() {}
+
void CommandInterpreter::UpdatePrompt(llvm::StringRef new_prompt) {
EventSP prompt_change_event_sp(
new Event(eBroadcastBitResetPrompt, new EventDataBytes(new_prompt)));
@@ -2128,12 +2133,13 @@ void CommandInterpreter::SourceInitFile(FileSpec file,
// broadcasting of the commands back to any appropriate listener (see
// CommandObjectSource::Execute for more details).
const bool saved_batch = SetBatchCommandMode(true);
+ ExecutionContext *ctx = nullptr;
CommandInterpreterRunOptions options;
options.SetSilent(true);
options.SetPrintErrors(true);
options.SetStopOnError(false);
options.SetStopOnContinue(true);
- HandleCommandsFromFile(file, options, result);
+ HandleCommandsFromFile(file, ctx, options, result);
SetBatchCommandMode(saved_batch);
}
@@ -2224,8 +2230,7 @@ PlatformSP CommandInterpreter::GetPlatform(bool prefer_target_platform) {
}
bool CommandInterpreter::DidProcessStopAbnormally() const {
- auto exe_ctx = GetExecutionContext();
- TargetSP target_sp = exe_ctx.GetTargetSP();
+ TargetSP target_sp = m_debugger.GetTargetList().GetSelectedTarget();
if (!target_sp)
return false;
@@ -2263,19 +2268,9 @@ bool CommandInterpreter::DidProcessStopAbnormally() const {
return false;
}
-void
-CommandInterpreter::HandleCommands(const StringList &commands,
- const ExecutionContext &override_context,
- const CommandInterpreterRunOptions &options,
- CommandReturnObject &result) {
-
- OverrideExecutionContext(override_context);
- HandleCommands(commands, options, result);
- RestoreExecutionContext();
-}
-
void CommandInterpreter::HandleCommands(const StringList &commands,
- const CommandInterpreterRunOptions &options,
+ ExecutionContext *override_context,
+ CommandInterpreterRunOptions &options,
CommandReturnObject &result) {
size_t num_lines = commands.GetSize();
@@ -2285,6 +2280,13 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
bool old_async_execution = m_debugger.GetAsyncExecution();
+ // If we've been given an execution context, set it at the start, but don't
+ // keep resetting it or we will cause series of commands that change the
+ // context, then do an operation that relies on that context to fail.
+
+ if (override_context != nullptr)
+ UpdateExecutionContext(override_context);
+
if (!options.GetStopOnContinue()) {
m_debugger.SetAsyncExecution(false);
}
@@ -2303,12 +2305,19 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
CommandReturnObject tmp_result(m_debugger.GetUseColor());
tmp_result.SetInteractive(result.GetInteractive());
+ // If override_context is not NULL, pass no_context_switching = true for
+ // HandleCommand() since we updated our context already.
+
// We might call into a regex or alias command, in which case the
// add_to_history will get lost. This m_command_source_depth dingus is the
// way we turn off adding to the history in that case, so set it up here.
if (!options.GetAddToHistory())
m_command_source_depth++;
- bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result);
+ bool success =
+ HandleCommand(cmd, options.m_add_to_history, tmp_result,
+ nullptr, /* override_context */
+ true, /* repeat_on_empty_command */
+ override_context != nullptr /* no_context_switching */);
if (!options.GetAddToHistory())
m_command_source_depth--;
@@ -2409,15 +2418,8 @@ enum {
};
void CommandInterpreter::HandleCommandsFromFile(
- FileSpec &cmd_file, const ExecutionContext &context,
- const CommandInterpreterRunOptions &options, CommandReturnObject &result) {
- OverrideExecutionContext(context);
- HandleCommandsFromFile(cmd_file, options, result);
- RestoreExecutionContext();
-}
-
-void CommandInterpreter::HandleCommandsFromFile(FileSpec &cmd_file,
- const CommandInterpreterRunOptions &options, CommandReturnObject &result) {
+ FileSpec &cmd_file, ExecutionContext *context,
+ CommandInterpreterRunOptions &options, CommandReturnObject &result) {
if (!FileSystem::Instance().Exists(cmd_file)) {
result.AppendErrorWithFormat(
"Error reading commands from file %s - file not found.\n",
@@ -2718,26 +2720,24 @@ void CommandInterpreter::FindCommandsForApropos(llvm::StringRef search_word,
m_alias_dict);
}
-ExecutionContext CommandInterpreter::GetExecutionContext() const {
- return !m_overriden_exe_contexts.empty()
- ? m_overriden_exe_contexts.top()
- : m_debugger.GetSelectedExecutionContext();
-}
-
-void CommandInterpreter::OverrideExecutionContext(
- const ExecutionContext &override_context) {
- m_overriden_exe_contexts.push(override_context);
-}
-
-void CommandInterpreter::RestoreExecutionContext() {
- if (!m_overriden_exe_contexts.empty())
- m_overriden_exe_contexts.pop();
+void CommandInterpreter::UpdateExecutionContext(
+ ExecutionContext *override_context) {
+ if (override_context != nullptr) {
+ m_exe_ctx_ref = *override_context;
+ } else {
+ const bool adopt_selected = true;
+ m_exe_ctx_ref.SetTargetPtr(m_debugger.GetSelectedTarget().get(),
+ adopt_selected);
+ }
}
void CommandInterpreter::GetProcessOutput() {
- auto *process_ptr = GetExecutionContext().GetProcessPtr();
- if (process_ptr != nullptr)
- m_debugger.FlushProcessOutput(*process_ptr, /*flush_stdout*/ true,
+ TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
+ if (!target_sp)
+ return;
+
+ if (ProcessSP process_sp = target_sp->GetProcessSP())
+ m_debugger.FlushProcessOutput(*process_sp, /*flush_stdout*/ true,
/*flush_stderr*/ true);
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 5ce846e..bee87eb 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -3351,7 +3351,7 @@ Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,
// Force Async:
bool old_async = debugger.GetAsyncExecution();
debugger.SetAsyncExecution(true);
- debugger.GetCommandInterpreter().HandleCommands(GetCommands(), exc_ctx,
+ debugger.GetCommandInterpreter().HandleCommands(GetCommands(), &exc_ctx,
options, result);
debugger.SetAsyncExecution(old_async);
lldb::ReturnStatus status = result.GetStatus();