summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Interpreter')
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/Args.cpp33
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp337
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp53
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp6
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp13
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp39
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp4
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp80
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp6
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp8
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp8
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp10
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp37
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp4
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/Property.cpp15
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp12
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreterPython.cpp221
-rw-r--r--contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py2
27 files changed, 770 insertions, 136 deletions
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp b/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp
index 4831eaa..9393380 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp
@@ -685,7 +685,7 @@ Args::ParseOptions (Options &options)
}
}
// Call the callback with the option
- if (long_options_index >= 0)
+ if (long_options_index >= 0 && long_options[long_options_index].definition)
{
const OptionDefinition *def = long_options[long_options_index].definition;
CommandInterpreter &interpreter = options.GetInterpreter();
@@ -829,15 +829,18 @@ Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::add
options.SetTryAllThreads(true);
ExpressionResults expr_result = target->EvaluateExpression(s,
- exe_ctx->GetFramePtr(),
- valobj_sp,
- options);
+ exe_ctx->GetFramePtr(),
+ valobj_sp,
+ options);
bool success = false;
if (expr_result == eExpressionCompleted)
{
+ if (valobj_sp)
+ valobj_sp = valobj_sp->GetQualifiedRepresentationIfAvailable(valobj_sp->GetDynamicValueType(), true);
// Get the address to watch.
- addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
+ if (valobj_sp)
+ addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
if (success)
{
if (error_ptr)
@@ -966,6 +969,26 @@ Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr)
return fail_value;
}
+char
+Args::StringToChar(const char *s, char fail_value, bool *success_ptr)
+{
+ bool success = false;
+ char result = fail_value;
+
+ if (s)
+ {
+ size_t length = strlen(s);
+ if (length == 1)
+ {
+ success = true;
+ result = s[0];
+ }
+ }
+ if (success_ptr)
+ *success_ptr = success;
+ return result;
+}
+
const char *
Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update)
{
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp
index 56c8f8c..176a1fc 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -49,7 +49,9 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Timer.h"
+#ifndef LLDB_DISABLE_LIBEDIT
#include "lldb/Host/Editline.h"
+#endif
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
@@ -117,7 +119,11 @@ CommandInterpreter::CommandInterpreter
m_comment_char ('#'),
m_batch_command_mode (false),
m_truncation_warning(eNoTruncation),
- m_command_source_depth (0)
+ m_command_source_depth (0),
+ m_num_errors(0),
+ m_quit_requested(false),
+ m_stopped_for_crash(false)
+
{
debugger.SetScriptLanguage (script_language);
SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit");
@@ -333,7 +339,11 @@ CommandInterpreter::Initialize ()
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
#else
- ProcessAliasOptionsArgs (cmd_obj_sp, "--shell=" LLDB_DEFAULT_SHELL " --", alias_arguments_vector_sp);
+ std::string shell_option;
+ shell_option.append("--shell=");
+ shell_option.append(HostInfo::GetDefaultShell().GetPath());
+ shell_option.append(" --");
+ ProcessAliasOptionsArgs (cmd_obj_sp, shell_option.c_str(), alias_arguments_vector_sp);
#endif
AddAlias ("r", cmd_obj_sp);
AddAlias ("run", cmd_obj_sp);
@@ -414,6 +424,7 @@ CommandInterpreter::LoadCommandDictionary ()
m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this));
const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
+ {"^/([^/]+)/$", "breakpoint set --source-pattern-regexp '%1'"},
{"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"},
{"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
{"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
@@ -431,7 +442,8 @@ CommandInterpreter::LoadCommandDictionary ()
"_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
2,
CommandCompletions::eSymbolCompletion |
- CommandCompletions::eSourceFileCompletion));
+ CommandCompletions::eSourceFileCompletion,
+ false));
if (break_regex_cmd_ap.get())
{
@@ -458,7 +470,8 @@ CommandInterpreter::LoadCommandDictionary ()
"_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
2,
CommandCompletions::eSymbolCompletion |
- CommandCompletions::eSourceFileCompletion));
+ CommandCompletions::eSourceFileCompletion,
+ false));
if (tbreak_regex_cmd_ap.get())
{
@@ -469,6 +482,8 @@ CommandInterpreter::LoadCommandDictionary ()
char buffer[1024];
int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o");
assert (num_printed < 1024);
+ // Quiet unused variable warning for release builds.
+ (void) num_printed;
success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer);
if (!success)
break;
@@ -487,7 +502,9 @@ CommandInterpreter::LoadCommandDictionary ()
"_regexp-attach",
"Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.",
"_regexp-attach [<pid>]\n_regexp-attach [<process-name>]",
- 2));
+ 2,
+ 0,
+ false));
if (attach_regex_cmd_ap.get())
{
if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") &&
@@ -504,7 +521,10 @@ CommandInterpreter::LoadCommandDictionary ()
down_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-down",
"Go down \"n\" frames in the stack (1 frame by default).",
- "_regexp-down [n]", 2));
+ "_regexp-down [n]",
+ 2,
+ 0,
+ false));
if (down_regex_cmd_ap.get())
{
if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") &&
@@ -519,7 +539,10 @@ CommandInterpreter::LoadCommandDictionary ()
up_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-up",
"Go up \"n\" frames in the stack (1 frame by default).",
- "_regexp-up [n]", 2));
+ "_regexp-up [n]",
+ 2,
+ 0,
+ false));
if (up_regex_cmd_ap.get())
{
if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") &&
@@ -534,7 +557,10 @@ CommandInterpreter::LoadCommandDictionary ()
display_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-display",
"Add an expression evaluation stop-hook.",
- "_regexp-display expression", 2));
+ "_regexp-display expression",
+ 2,
+ 0,
+ false));
if (display_regex_cmd_ap.get())
{
if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\""))
@@ -548,7 +574,10 @@ CommandInterpreter::LoadCommandDictionary ()
undisplay_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-undisplay",
"Remove an expression evaluation stop-hook.",
- "_regexp-undisplay stop-hook-number", 2));
+ "_regexp-undisplay stop-hook-number",
+ 2,
+ 0,
+ false));
if (undisplay_regex_cmd_ap.get())
{
if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1"))
@@ -562,7 +591,10 @@ CommandInterpreter::LoadCommandDictionary ()
connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand (*this,
"gdb-remote",
"Connect to a remote GDB server. If no hostname is provided, localhost is assumed.",
- "gdb-remote [<hostname>:]<portnum>", 2));
+ "gdb-remote [<hostname>:]<portnum>",
+ 2,
+ 0,
+ false));
if (connect_gdb_remote_cmd_ap.get())
{
if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") &&
@@ -577,7 +609,10 @@ CommandInterpreter::LoadCommandDictionary ()
connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand (*this,
"kdp-remote",
"Connect to a remote KDP server. udp port 41139 is the default port number.",
- "kdp-remote <hostname>[:<portnum>]", 2));
+ "kdp-remote <hostname>[:<portnum>]",
+ 2,
+ 0,
+ false));
if (connect_kdp_remote_cmd_ap.get())
{
if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") &&
@@ -590,9 +625,12 @@ CommandInterpreter::LoadCommandDictionary ()
std::unique_ptr<CommandObjectRegexCommand>
bt_regex_cmd_ap(new CommandObjectRegexCommand (*this,
- "_regexp-bt",
- "Show a backtrace. An optional argument is accepted; if that argument is a number, it specifies the number of frames to display. If that argument is 'all', full backtraces of all threads are displayed.",
- "bt [<digit>|all]", 2));
+ "_regexp-bt",
+ "Show a backtrace. An optional argument is accepted; if that argument is a number, it specifies the number of frames to display. If that argument is 'all', full backtraces of all threads are displayed.",
+ "bt [<digit>|all]",
+ 2,
+ 0,
+ false));
if (bt_regex_cmd_ap.get())
{
// accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace
@@ -614,7 +652,8 @@ CommandInterpreter::LoadCommandDictionary ()
"Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.",
"_regexp-list [<line>]\n_regexp-list [<file>:<line>]\n_regexp-list [<file>:<line>]",
2,
- CommandCompletions::eSourceFileCompletion));
+ CommandCompletions::eSourceFileCompletion,
+ false));
if (list_regex_cmd_ap.get())
{
if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") &&
@@ -634,7 +673,10 @@ CommandInterpreter::LoadCommandDictionary ()
env_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-env",
"Implements a shortcut to viewing and setting environment variables.",
- "_regexp-env\n_regexp-env FOO=BAR", 2));
+ "_regexp-env\n_regexp-env FOO=BAR",
+ 2,
+ 0,
+ false));
if (env_regex_cmd_ap.get())
{
if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") &&
@@ -652,7 +694,10 @@ CommandInterpreter::LoadCommandDictionary ()
"_regexp-jump [<line>]\n"
"_regexp-jump [<+-lineoffset>]\n"
"_regexp-jump [<file>:<line>]\n"
- "_regexp-jump [*<addr>]\n", 2));
+ "_regexp-jump [*<addr>]\n",
+ 2,
+ 0,
+ false));
if (jump_regex_cmd_ap.get())
{
if (jump_regex_cmd_ap->AddRegexCommand("^\\*(.*)$", "thread jump --addr %1") &&
@@ -1043,6 +1088,22 @@ CommandInterpreter::RemoveAlias (const char *alias_name)
}
return false;
}
+
+bool
+CommandInterpreter::RemoveCommand (const char *cmd)
+{
+ auto pos = m_command_dict.find(cmd);
+ if (pos != m_command_dict.end())
+ {
+ if (pos->second->IsRemovable())
+ {
+ // Only regular expression objects or python commands are removable
+ m_command_dict.erase(pos);
+ return true;
+ }
+ }
+ return false;
+}
bool
CommandInterpreter::RemoveUser (const char *alias_name)
{
@@ -1448,7 +1509,7 @@ CommandInterpreter::PreprocessCommand (std::string &command)
// Get a dummy target to allow for calculator mode while processing backticks.
// This also helps break the infinite loop caused when target is null.
if (!target)
- target = Host::GetDummyTarget(GetDebugger()).get();
+ target = m_debugger.GetDummyTarget();
if (target)
{
ValueObjectSP expr_result_valobj_sp;
@@ -1462,13 +1523,15 @@ CommandInterpreter::PreprocessCommand (std::string &command)
options.SetTimeoutUsec(0);
ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
- exe_ctx.GetFramePtr(),
- expr_result_valobj_sp,
- options);
+ exe_ctx.GetFramePtr(),
+ expr_result_valobj_sp,
+ options);
if (expr_result == eExpressionCompleted)
{
Scalar scalar;
+ if (expr_result_valobj_sp)
+ expr_result_valobj_sp = expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(expr_result_valobj_sp->GetDynamicValueType(), true);
if (expr_result_valobj_sp->ResolveValue (scalar))
{
command.erase (start_backtick, end_backtick - start_backtick + 1);
@@ -2415,13 +2478,14 @@ CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
if (init_file.Exists())
{
const bool saved_batch = SetBatchCommandMode (true);
+ CommandInterpreterRunOptions options;
+ options.SetSilent (true);
+ options.SetStopOnError (false);
+ options.SetStopOnContinue (true);
+
HandleCommandsFromFile (init_file,
nullptr, // Execution context
- eLazyBoolYes, // Stop on continue
- eLazyBoolNo, // Stop on error
- eLazyBoolNo, // Don't echo commands
- eLazyBoolNo, // Don't print command output
- eLazyBoolNo, // Don't add the commands that are sourced into the history buffer
+ options,
result);
SetBatchCommandMode (saved_batch);
}
@@ -2451,12 +2515,8 @@ CommandInterpreter::GetPlatform (bool prefer_target_platform)
void
CommandInterpreter::HandleCommands (const StringList &commands,
- ExecutionContext *override_context,
- bool stop_on_continue,
- bool stop_on_error,
- bool echo_commands,
- bool print_results,
- LazyBool add_to_history,
+ ExecutionContext *override_context,
+ CommandInterpreterRunOptions &options,
CommandReturnObject &result)
{
size_t num_lines = commands.GetSize();
@@ -2472,7 +2532,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
if (override_context != nullptr)
UpdateExecutionContext (override_context);
- if (!stop_on_continue)
+ if (!options.GetStopOnContinue())
{
m_debugger.SetAsyncExecution (false);
}
@@ -2483,7 +2543,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
if (cmd[0] == '\0')
continue;
- if (echo_commands)
+ if (options.GetEchoCommands())
{
result.AppendMessageWithFormat ("%s %s\n",
m_debugger.GetPrompt(),
@@ -2496,16 +2556,16 @@ CommandInterpreter::HandleCommands (const StringList &commands,
// 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 (!add_to_history)
+ if (!options.GetAddToHistory())
m_command_source_depth++;
- bool success = HandleCommand(cmd, 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 (!add_to_history)
+ if (!options.GetAddToHistory())
m_command_source_depth--;
- if (print_results)
+ if (options.GetPrintResults())
{
if (tmp_result.Succeeded())
result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
@@ -2516,7 +2576,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
const char *error_msg = tmp_result.GetErrorData();
if (error_msg == nullptr || error_msg[0] == '\0')
error_msg = "<unknown error>.\n";
- if (stop_on_error)
+ if (options.GetStopOnError())
{
result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s",
(uint64_t)idx, cmd, error_msg);
@@ -2524,7 +2584,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
m_debugger.SetAsyncExecution (old_async_execution);
return;
}
- else if (print_results)
+ else if (options.GetPrintResults())
{
result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s",
(uint64_t)idx + 1,
@@ -2545,7 +2605,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
|| (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
{
- if (stop_on_continue)
+ if (options.GetStopOnContinue())
{
// If we caused the target to proceed, and we're going to stop in that case, set the
// status in our real result before returning. This is an error if the continue was not the
@@ -2562,6 +2622,42 @@ CommandInterpreter::HandleCommands (const StringList &commands,
return;
}
}
+
+ // Also check for "stop on crash here:
+ bool should_stop = false;
+ if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash())
+ {
+ TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
+ if (target_sp)
+ {
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ {
+ for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
+ {
+ StopReason reason = thread_sp->GetStopReason();
+ if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation)
+ {
+ should_stop = true;
+ break;
+ }
+ }
+ }
+ }
+ if (should_stop)
+ {
+ if (idx != num_lines - 1)
+ result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' stopped with a signal or exception.\n",
+ (uint64_t)idx + 1, cmd);
+ else
+ result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", (uint64_t)idx + 1, cmd);
+
+ result.SetStatus(tmp_result.GetStatus());
+ m_debugger.SetAsyncExecution (old_async_execution);
+
+ return;
+ }
+ }
}
@@ -2576,17 +2672,14 @@ enum {
eHandleCommandFlagStopOnContinue = (1u << 0),
eHandleCommandFlagStopOnError = (1u << 1),
eHandleCommandFlagEchoCommand = (1u << 2),
- eHandleCommandFlagPrintResult = (1u << 3)
+ eHandleCommandFlagPrintResult = (1u << 3),
+ eHandleCommandFlagStopOnCrash = (1u << 4)
};
void
CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
ExecutionContext *context,
- LazyBool stop_on_continue,
- LazyBool stop_on_error,
- LazyBool echo_command,
- LazyBool print_result,
- LazyBool add_to_history,
+ CommandInterpreterRunOptions &options,
CommandReturnObject &result)
{
if (cmd_file.Exists())
@@ -2602,7 +2695,7 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
uint32_t flags = 0;
- if (stop_on_continue == eLazyBoolCalculate)
+ if (options.m_stop_on_continue == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@@ -2614,12 +2707,12 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagStopOnContinue;
}
}
- else if (stop_on_continue == eLazyBoolYes)
+ else if (options.m_stop_on_continue == eLazyBoolYes)
{
flags |= eHandleCommandFlagStopOnContinue;
}
- if (stop_on_error == eLazyBoolCalculate)
+ if (options.m_stop_on_error == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@@ -2631,12 +2724,25 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagStopOnError;
}
}
- else if (stop_on_error == eLazyBoolYes)
+ else if (options.m_stop_on_error == eLazyBoolYes)
{
flags |= eHandleCommandFlagStopOnError;
}
- if (echo_command == eLazyBoolCalculate)
+ if (options.GetStopOnCrash())
+ {
+ if (m_command_source_flags.empty())
+ {
+ // Echo command by default
+ flags |= eHandleCommandFlagStopOnCrash;
+ }
+ else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash)
+ {
+ flags |= eHandleCommandFlagStopOnCrash;
+ }
+ }
+
+ if (options.m_echo_commands == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@@ -2648,12 +2754,12 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagEchoCommand;
}
}
- else if (echo_command == eLazyBoolYes)
+ else if (options.m_echo_commands == eLazyBoolYes)
{
flags |= eHandleCommandFlagEchoCommand;
}
- if (print_result == eLazyBoolCalculate)
+ if (options.m_print_results == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@@ -2665,7 +2771,7 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagPrintResult;
}
}
- else if (print_result == eLazyBoolYes)
+ else if (options.m_print_results == eLazyBoolYes)
{
flags |= eHandleCommandFlagPrintResult;
}
@@ -2680,18 +2786,21 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
lldb::StreamFileSP empty_stream_sp;
m_command_source_flags.push_back(flags);
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
+ IOHandler::Type::CommandInterpreter,
input_file_sp,
empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream
empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream
flags,
nullptr, // Pass in NULL for "editline_name" so no history is saved, or written
debugger.GetPrompt(),
+ NULL,
false, // Not multi-line
+ debugger.GetUseColor(),
0,
*this));
const bool old_async_execution = debugger.GetAsyncExecution();
- // Set synchronous execution if we not stopping when we continue
+ // Set synchronous execution if we are not stopping on continue
if ((flags & eHandleCommandFlagStopOnContinue) == 0)
debugger.SetAsyncExecution (false);
@@ -2715,7 +2824,7 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
else
{
result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n",
- cmd_file.GetFilename().AsCString());
+ cmd_file.GetFilename().AsCString("<Unknown>"));
result.SetStatus (eReturnStatusFailed);
return;
}
@@ -3056,14 +3165,46 @@ CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &
break;
case eReturnStatusFailed:
+ m_num_errors++;
if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError))
io_handler.SetIsDone(true);
break;
case eReturnStatusQuit:
+ m_quit_requested = true;
io_handler.SetIsDone(true);
break;
}
+
+ // Finally, if we're going to stop on crash, check that here:
+ if (!m_quit_requested
+ && result.GetDidChangeProcessState()
+ && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash))
+ {
+ bool should_stop = false;
+ TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
+ if (target_sp)
+ {
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ {
+ for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
+ {
+ StopReason reason = thread_sp->GetStopReason();
+ if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation)
+ {
+ should_stop = true;
+ break;
+ }
+ }
+ }
+ }
+ if (should_stop)
+ {
+ io_handler.SetIsDone(true);
+ m_stopped_for_crash = true;
+ }
+ }
}
bool
@@ -3092,9 +3233,12 @@ CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt,
{
Debugger &debugger = GetDebugger();
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
+ IOHandler::Type::CommandList,
"lldb", // Name of input reader for history
prompt, // Prompt
+ NULL, // Continuation prompt
true, // Get multiple lines
+ debugger.GetUseColor(),
0, // Don't show line numbers
delegate)); // IOHandlerDelegate
@@ -3118,9 +3262,12 @@ CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt,
{
Debugger &debugger = GetDebugger();
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
+ IOHandler::Type::PythonCode,
"lldb-python", // Name of input reader for history
prompt, // Prompt
+ NULL, // Continuation prompt
true, // Get multiple lines
+ debugger.GetUseColor(),
0, // Don't show line numbers
delegate)); // IOHandlerDelegate
@@ -3141,28 +3288,64 @@ CommandInterpreter::IsActive ()
return m_debugger.IsTopIOHandler (m_command_io_handler_sp);
}
-void
-CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
- bool spawn_thread)
+lldb::IOHandlerSP
+CommandInterpreter::GetIOHandler(bool force_create, CommandInterpreterRunOptions *options)
{
- // Only get one line at a time
- const bool multiple_lines = false;
-
// Always re-create the IOHandlerEditline in case the input
// changed. The old instance might have had a non-interactive
// input and now it does or vice versa.
- m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
- m_debugger.GetInputFile(),
- m_debugger.GetOutputFile(),
- m_debugger.GetErrorFile(),
- eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult,
- "lldb",
- m_debugger.GetPrompt(),
- multiple_lines,
- 0, // Don't show line numbers
- *this));
-
- m_debugger.PushIOHandler(m_command_io_handler_sp);
+ if (force_create || !m_command_io_handler_sp)
+ {
+ // Always re-create the IOHandlerEditline in case the input
+ // changed. The old instance might have had a non-interactive
+ // input and now it does or vice versa.
+ uint32_t flags = 0;
+
+ if (options)
+ {
+ if (options->m_stop_on_continue == eLazyBoolYes)
+ flags |= eHandleCommandFlagStopOnContinue;
+ if (options->m_stop_on_error == eLazyBoolYes)
+ flags |= eHandleCommandFlagStopOnError;
+ if (options->m_stop_on_crash == eLazyBoolYes)
+ flags |= eHandleCommandFlagStopOnCrash;
+ if (options->m_echo_commands != eLazyBoolNo)
+ flags |= eHandleCommandFlagEchoCommand;
+ if (options->m_print_results != eLazyBoolNo)
+ flags |= eHandleCommandFlagPrintResult;
+ }
+ else
+ {
+ flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult;
+ }
+
+ m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
+ IOHandler::Type::CommandInterpreter,
+ m_debugger.GetInputFile(),
+ m_debugger.GetOutputFile(),
+ m_debugger.GetErrorFile(),
+ flags,
+ "lldb",
+ m_debugger.GetPrompt(),
+ NULL, // Continuation prompt
+ false, // Don't enable multiple line input, just single line commands
+ m_debugger.GetUseColor(),
+ 0, // Don't show line numbers
+ *this));
+ }
+ return m_command_io_handler_sp;
+}
+
+void
+CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
+ bool spawn_thread,
+ CommandInterpreterRunOptions &options)
+{
+ // Always re-create the command intepreter when we run it in case
+ // any file handles have changed.
+ bool force_create = true;
+ m_debugger.PushIOHandler(GetIOHandler(force_create, &options));
+ m_stopped_for_crash = false;
if (auto_handle_events)
m_debugger.StartEventHandlerThread();
@@ -3174,10 +3357,10 @@ CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
else
{
m_debugger.ExecuteIOHanders();
-
+
if (auto_handle_events)
m_debugger.StopEventHandlerThread();
}
-
+
}
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp
index 3fdbf99..753e720 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp
@@ -49,7 +49,7 @@ CommandObject::CommandObject
uint32_t flags
) :
m_interpreter (interpreter),
- m_cmd_name (name),
+ m_cmd_name (name ? name : ""),
m_cmd_help_short (),
m_cmd_help_long (),
m_cmd_syntax (),
@@ -236,19 +236,34 @@ CommandObject::CheckRequirements (CommandReturnObject &result)
if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
{
- result.AppendError (GetInvalidProcessDescription());
+ if (!m_exe_ctx.HasTargetScope())
+ result.AppendError (GetInvalidTargetDescription());
+ else
+ result.AppendError (GetInvalidProcessDescription());
return false;
}
if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
{
- result.AppendError (GetInvalidThreadDescription());
+ if (!m_exe_ctx.HasTargetScope())
+ result.AppendError (GetInvalidTargetDescription());
+ else if (!m_exe_ctx.HasProcessScope())
+ result.AppendError (GetInvalidProcessDescription());
+ else
+ result.AppendError (GetInvalidThreadDescription());
return false;
}
if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
{
- result.AppendError (GetInvalidFrameDescription());
+ if (!m_exe_ctx.HasTargetScope())
+ result.AppendError (GetInvalidTargetDescription());
+ else if (!m_exe_ctx.HasProcessScope())
+ result.AppendError (GetInvalidProcessDescription());
+ else if (!m_exe_ctx.HasThreadScope())
+ result.AppendError (GetInvalidThreadDescription());
+ else
+ result.AppendError (GetInvalidFrameDescription());
return false;
}
@@ -733,6 +748,22 @@ BreakpointIDRangeHelpTextCallback ()
}
static const char *
+BreakpointNameHelpTextCallback ()
+{
+ return "A name that can be added to a breakpoint when it is created, or later "
+ "on with the \"breakpoint name add\" command. "
+ "Breakpoint names can be used to specify breakpoints in all the places breakpoint ID's "
+ "and breakpoint ID ranges can be used. As such they provide a convenient way to group breakpoints, "
+ "and to operate on breakpoints you create without having to track the breakpoint number. "
+ "Note, the attributes you set when using a breakpoint name in a breakpoint command don't "
+ "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that name. Future breakpoints "
+ "tagged with that name will not pick up the attributes previously given using that name. "
+ "In order to distinguish breakpoint names from breakpoint ID's and ranges, "
+ "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\". "
+ "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations.";
+}
+
+static const char *
GDBFormatHelpTextCallback ()
{
return "A GDB format consists of a repeat count, a format letter and a size letter. "
@@ -1003,6 +1034,18 @@ CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType
return nullptr;
}
+Target *
+CommandObject::GetDummyTarget()
+{
+ return m_interpreter.GetDebugger().GetDummyTarget();
+}
+
+Target *
+CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy)
+{
+ return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
+}
+
bool
CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
{
@@ -1085,6 +1128,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" },
{ eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr },
{ eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr },
+ { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
{ eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." },
{ eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." },
{ eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." },
@@ -1103,6 +1147,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function." },
{ eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function or symbol." },
{ eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, nullptr },
+ { eArgTypeHelpText, "help-text", CommandCompletions::eNoCompletion, { nullptr, false }, "Text to be used as help for some other entity in LLDB" },
{ eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." },
{ eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
{ eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." },
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp
index d27320d..efc7c33 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp
@@ -31,12 +31,14 @@ CommandObjectRegexCommand::CommandObjectRegexCommand
const char *help,
const char *syntax,
uint32_t max_matches,
- uint32_t completion_type_mask
+ uint32_t completion_type_mask,
+ bool is_removable
) :
CommandObjectRaw (interpreter, name, help, syntax),
m_max_matches (max_matches),
m_completion_type_mask (completion_type_mask),
- m_entries ()
+ m_entries (),
+ m_is_removable (is_removable)
{
}
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp
index 9ffd5f0..7e5e124 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp
@@ -33,7 +33,7 @@ OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter,
if (!m_platform_name.empty())
{
- platform_sp = Platform::Create (m_platform_name.c_str(), error);
+ platform_sp = Platform::Create (ConstString(m_platform_name.c_str()), error);
if (platform_sp)
{
if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index 125e5fb..b6c63fa 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -45,6 +45,7 @@ g_option_table[] =
{ LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the depth at which omitting summary information stops (default is 1)."},
{ LLDB_OPT_SET_1, false, "raw-output", 'R', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use formatting options."},
{ LLDB_OPT_SET_1, false, "show-all-children", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore the upper bound on the number of children to show."},
+ { LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show results of type validators."},
{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
@@ -115,6 +116,13 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter,
if (!success)
error.SetErrorStringWithFormat("invalid synthetic-type '%s'", option_arg);
break;
+
+ case 'V':
+ run_validator = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid validate '%s'", option_arg);
+ break;
+
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -137,6 +145,7 @@ OptionGroupValueObjectDisplay::OptionParsingStarting (CommandInterpreter &interp
use_synth = true;
be_raw = false;
ignore_cap = false;
+ run_validator = false;
Target *target = interpreter.GetExecutionContext().GetTargetPtr();
if (target != nullptr)
@@ -176,7 +185,9 @@ OptionGroupValueObjectDisplay::GetAsDumpOptions (LanguageRuntimeDescriptionDispl
.SetHideValue(use_objc);
if (be_raw)
- options.SetRawDisplay(true);
+ options.SetRawDisplay();
+
+ options.SetRunValidator(run_validator);
return options;
}
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp
index bc1e1c4..a08a612 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp
@@ -71,6 +71,21 @@ OptionValue::GetAsBoolean () const
return nullptr;
}
+const OptionValueChar *
+OptionValue::GetAsChar () const
+{
+ if (GetType () == OptionValue::eTypeChar)
+ return static_cast<const OptionValueChar *>(this);
+ return nullptr;
+}
+
+OptionValueChar *
+OptionValue::GetAsChar ()
+{
+ if (GetType () == OptionValue::eTypeChar)
+ return static_cast<OptionValueChar *>(this);
+ return nullptr;
+}
OptionValueFileSpec *
OptionValue::GetAsFileSpec ()
@@ -342,6 +357,27 @@ OptionValue::SetBooleanValue (bool new_value)
return false;
}
+char
+OptionValue::GetCharValue(char fail_value) const
+{
+ const OptionValueChar *option_value = GetAsChar();
+ if (option_value)
+ return option_value->GetCurrentValue();
+ return fail_value;
+}
+
+char
+OptionValue::SetCharValue(char new_value)
+{
+ OptionValueChar *option_value = GetAsChar();
+ if (option_value)
+ {
+ option_value->SetCurrentValue(new_value);
+ return true;
+ }
+ return false;
+}
+
int64_t
OptionValue::GetEnumerationValue (int64_t fail_value) const
{
@@ -520,6 +556,8 @@ OptionValue::GetBuiltinTypeAsCString (Type t)
case eTypeArgs: return "arguments";
case eTypeArray: return "array";
case eTypeBoolean: return "boolean";
+ case eTypeChar:
+ return "char";
case eTypeDictionary: return "dictionary";
case eTypeEnum: return "enum";
case eTypeFileSpec: return "file";
@@ -547,6 +585,7 @@ OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t
{
case 1u << eTypeArch: value_sp.reset(new OptionValueArch()); break;
case 1u << eTypeBoolean: value_sp.reset(new OptionValueBoolean(false)); break;
+ case 1u << eTypeChar: value_sp.reset(new OptionValueChar('\0')); break;
case 1u << eTypeFileSpec: value_sp.reset(new OptionValueFileSpec()); break;
case 1u << eTypeFormat: value_sp.reset(new OptionValueFormat(eFormatInvalid)); break;
case 1u << eTypeSInt64: value_sp.reset(new OptionValueSInt64()); break;
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp
index 6d283d6..7df1492 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp
@@ -50,6 +50,7 @@ OptionValueArch::SetValueFromCString (const char *value_cstr, VarSetOperationTyp
{
case eVarSetOperationClear:
Clear();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -57,7 +58,10 @@ OptionValueArch::SetValueFromCString (const char *value_cstr, VarSetOperationTyp
if (value_cstr && value_cstr[0])
{
if (m_current_value.SetTriple (value_cstr))
+ {
m_value_was_set = true;
+ NotifyValueChanged();
+ }
else
error.SetErrorStringWithFormat("unsupported architecture '%s'", value_cstr);
}
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp
index 769aadd..c0d48c1 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp
@@ -53,6 +53,7 @@ OptionValueArray::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint
break;
case eTypeBoolean:
+ case eTypeChar:
case eTypeEnum:
case eTypeFileSpec:
case eTypeFormat:
@@ -75,6 +76,7 @@ Error
OptionValueArray::SetValueFromCString (const char *value, VarSetOperationType op)
{
Args args(value);
+ NotifyValueChanged();
return SetArgs (args, op);
}
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp
index bf153a1..71cc2af 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp
@@ -45,6 +45,7 @@ OptionValueBoolean::SetValueFromCString (const char *value_cstr,
{
case eVarSetOperationClear:
Clear();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -56,6 +57,7 @@ OptionValueBoolean::SetValueFromCString (const char *value_cstr,
{
m_value_was_set = true;
m_current_value = value;
+ NotifyValueChanged();
}
else
{
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp
new file mode 100644
index 0000000..7a01353
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp
@@ -0,0 +1,80 @@
+//===-- OptionValueChar.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueChar.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Interpreter/Args.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueChar::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+ if (dump_mask & eDumpOptionType)
+ strm.Printf ("(%s)", GetTypeAsCString ());
+
+ if (dump_mask & eDumpOptionValue)
+ {
+ if (dump_mask & eDumpOptionType)
+ strm.PutCString (" = ");
+ if (m_current_value != '\0')
+ strm.PutChar(m_current_value);
+ else
+ strm.PutCString("(null)");
+ }
+}
+
+Error
+OptionValueChar::SetValueFromCString (const char *value_cstr,
+ VarSetOperationType op)
+{
+ Error error;
+ switch (op)
+ {
+ case eVarSetOperationClear:
+ Clear();
+ break;
+
+ case eVarSetOperationReplace:
+ case eVarSetOperationAssign:
+ {
+ bool success = false;
+ char char_value = Args::StringToChar(value_cstr, '\0', &success);
+ if (success)
+ {
+ m_current_value = char_value;
+ m_value_was_set = true;
+ }
+ else
+ error.SetErrorStringWithFormat("'%s' cannot be longer than 1 character", value_cstr);
+ }
+ break;
+
+ default:
+ error = OptionValue::SetValueFromCString (value_cstr, op);
+ break;
+ }
+ return error;
+}
+
+lldb::OptionValueSP
+OptionValueChar::DeepCopy () const
+{
+ return OptionValueSP(new OptionValueChar(*this));
+}
+
+
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp
index b560937..e5299f8 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp
@@ -64,6 +64,7 @@ OptionValueDictionary::DumpValue (const ExecutionContext *exe_ctx, Stream &strm,
break;
case eTypeBoolean:
+ case eTypeChar:
case eTypeEnum:
case eTypeFileSpec:
case eTypeFormat:
@@ -220,7 +221,10 @@ Error
OptionValueDictionary::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
{
Args args(value_cstr);
- return SetArgs (args, op);
+ Error error = SetArgs (args, op);
+ if (error.Success())
+ NotifyValueChanged();
+ return error;
}
lldb::OptionValueSP
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp
index 7aceac9..dbaeb18 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp
@@ -62,6 +62,7 @@ OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationT
{
case eVarSetOperationClear:
Clear ();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -73,6 +74,7 @@ OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationT
if (enumerator_entry)
{
m_current_value = enumerator_entry->value.value;
+ NotifyValueChanged();
}
else
{
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp
index c8aaade..3f46698 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp
@@ -78,6 +78,7 @@ OptionValueFileSpec::SetValueFromCString (const char *value_cstr,
{
case eVarSetOperationClear:
Clear ();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -100,6 +101,7 @@ OptionValueFileSpec::SetValueFromCString (const char *value_cstr,
m_value_was_set = true;
m_current_value.SetFile(filepath.c_str(), true);
m_data_sp.reset();
+ NotifyValueChanged();
}
else
{
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp
index e493c70..7150ad4 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp
@@ -51,6 +51,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
{
case eVarSetOperationClear:
Clear ();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -72,6 +73,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
else
m_current_value.Append(file);
}
+ NotifyValueChanged();
}
}
else
@@ -94,6 +96,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
FileSpec file (args.GetArgumentAtIndex(i), false);
m_current_value.Append(file);
}
+ NotifyValueChanged();
}
else
{
@@ -120,6 +123,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
FileSpec file (args.GetArgumentAtIndex(i), false);
m_current_value.Insert (idx, file);
}
+ NotifyValueChanged();
}
}
else
@@ -155,6 +159,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
m_current_value.Remove (j);
}
}
+ NotifyValueChanged();
}
else
{
@@ -172,9 +177,6 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
break;
}
return error;
-
- m_value_was_set = true;
- return Error();
}
lldb::OptionValueSP
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp
index 296dd98..d91f10b 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp
@@ -43,6 +43,7 @@ OptionValueFormat::SetValueFromCString (const char *value_cstr, VarSetOperationT
{
case eVarSetOperationClear:
Clear();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -54,6 +55,7 @@ OptionValueFormat::SetValueFromCString (const char *value_cstr, VarSetOperationT
{
m_value_was_set = true;
m_current_value = new_format;
+ NotifyValueChanged();
}
}
break;
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp
index 88a0eb7..56f2ecf 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp
@@ -43,6 +43,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
{
case eVarSetOperationClear:
Clear ();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -64,6 +65,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
if (!m_path_mappings.Replace (a, b, idx, m_notify_changes))
m_path_mappings.Append(a, b, m_notify_changes);
}
+ NotifyValueChanged();
}
}
else
@@ -97,6 +99,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
m_path_mappings.Append(a, b, m_notify_changes);
m_value_was_set = true;
}
+ NotifyValueChanged();
}
break;
@@ -121,6 +124,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
ConstString b(args.GetArgumentAtIndex(i+1));
m_path_mappings.Insert (a, b, idx, m_notify_changes);
}
+ NotifyValueChanged();
}
}
else
@@ -156,6 +160,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
m_path_mappings.Remove (j, m_notify_changes);
}
}
+ NotifyValueChanged();
}
else
{
@@ -173,9 +178,6 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
break;
}
return error;
-
- m_value_was_set = true;
- return Error();
}
lldb::OptionValueSP
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp
index 0497ee1..6ec2aa5 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp
@@ -81,6 +81,16 @@ OptionValueProperties::Initialize (const PropertyDefinition *defs)
}
void
+OptionValueProperties::SetValueChangedCallback (uint32_t property_idx,
+ OptionValueChangedCallback callback,
+ void *baton)
+{
+ Property *property = ProtectedGetPropertyAtIndex (property_idx);
+ if (property)
+ property->SetValueChangedCallback (callback, baton);
+}
+
+void
OptionValueProperties::AppendProperty(const ConstString &name,
const ConstString &desc,
bool is_global,
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp
index f1ba0ed..f51cf02 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp
@@ -57,6 +57,7 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr,
case eVarSetOperationClear:
Clear();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -64,6 +65,7 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr,
if (m_regex.Compile (value_cstr, m_regex.GetCompileFlags()))
{
m_value_was_set = true;
+ NotifyValueChanged();
}
else
{
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp
index 04bf930..1827cc1 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp
@@ -44,6 +44,7 @@ OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
{
case eVarSetOperationClear:
Clear();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -57,6 +58,7 @@ OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
{
m_value_was_set = true;
m_current_value = value;
+ NotifyValueChanged();
}
else
error.SetErrorStringWithFormat ("%" PRIi64 " is out of range, valid values must be between %" PRIi64 " and %" PRIi64 ".",
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp
index df047bd..a1b80d8 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp
@@ -94,30 +94,32 @@ OptionValueString::SetValueFromCString (const char *value_cstr,
case eVarSetOperationAppend:
{
- std::string new_value(m_current_value);
- if (value_cstr && value_cstr[0])
- {
- if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
+ std::string new_value(m_current_value);
+ if (value_cstr && value_cstr[0])
{
- std::string str;
- Args::EncodeEscapeSequences (value_cstr, str);
- new_value.append(str);
+ if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
+ {
+ std::string str;
+ Args::EncodeEscapeSequences (value_cstr, str);
+ new_value.append(str);
+ }
+ else
+ new_value.append(value_cstr);
}
- else
- new_value.append(value_cstr);
- }
- if (m_validator)
- {
- error = m_validator(new_value.c_str(),m_validator_baton);
- if (error.Fail())
- return error;
- }
- m_current_value.assign(new_value);
+ if (m_validator)
+ {
+ error = m_validator(new_value.c_str(),m_validator_baton);
+ if (error.Fail())
+ return error;
+ }
+ m_current_value.assign(new_value);
+ NotifyValueChanged();
}
break;
case eVarSetOperationClear:
Clear ();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -137,6 +139,7 @@ OptionValueString::SetValueFromCString (const char *value_cstr,
{
SetCurrentValue (value_cstr);
}
+ NotifyValueChanged();
break;
}
return error;
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp
index 56b3a1c..3e12c03 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp
@@ -51,6 +51,7 @@ OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
{
case eVarSetOperationClear:
Clear ();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -62,6 +63,7 @@ OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
{
m_value_was_set = true;
m_current_value = value;
+ NotifyValueChanged();
}
else
{
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp
index 0141911..c228cf6 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp
@@ -45,6 +45,7 @@ OptionValueUUID::SetValueFromCString (const char *value_cstr,
{
case eVarSetOperationClear:
Clear();
+ NotifyValueChanged();
break;
case eVarSetOperationReplace:
@@ -53,7 +54,10 @@ OptionValueUUID::SetValueFromCString (const char *value_cstr,
if (m_uuid.SetFromCString(value_cstr) == 0)
error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr);
else
+ {
m_value_was_set = true;
+ NotifyValueChanged();
+ }
}
break;
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp b/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp
index 4937626..7f7219f 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp
@@ -60,7 +60,11 @@ Property::Property (const PropertyDefinition &definition) :
else
m_value_sp.reset (new OptionValueBoolean(definition.default_uint_value != 0));
break;
-
+
+ case OptionValue::eTypeChar:
+ m_value_sp.reset(new OptionValueChar(Args::StringToChar(definition.default_cstr_value, '\0', nullptr)));
+ break;
+
case OptionValue::eTypeDictionary:
// "definition.default_uint_value" is always a OptionValue::Type
m_value_sp.reset (new OptionValueDictionary(OptionValue::ConvertTypeToMask((OptionValue::Type)definition.default_uint_value)));
@@ -273,3 +277,12 @@ Property::DumpDescription (CommandInterpreter &interpreter,
}
}
+
+void
+Property::SetValueChangedCallback (OptionValueChangedCallback callback, void *baton)
+{
+ if (m_value_sp)
+ m_value_sp->SetValueChangedCallback (callback, baton);
+}
+
+
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp b/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp
index b6c46f8..45e3b44 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -124,6 +124,7 @@ ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_call
SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
SWIGPythonUpdateSynthProviderInstance swig_update_provider,
SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
+ SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
SWIGPythonCallCommand swig_call_command,
SWIGPythonCallModuleInit swig_call_module_init,
SWIGPythonCreateOSPlugin swig_create_os_plugin,
@@ -131,7 +132,10 @@ ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_call
SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
- SWIGPython_GetDynamicSetting swig_plugin_get)
+ SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
+ SWIGPython_GetDynamicSetting swig_plugin_get,
+ SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
+ SWIGPythonCallThreadPlan swig_call_thread_plan)
{
#ifndef LLDB_DISABLE_PYTHON
ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
@@ -146,6 +150,7 @@ ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_call
swig_get_valobj_sp_from_sbvalue,
swig_update_provider,
swig_mighthavechildren_provider,
+ swig_getvalue_provider,
swig_call_command,
swig_call_module_init,
swig_create_os_plugin,
@@ -153,6 +158,9 @@ ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_call
swig_run_script_keyword_thread,
swig_run_script_keyword_target,
swig_run_script_keyword_frame,
- swig_plugin_get);
+ swig_run_script_keyword_value,
+ swig_plugin_get,
+ swig_thread_plan_script,
+ swig_call_thread_plan);
#endif // #ifndef LLDB_DISABLE_PYTHON
}
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreterPython.cpp
index 1b24fea..ab15107 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -28,15 +28,20 @@
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/WatchpointOptions.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+#if defined(_WIN32)
+#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
+#endif
using namespace lldb;
using namespace lldb_private;
@@ -54,6 +59,7 @@ static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue
static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
+static ScriptInterpreter::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr;
static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
@@ -61,7 +67,10 @@ static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyw
static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
+static ScriptInterpreter::SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr;
static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
+static ScriptInterpreter::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr;
+static ScriptInterpreter::SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr;
static std::string
ReadPythonBacktrace (PyObject* py_backtrace);
@@ -435,19 +444,23 @@ ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
if (in == nullptr || out == nullptr || err == nullptr)
m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid (in_sp, out_sp, err_sp);
- if (in == nullptr && in_sp && (on_entry_flags & Locker::NoSTDIN) == 0)
- in = in_sp->GetFile().GetStream();
- if (in)
- {
- m_saved_stdin.Reset(sys_module_dict.GetItemForKey("stdin"));
+ m_saved_stdin.Reset();
- PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", nullptr);
- sys_module_dict.SetItemForKey ("stdin", new_file);
- Py_DECREF (new_file);
+ if ((on_entry_flags & Locker::NoSTDIN) == 0)
+ {
+ // STDIN is enabled
+ if (in == nullptr && in_sp)
+ in = in_sp->GetFile().GetStream();
+ if (in)
+ {
+ m_saved_stdin.Reset(sys_module_dict.GetItemForKey("stdin"));
+ // This call can deadlock your process if the file is locked
+ PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", nullptr);
+ sys_module_dict.SetItemForKey ("stdin", new_file);
+ Py_DECREF (new_file);
+ }
}
- else
- m_saved_stdin.Reset();
-
+
if (out == nullptr && out_sp)
out = out_sp->GetFile().GetStream();
if (out)
@@ -594,9 +607,16 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec
// Set output to a temporary file so we can forward the results on to the result object
Pipe pipe;
- if (pipe.Open())
+ Error pipe_result = pipe.CreateNew(false);
+ if (pipe_result.Success())
{
+#if defined(_WIN32)
+ lldb::file_t read_file = pipe.GetReadNativeHandle();
+ pipe.ReleaseReadFileDescriptor();
+ std::unique_ptr<ConnectionGenericFile> conn_ap(new ConnectionGenericFile(read_file, true));
+#else
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true));
+#endif
if (conn_ap->IsConnected())
{
output_comm.SetConnection(conn_ap.release());
@@ -632,7 +652,8 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec
Locker locker(this,
ScriptInterpreterPython::Locker::AcquireLock |
ScriptInterpreterPython::Locker::InitSession |
- (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) |
+ ((result && result->GetInteractive()) ? 0: Locker::NoSTDIN),
ScriptInterpreterPython::Locker::FreeAcquiredLock |
ScriptInterpreterPython::Locker::TearDownSession,
in_file,
@@ -708,7 +729,7 @@ public:
IOHandlerPythonInterpreter (Debugger &debugger,
ScriptInterpreterPython *python) :
- IOHandler (debugger),
+ IOHandler (debugger, IOHandler::Type::PythonInterpreter),
m_python(python)
{
@@ -1617,6 +1638,87 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
}
lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::CreateScriptedThreadPlan (const char *class_name,
+ lldb::ThreadPlanSP thread_plan_sp)
+{
+ if (class_name == nullptr || class_name[0] == '\0')
+ return lldb::ScriptInterpreterObjectSP();
+
+ if (!thread_plan_sp.get())
+ return lldb::ScriptInterpreterObjectSP();
+
+ Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
+ ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter = static_cast<ScriptInterpreterPython *>(script_interpreter);
+
+ if (!script_interpreter)
+ return lldb::ScriptInterpreterObjectSP();
+
+ void* ret_val;
+
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ ret_val = g_swig_thread_plan_script (class_name,
+ python_interpreter->m_dictionary_name.c_str(),
+ thread_plan_sp);
+ }
+
+ return MakeScriptObject(ret_val);
+}
+
+bool
+ScriptInterpreterPython::ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp,
+ Event *event,
+ bool &script_error)
+{
+ bool explains_stop = true;
+ if (implementor_sp)
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ explains_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "explains_stop", event, script_error);
+ if (script_error)
+ return true;
+ }
+ return explains_stop;
+}
+
+bool
+ScriptInterpreterPython::ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp,
+ Event *event,
+ bool &script_error)
+{
+ bool should_stop = true;
+ if (implementor_sp)
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ should_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_stop", event, script_error);
+ if (script_error)
+ return true;
+ }
+ return should_stop;
+}
+
+lldb::StateType
+ScriptInterpreterPython::ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp,
+ bool &script_error)
+{
+ bool should_step = false;
+ if (implementor_sp)
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ should_step = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_step", NULL, script_error);
+ if (script_error)
+ should_step = true;
+ }
+ if (should_step)
+ return lldb::eStateStepping;
+ else
+ return lldb::eStateRunning;
+}
+
+
+lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::LoadPluginModule (const FileSpec& file_spec,
lldb_private::Error& error)
{
@@ -1759,6 +1861,7 @@ bool
ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
lldb::ValueObjectSP valobj,
lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
+ const TypeSummaryOptions& options,
std::string& retval)
{
@@ -1780,11 +1883,14 @@ ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
{
+ TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
+
Timer scoped_timer ("g_swig_typescript_callback","g_swig_typescript_callback");
ret_val = g_swig_typescript_callback (python_function_name,
GetSessionDictionary().get(),
valobj,
&new_callee,
+ options_sp,
retval);
}
}
@@ -2056,6 +2162,42 @@ ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::Scr
return ret_val;
}
+lldb::ValueObjectSP
+ScriptInterpreterPython::GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor_sp)
+{
+ lldb::ValueObjectSP ret_val(nullptr);
+
+ if (!implementor_sp)
+ return ret_val;
+
+ void* implementor = implementor_sp->GetObject();
+
+ if (!implementor)
+ return ret_val;
+
+ if (!g_swig_getvalue_provider || !g_swig_cast_to_sbvalue || !g_swig_get_valobj_sp_from_sbvalue)
+ return ret_val;
+
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ void* child_ptr = g_swig_getvalue_provider (implementor);
+ if (child_ptr != nullptr && child_ptr != Py_None)
+ {
+ lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
+ if (sb_value_ptr == nullptr)
+ Py_XDECREF(child_ptr);
+ else
+ ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
+ }
+ else
+ {
+ Py_XDECREF(child_ptr);
+ }
+ }
+
+ return ret_val;
+}
+
static std::string
ReadPythonBacktrace (PyObject* py_backtrace)
{
@@ -2240,6 +2382,38 @@ ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
}
return ret_val;
}
+
+bool
+ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
+ ValueObject *value,
+ std::string& output,
+ Error& error)
+{
+ bool ret_val;
+ if (!value)
+ {
+ error.SetErrorString("no value");
+ return false;
+ }
+ if (!impl_function || !impl_function[0])
+ {
+ error.SetErrorString("no function to execute");
+ return false;
+ }
+ if (!g_swig_run_script_keyword_value)
+ {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+ {
+ ValueObjectSP value_sp(value->GetSP());
+ Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ ret_val = g_swig_run_script_keyword_value (impl_function, m_dictionary_name.c_str(), value_sp, output);
+ if (!ret_val)
+ error.SetErrorString("python script evaluation failed");
+ }
+ return ret_val;
+}
uint64_t replace_all(std::string& str, const std::string& oldStr, const std::string& newStr)
{
@@ -2426,7 +2600,8 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
const char* args,
ScriptedCommandSynchronicity synchronicity,
lldb_private::CommandReturnObject& cmd_retobj,
- Error& error)
+ Error& error,
+ const lldb_private::ExecutionContext& exe_ctx)
{
if (!impl_function)
{
@@ -2441,6 +2616,7 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
}
lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
if (!debugger_sp.get())
{
@@ -2464,7 +2640,8 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
m_dictionary_name.c_str(),
debugger_sp,
args,
- cmd_retobj);
+ cmd_retobj,
+ exe_ctx_ref_sp);
}
if (!ret_val)
@@ -2529,6 +2706,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
SWIGPythonUpdateSynthProviderInstance swig_update_provider,
SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
+ SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
SWIGPythonCallCommand swig_call_command,
SWIGPythonCallModuleInit swig_call_module_init,
SWIGPythonCreateOSPlugin swig_create_os_plugin,
@@ -2536,7 +2714,10 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
- SWIGPython_GetDynamicSetting swig_plugin_get)
+ SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
+ SWIGPython_GetDynamicSetting swig_plugin_get,
+ SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
+ SWIGPythonCallThreadPlan swig_call_thread_plan)
{
g_swig_init_callback = swig_init_callback;
g_swig_breakpoint_callback = swig_breakpoint_callback;
@@ -2550,6 +2731,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
g_swig_update_provider = swig_update_provider;
g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
+ g_swig_getvalue_provider = swig_getvalue_provider;
g_swig_call_command = swig_call_command;
g_swig_call_module_init = swig_call_module_init;
g_swig_create_os_plugin = swig_create_os_plugin;
@@ -2557,7 +2739,10 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callb
g_swig_run_script_keyword_thread = swig_run_script_keyword_thread;
g_swig_run_script_keyword_target = swig_run_script_keyword_target;
g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
+ g_swig_run_script_keyword_value = swig_run_script_keyword_value;
g_swig_plugin_get = swig_plugin_get;
+ g_swig_thread_plan_script = swig_thread_plan_script;
+ g_swig_call_thread_plan = swig_call_thread_plan;
}
void
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py b/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py
index 51a9716..10186f5 100644
--- a/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py
+++ b/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py
@@ -61,7 +61,7 @@ def get_terminal_size(fd):
def readfunc_stdio(prompt):
sys.stdout.write(prompt)
- return sys.stdin.readline()
+ return sys.stdin.readline().rstrip()
def run_python_interpreter (local_dict):
# Pass in the dictionary, for continuity from one session to the next.
OpenPOWER on IntegriCloud