aboutsummaryrefslogtreecommitdiff
path: root/source/Core/Debugger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Core/Debugger.cpp')
-rw-r--r--source/Core/Debugger.cpp2792
1 files changed, 1337 insertions, 1455 deletions
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index 34608d0193fc..8f888a518d5b 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -19,7 +19,6 @@
#include "llvm/Support/DynamicLibrary.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
@@ -50,15 +49,17 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/VariableList.h"
-#include "lldb/Target/TargetList.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/StructuredDataPlugin.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
@@ -69,1124 +70,1052 @@ static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
#pragma mark Static Functions
typedef std::vector<DebuggerSP> DebuggerList;
-static std::recursive_mutex *g_debugger_list_mutex_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
-static DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
-
-OptionEnumValueElement
-g_show_disassembly_enum_values[] =
-{
- { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."},
- { Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", "Show disassembly when there is no debug information."},
- { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
- { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."},
- { 0, nullptr, nullptr }
-};
-
-OptionEnumValueElement
-g_language_enumerators[] =
-{
- { eScriptLanguageNone, "none", "Disable scripting languages."},
- { eScriptLanguagePython, "python", "Select python as the default scripting language."},
- { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."},
- { 0, nullptr, nullptr }
-};
-
-#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
+static std::recursive_mutex *g_debugger_list_mutex_ptr =
+ nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
+static DebuggerList *g_debugger_list_ptr =
+ nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
+
+OptionEnumValueElement g_show_disassembly_enum_values[] = {
+ {Debugger::eStopDisassemblyTypeNever, "never",
+ "Never show disassembly when displaying a stop context."},
+ {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo",
+ "Show disassembly when there is no debug information."},
+ {Debugger::eStopDisassemblyTypeNoSource, "no-source",
+ "Show disassembly when there is no source information, or the source file "
+ "is missing when displaying a stop context."},
+ {Debugger::eStopDisassemblyTypeAlways, "always",
+ "Always show disassembly when displaying a stop context."},
+ {0, nullptr, nullptr}};
+
+OptionEnumValueElement g_language_enumerators[] = {
+ {eScriptLanguageNone, "none", "Disable scripting languages."},
+ {eScriptLanguagePython, "python",
+ "Select python as the default scripting language."},
+ {eScriptLanguageDefault, "default",
+ "Select the lldb default as the default scripting language."},
+ {0, nullptr, nullptr}};
+
+#define MODULE_WITH_FUNC \
+ "{ " \
+ "${module.file.basename}{`${function.name-with-args}" \
+ "{${frame.no-debug}${function.pc-offset}}}}"
#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
#define IS_OPTIMIZED "{${function.is-optimized} [opt]}"
-#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
- "{, ${frame.pc}}"\
- MODULE_WITH_FUNC\
- FILE_AND_LINE\
- "{, name = '${thread.name}'}"\
- "{, queue = '${thread.queue}'}"\
- "{, activity = '${thread.info.activity.name}'}" \
- "{, ${thread.info.trace_messages} messages}" \
- "{, stop reason = ${thread.stop-reason}}"\
- "{\\nReturn value: ${thread.return-value}}"\
- "{\\nCompleted expression: ${thread.completed-expression}}"\
- "\\n"
-
-#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
- MODULE_WITH_FUNC\
- FILE_AND_LINE\
- IS_OPTIMIZED\
- "\\n"
+#define DEFAULT_THREAD_FORMAT \
+ "thread #${thread.index}: tid = ${thread.id%tid}" \
+ "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \
+ "{, name = '${thread.name}'}" \
+ "{, queue = '${thread.queue}'}" \
+ "{, activity = '${thread.info.activity.name}'}" \
+ "{, ${thread.info.trace_messages} messages}" \
+ "{, stop reason = ${thread.stop-reason}}" \
+ "{\\nReturn value: ${thread.return-value}}" \
+ "{\\nCompleted expression: ${thread.completed-expression}}" \
+ "\\n"
+
+#define DEFAULT_THREAD_STOP_FORMAT \
+ "thread #${thread.index}{, name = '${thread.name}'}" \
+ "{, queue = '${thread.queue}'}" \
+ "{, activity = '${thread.info.activity.name}'}" \
+ "{, ${thread.info.trace_messages} messages}" \
+ "{, stop reason = ${thread.stop-reason}}" \
+ "{\\nReturn value: ${thread.return-value}}" \
+ "{\\nCompleted expression: ${thread.completed-expression}}" \
+ "\\n"
+
+#define DEFAULT_FRAME_FORMAT \
+ "frame #${frame.index}:{ ${frame.no-debug}${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \
+ IS_OPTIMIZED "\\n"
// Three parts to this disassembly format specification:
// 1. If this is a new function/symbol (no previous symbol/function), print
// dylib`funcname:\n
-// 2. If this is a symbol context change (different from previous symbol/function), print
+// 2. If this is a symbol context change (different from previous
+// symbol/function), print
// dylib`funcname:\n
-// 3. print
-// address <+offset>:
-#define DEFAULT_DISASSEMBLY_FORMAT "{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: "
+// 3. print
+// address <+offset>:
+#define DEFAULT_DISASSEMBLY_FORMAT \
+ "{${function.initial-function}{${module.file.basename}`}{${function.name-" \
+ "without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${" \
+ "function.name-without-args}}:\n}{${current-pc-arrow} " \
+ "}${addr-file-or-load}{ " \
+ "<${function.concrete-only-addr-offset-no-padding}>}: "
// gdb's disassembly format can be emulated with
-// ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
+// ${current-pc-arrow}${addr-file-or-load}{
+// <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
// lldb's original format for disassembly would look like this format string -
-// {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}:
-
-static PropertyDefinition
-g_properties[] =
-{
-{ "auto-confirm", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "If true all confirmation prompts will receive their default reply." },
-{ "disassembly-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_DISASSEMBLY_FORMAT, nullptr, "The default disassembly format string to use when disassembling instruction sequences." },
-{ "frame-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_FRAME_FORMAT, nullptr, "The default frame format string to use when displaying stack frame information for threads." },
-{ "notify-void", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Notify the user explicitly if an expression returns void (default: false)." },
-{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", nullptr, "The debugger command line prompt displayed for the user." },
-{ "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, nullptr, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
-{ "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , nullptr, nullptr, "The number of disassembly lines to show when displaying a stopped context." },
-{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
-{ "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , nullptr, nullptr, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
-{ "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , nullptr, nullptr, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
-{ "term-width", OptionValue::eTypeSInt64 , true, 80 , nullptr, nullptr, "The maximum number of columns to use for displaying text." },
-{ "thread-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use when displaying thread information." },
-{ "use-external-editor", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Whether to use an external editor or not." },
-{ "use-color", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "Whether to use Ansi color codes or not." },
-{ "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
-{ "auto-indent", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true)." },
-{ "print-decls", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "If true, LLDB will print the values of variables declared in an expression. Currently only supported in the REPL (default: true)." },
-{ "tab-size", OptionValue::eTypeUInt64 , true, 4 , nullptr, nullptr, "The tab size to use when indenting code in multi-line input mode (default: 4)." },
-{ "escape-non-printables", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
-{ nullptr, OptionValue::eTypeInvalid , true, 0 , nullptr, nullptr, nullptr }
-};
-
-enum
-{
- ePropertyAutoConfirm = 0,
- ePropertyDisassemblyFormat,
- ePropertyFrameFormat,
- ePropertyNotiftVoid,
- ePropertyPrompt,
- ePropertyScriptLanguage,
- ePropertyStopDisassemblyCount,
- ePropertyStopDisassemblyDisplay,
- ePropertyStopLineCountAfter,
- ePropertyStopLineCountBefore,
- ePropertyTerminalWidth,
- ePropertyThreadFormat,
- ePropertyUseExternalEditor,
- ePropertyUseColor,
- ePropertyAutoOneLineSummaries,
- ePropertyAutoIndent,
- ePropertyPrintDecls,
- ePropertyTabSize,
- ePropertyEscapeNonPrintables
+// {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow}
+// }{${addr-file-or-load}}:
+
+#define DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX "${ansi.underline}"
+#define DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX "${ansi.normal}"
+
+static OptionEnumValueElement s_stop_show_column_values[] = {
+ {eStopShowColumnAnsiOrCaret, "ansi-or-caret",
+ "Highlight the stop column with ANSI terminal codes when color/ANSI mode "
+ "is enabled; otherwise, fall back to using a text-only caret (^) as if "
+ "\"caret-only\" mode was selected."},
+ {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI "
+ "terminal codes when running LLDB with "
+ "color/ANSI enabled."},
+ {eStopShowColumnCaret, "caret",
+ "Highlight the stop column with a caret character (^) underneath the stop "
+ "column. This method introduces a new line in source listings that "
+ "display thread stop locations."},
+ {eStopShowColumnNone, "none", "Do not highlight the stop column."},
+ {0, nullptr, nullptr}};
+
+static PropertyDefinition g_properties[] = {
+ {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, nullptr,
+ "If true all confirmation prompts will receive their default reply."},
+ {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_DISASSEMBLY_FORMAT, nullptr, "The default disassembly format "
+ "string to use when disassembling "
+ "instruction sequences."},
+ {"frame-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_FRAME_FORMAT, nullptr, "The default frame format string to use "
+ "when displaying stack frame information "
+ "for threads."},
+ {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, nullptr,
+ "Notify the user explicitly if an expression returns void (default: "
+ "false)."},
+ {"prompt", OptionValue::eTypeString, true,
+ OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ",
+ nullptr, "The debugger command line prompt displayed for the user."},
+ {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython,
+ nullptr, g_language_enumerators,
+ "The script language to be used for evaluating user-written scripts."},
+ {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr,
+ nullptr, "The number of disassembly lines to show when displaying a "
+ "stopped context."},
+ {"stop-disassembly-display", OptionValue::eTypeEnum, true,
+ Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr,
+ g_show_disassembly_enum_values,
+ "Control when to display disassembly when displaying a stopped context."},
+ {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr,
+ nullptr, "The number of sources lines to display that come after the "
+ "current source line when displaying a stopped context."},
+ {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr,
+ nullptr, "The number of sources lines to display that come before the "
+ "current source line when displaying a stopped context."},
+ {"stop-show-column", OptionValue::eTypeEnum, false,
+ eStopShowColumnAnsiOrCaret, nullptr, s_stop_show_column_values,
+ "If true, LLDB will use the column information from the debug info to "
+ "mark the current position when displaying a stopped context."},
+ {"stop-show-column-ansi-prefix", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX, nullptr,
+ "When displaying the column marker in a color-enabled (i.e. ANSI) "
+ "terminal, use the ANSI terminal code specified in this format at the "
+ "immediately before the column to be marked."},
+ {"stop-show-column-ansi-suffix", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX, nullptr,
+ "When displaying the column marker in a color-enabled (i.e. ANSI) "
+ "terminal, use the ANSI terminal code specified in this format "
+ "immediately after the column to be marked."},
+ {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, nullptr,
+ "The maximum number of columns to use for displaying text."},
+ {"thread-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use "
+ "when displaying thread information."},
+ {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_THREAD_STOP_FORMAT, nullptr, "The default thread format "
+ "string to usewhen displaying thread "
+ "information as part of the stop display."},
+ {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr,
+ nullptr, "Whether to use an external editor or not."},
+ {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
+ "Whether to use Ansi color codes or not."},
+ {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr,
+ nullptr, "If true, LLDB will automatically display small structs in "
+ "one-liner format (default: true)."},
+ {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
+ "If true, LLDB will auto indent/outdent code. Currently only supported in "
+ "the REPL (default: true)."},
+ {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
+ "If true, LLDB will print the values of variables declared in an "
+ "expression. Currently only supported in the REPL (default: true)."},
+ {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, nullptr,
+ "The tab size to use when indenting code in multi-line input mode "
+ "(default: 4)."},
+ {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr,
+ nullptr, "If true, LLDB will automatically escape non-printable and "
+ "escape characters when formatting strings."},
+ {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}};
+
+enum {
+ ePropertyAutoConfirm = 0,
+ ePropertyDisassemblyFormat,
+ ePropertyFrameFormat,
+ ePropertyNotiftVoid,
+ ePropertyPrompt,
+ ePropertyScriptLanguage,
+ ePropertyStopDisassemblyCount,
+ ePropertyStopDisassemblyDisplay,
+ ePropertyStopLineCountAfter,
+ ePropertyStopLineCountBefore,
+ ePropertyStopShowColumn,
+ ePropertyStopShowColumnAnsiPrefix,
+ ePropertyStopShowColumnAnsiSuffix,
+ ePropertyTerminalWidth,
+ ePropertyThreadFormat,
+ ePropertyThreadStopFormat,
+ ePropertyUseExternalEditor,
+ ePropertyUseColor,
+ ePropertyAutoOneLineSummaries,
+ ePropertyAutoIndent,
+ ePropertyPrintDecls,
+ ePropertyTabSize,
+ ePropertyEscapeNonPrintables
};
LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
-Error
-Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
- VarSetOperationType op,
- const char *property_path,
- const char *value)
-{
- bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
- bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
- TargetSP target_sp;
- LoadScriptFromSymFile load_script_old_value;
- if (is_load_script && exe_ctx->GetTargetSP())
- {
- target_sp = exe_ctx->GetTargetSP();
- load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
- }
- Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
- if (error.Success())
- {
- // FIXME it would be nice to have "on-change" callbacks for properties
- if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
- {
- const char *new_prompt = GetPrompt();
- std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
- if (str.length())
- new_prompt = str.c_str();
- GetCommandInterpreter().UpdatePrompt(new_prompt);
- EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
- GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
- }
- else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
- {
- // use-color changed. Ping the prompt so it can reset the ansi terminal codes.
- SetPrompt (GetPrompt());
- }
- else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
- {
- if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
- {
- std::list<Error> errors;
- StreamString feedback_stream;
- if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
- {
- StreamFileSP stream_sp (GetErrorFile());
- if (stream_sp)
- {
- for (auto error : errors)
- {
- stream_sp->Printf("%s\n",error.AsCString());
- }
- if (feedback_stream.GetSize())
- stream_sp->Printf("%s",feedback_stream.GetData());
- }
- }
+Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ llvm::StringRef property_path, llvm::StringRef value) {
+ bool is_load_script = (property_path == "target.load-script-from-symbol-file");
+ bool is_escape_non_printables = (property_path == "escape-non-printables");
+ TargetSP target_sp;
+ LoadScriptFromSymFile load_script_old_value;
+ if (is_load_script && exe_ctx->GetTargetSP()) {
+ target_sp = exe_ctx->GetTargetSP();
+ load_script_old_value =
+ target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
+ }
+ Error error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
+ if (error.Success()) {
+ // FIXME it would be nice to have "on-change" callbacks for properties
+ if (property_path == g_properties[ePropertyPrompt].name) {
+ llvm::StringRef new_prompt = GetPrompt();
+ std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes(
+ new_prompt, GetUseColor());
+ if (str.length())
+ new_prompt = str;
+ GetCommandInterpreter().UpdatePrompt(new_prompt);
+ EventSP prompt_change_event_sp(
+ new Event(CommandInterpreter::eBroadcastBitResetPrompt,
+ new EventDataBytes(new_prompt)));
+ GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp);
+ } else if (property_path == g_properties[ePropertyUseColor].name) {
+ // use-color changed. Ping the prompt so it can reset the ansi terminal
+ // codes.
+ SetPrompt(GetPrompt());
+ } else if (is_load_script && target_sp &&
+ load_script_old_value == eLoadScriptFromSymFileWarn) {
+ if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
+ eLoadScriptFromSymFileTrue) {
+ std::list<Error> errors;
+ StreamString feedback_stream;
+ if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) {
+ StreamFileSP stream_sp(GetErrorFile());
+ if (stream_sp) {
+ for (auto error : errors) {
+ stream_sp->Printf("%s\n", error.AsCString());
}
+ if (feedback_stream.GetSize())
+ stream_sp->PutCString(feedback_stream.GetString());
+ }
}
- else if (is_escape_non_printables)
- {
- DataVisualization::ForceUpdate();
- }
+ }
+ } else if (is_escape_non_printables) {
+ DataVisualization::ForceUpdate();
}
- return error;
+ }
+ return error;
}
-bool
-Debugger::GetAutoConfirm () const
-{
- const uint32_t idx = ePropertyAutoConfirm;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::GetAutoConfirm() const {
+ const uint32_t idx = ePropertyAutoConfirm;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-const FormatEntity::Entry *
-Debugger::GetDisassemblyFormat() const
-{
- const uint32_t idx = ePropertyDisassemblyFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
+ const uint32_t idx = ePropertyDisassemblyFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-const FormatEntity::Entry *
-Debugger::GetFrameFormat() const
-{
- const uint32_t idx = ePropertyFrameFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetFrameFormat() const {
+ const uint32_t idx = ePropertyFrameFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetNotifyVoid () const
-{
- const uint32_t idx = ePropertyNotiftVoid;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::GetNotifyVoid() const {
+ const uint32_t idx = ePropertyNotiftVoid;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-const char *
-Debugger::GetPrompt() const
-{
- const uint32_t idx = ePropertyPrompt;
- return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, g_properties[idx].default_cstr_value);
+llvm::StringRef Debugger::GetPrompt() const {
+ const uint32_t idx = ePropertyPrompt;
+ return m_collection_sp->GetPropertyAtIndexAsString(
+ nullptr, idx, g_properties[idx].default_cstr_value);
}
-void
-Debugger::SetPrompt(const char *p)
-{
- const uint32_t idx = ePropertyPrompt;
- m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
- const char *new_prompt = GetPrompt();
- std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
- if (str.length())
- new_prompt = str.c_str();
- GetCommandInterpreter().UpdatePrompt(new_prompt);
+void Debugger::SetPrompt(llvm::StringRef p) {
+ const uint32_t idx = ePropertyPrompt;
+ m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
+ llvm::StringRef new_prompt = GetPrompt();
+ std::string str =
+ lldb_utility::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor());
+ if (str.length())
+ new_prompt = str;
+ GetCommandInterpreter().UpdatePrompt(new_prompt);
}
-const FormatEntity::Entry *
-Debugger::GetThreadFormat() const
-{
- const uint32_t idx = ePropertyThreadFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetThreadFormat() const {
+ const uint32_t idx = ePropertyThreadFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-lldb::ScriptLanguage
-Debugger::GetScriptLanguage() const
-{
- const uint32_t idx = ePropertyScriptLanguage;
- return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+const FormatEntity::Entry *Debugger::GetThreadStopFormat() const {
+ const uint32_t idx = ePropertyThreadStopFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
-{
- const uint32_t idx = ePropertyScriptLanguage;
- return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, script_lang);
+lldb::ScriptLanguage Debugger::GetScriptLanguage() const {
+ const uint32_t idx = ePropertyScriptLanguage;
+ return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-uint32_t
-Debugger::GetTerminalWidth () const
-{
- const uint32_t idx = ePropertyTerminalWidth;
- return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
+ const uint32_t idx = ePropertyScriptLanguage;
+ return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx,
+ script_lang);
}
-bool
-Debugger::SetTerminalWidth (uint32_t term_width)
-{
- const uint32_t idx = ePropertyTerminalWidth;
- return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
+uint32_t Debugger::GetTerminalWidth() const {
+ const uint32_t idx = ePropertyTerminalWidth;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::GetUseExternalEditor () const
-{
- const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::SetTerminalWidth(uint32_t term_width) {
+ const uint32_t idx = ePropertyTerminalWidth;
+ return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
}
-bool
-Debugger::SetUseExternalEditor (bool b)
-{
- const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+bool Debugger::GetUseExternalEditor() const {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-bool
-Debugger::GetUseColor () const
-{
- const uint32_t idx = ePropertyUseColor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::SetUseExternalEditor(bool b) {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
-bool
-Debugger::SetUseColor (bool b)
-{
- const uint32_t idx = ePropertyUseColor;
- bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
- SetPrompt (GetPrompt());
- return ret;
+bool Debugger::GetUseColor() const {
+ const uint32_t idx = ePropertyUseColor;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-uint32_t
-Debugger::GetStopSourceLineCount (bool before) const
-{
- const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
- return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+bool Debugger::SetUseColor(bool b) {
+ const uint32_t idx = ePropertyUseColor;
+ bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+ SetPrompt(GetPrompt());
+ return ret;
}
-Debugger::StopDisassemblyType
-Debugger::GetStopDisassemblyDisplay () const
-{
- const uint32_t idx = ePropertyStopDisassemblyDisplay;
- return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+StopShowColumn Debugger::GetStopShowColumn() const {
+ const uint32_t idx = ePropertyStopShowColumn;
+ return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-uint32_t
-Debugger::GetDisassemblyLineCount () const
-{
- const uint32_t idx = ePropertyStopDisassemblyCount;
- return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiPrefix() const {
+ const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetAutoOneLineSummaries () const
-{
- const uint32_t idx = ePropertyAutoOneLineSummaries;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiSuffix() const {
+ const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetEscapeNonPrintables () const
-{
- const uint32_t idx = ePropertyEscapeNonPrintables;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+uint32_t Debugger::GetStopSourceLineCount(bool before) const {
+ const uint32_t idx =
+ before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::GetAutoIndent () const
-{
- const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const {
+ const uint32_t idx = ePropertyStopDisassemblyDisplay;
+ return (Debugger::StopDisassemblyType)
+ m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::SetAutoIndent (bool b)
-{
- const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+uint32_t Debugger::GetDisassemblyLineCount() const {
+ const uint32_t idx = ePropertyStopDisassemblyCount;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::GetPrintDecls () const
-{
- const uint32_t idx = ePropertyPrintDecls;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+bool Debugger::GetAutoOneLineSummaries() const {
+ const uint32_t idx = ePropertyAutoOneLineSummaries;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
-bool
-Debugger::SetPrintDecls (bool b)
-{
- const uint32_t idx = ePropertyPrintDecls;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+bool Debugger::GetEscapeNonPrintables() const {
+ const uint32_t idx = ePropertyEscapeNonPrintables;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
-uint32_t
-Debugger::GetTabSize () const
-{
- const uint32_t idx = ePropertyTabSize;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_properties[idx].default_uint_value);
+bool Debugger::GetAutoIndent() const {
+ const uint32_t idx = ePropertyAutoIndent;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
-bool
-Debugger::SetTabSize (uint32_t tab_size)
-{
- const uint32_t idx = ePropertyTabSize;
- return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size);
+bool Debugger::SetAutoIndent(bool b) {
+ const uint32_t idx = ePropertyAutoIndent;
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+}
+
+bool Debugger::GetPrintDecls() const {
+ const uint32_t idx = ePropertyPrintDecls;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+}
+
+bool Debugger::SetPrintDecls(bool b) {
+ const uint32_t idx = ePropertyPrintDecls;
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+}
+
+uint32_t Debugger::GetTabSize() const {
+ const uint32_t idx = ePropertyTabSize;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
+}
+
+bool Debugger::SetTabSize(uint32_t tab_size) {
+ const uint32_t idx = ePropertyTabSize;
+ return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size);
}
#pragma mark Debugger
-//const DebuggerPropertiesSP &
-//Debugger::GetSettings() const
+// const DebuggerPropertiesSP &
+// Debugger::GetSettings() const
//{
// return m_properties_sp;
//}
//
-void
-Debugger::Initialize(LoadPluginCallbackType load_plugin_callback)
-{
- assert(g_debugger_list_ptr == nullptr && "Debugger::Initialize called more than once!");
- g_debugger_list_mutex_ptr = new std::recursive_mutex();
- g_debugger_list_ptr = new DebuggerList();
- g_load_plugin_callback = load_plugin_callback;
+void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) {
+ assert(g_debugger_list_ptr == nullptr &&
+ "Debugger::Initialize called more than once!");
+ g_debugger_list_mutex_ptr = new std::recursive_mutex();
+ g_debugger_list_ptr = new DebuggerList();
+ g_load_plugin_callback = load_plugin_callback;
}
-void
-Debugger::Terminate ()
-{
- assert(g_debugger_list_ptr && "Debugger::Terminate called without a matching Debugger::Initialize!");
+void Debugger::Terminate() {
+ assert(g_debugger_list_ptr &&
+ "Debugger::Terminate called without a matching Debugger::Initialize!");
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ // Clear our master list of debugger objects
{
- // Clear our master list of debugger objects
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- for (const auto& debugger: *g_debugger_list_ptr)
- debugger->Clear();
- g_debugger_list_ptr->clear();
- }
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ for (const auto &debugger : *g_debugger_list_ptr)
+ debugger->Clear();
+ g_debugger_list_ptr->clear();
}
+ }
}
-void
-Debugger::SettingsInitialize ()
-{
- Target::SettingsInitialize ();
-}
+void Debugger::SettingsInitialize() { Target::SettingsInitialize(); }
-void
-Debugger::SettingsTerminate ()
-{
- Target::SettingsTerminate ();
-}
+void Debugger::SettingsTerminate() { Target::SettingsTerminate(); }
-bool
-Debugger::LoadPlugin (const FileSpec& spec, Error& error)
-{
- if (g_load_plugin_callback)
- {
- llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
- if (dynlib.isValid())
- {
- m_loaded_plugins.push_back(dynlib);
- return true;
- }
+bool Debugger::LoadPlugin(const FileSpec &spec, Error &error) {
+ if (g_load_plugin_callback) {
+ llvm::sys::DynamicLibrary dynlib =
+ g_load_plugin_callback(shared_from_this(), spec, error);
+ if (dynlib.isValid()) {
+ m_loaded_plugins.push_back(dynlib);
+ return true;
}
- else
- {
- // The g_load_plugin_callback is registered in SBDebugger::Initialize()
- // and if the public API layer isn't available (code is linking against
- // all of the internal LLDB static libraries), then we can't load plugins
- error.SetErrorString("Public API layer is not available");
- }
- return false;
+ } else {
+ // The g_load_plugin_callback is registered in SBDebugger::Initialize()
+ // and if the public API layer isn't available (code is linking against
+ // all of the internal LLDB static libraries), then we can't load plugins
+ error.SetErrorString("Public API layer is not available");
+ }
+ return false;
}
static FileSpec::EnumerateDirectoryResult
-LoadPluginCallback(void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- Error error;
-
- static ConstString g_dylibext("dylib");
- static ConstString g_solibext("so");
-
- if (!baton)
- return FileSpec::eEnumerateDirectoryResultQuit;
-
- Debugger *debugger = (Debugger*)baton;
-
- // If we have a regular file, a symbolic link or unknown file type, try
- // and process the file. We must handle unknown as sometimes the directory
- // enumeration might be enumerating a file system that doesn't have correct
- // file type information.
- if (file_type == FileSpec::eFileTypeRegular ||
- file_type == FileSpec::eFileTypeSymbolicLink ||
- file_type == FileSpec::eFileTypeUnknown )
- {
- FileSpec plugin_file_spec (file_spec);
- plugin_file_spec.ResolvePath ();
-
- if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
- plugin_file_spec.GetFileNameExtension() != g_solibext)
- {
- return FileSpec::eEnumerateDirectoryResultNext;
- }
-
- Error plugin_load_error;
- debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
-
- return FileSpec::eEnumerateDirectoryResultNext;
- }
- else if (file_type == FileSpec::eFileTypeUnknown ||
- file_type == FileSpec::eFileTypeDirectory ||
- file_type == FileSpec::eFileTypeSymbolicLink )
- {
- // Try and recurse into anything that a directory or symbolic link.
- // We must also do this for unknown as sometimes the directory enumeration
- // might be enumerating a file system that doesn't have correct file type
- // information.
- return FileSpec::eEnumerateDirectoryResultEnter;
+LoadPluginCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ Error error;
+
+ static ConstString g_dylibext("dylib");
+ static ConstString g_solibext("so");
+
+ if (!baton)
+ return FileSpec::eEnumerateDirectoryResultQuit;
+
+ Debugger *debugger = (Debugger *)baton;
+
+ // If we have a regular file, a symbolic link or unknown file type, try
+ // and process the file. We must handle unknown as sometimes the directory
+ // enumeration might be enumerating a file system that doesn't have correct
+ // file type information.
+ if (file_type == FileSpec::eFileTypeRegular ||
+ file_type == FileSpec::eFileTypeSymbolicLink ||
+ file_type == FileSpec::eFileTypeUnknown) {
+ FileSpec plugin_file_spec(file_spec);
+ plugin_file_spec.ResolvePath();
+
+ if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
+ plugin_file_spec.GetFileNameExtension() != g_solibext) {
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-void
-Debugger::InstanceInitialize ()
-{
- FileSpec dir_spec;
- const bool find_directories = true;
- const bool find_files = true;
- const bool find_other = true;
- char dir_path[PATH_MAX];
- if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- this);
- }
+ Error plugin_load_error;
+ debugger->LoadPlugin(plugin_file_spec, plugin_load_error);
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+ } else if (file_type == FileSpec::eFileTypeUnknown ||
+ file_type == FileSpec::eFileTypeDirectory ||
+ file_type == FileSpec::eFileTypeSymbolicLink) {
+ // Try and recurse into anything that a directory or symbolic link.
+ // We must also do this for unknown as sometimes the directory enumeration
+ // might be enumerating a file system that doesn't have correct file type
+ // information.
+ return FileSpec::eEnumerateDirectoryResultEnter;
+ }
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+void Debugger::InstanceInitialize() {
+ FileSpec dir_spec;
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true;
+ char dir_path[PATH_MAX];
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, this);
}
+ }
- if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- this);
- }
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, this);
}
-
- PluginManager::DebuggerInitialize (*this);
+ }
+
+ PluginManager::DebuggerInitialize(*this);
}
-DebuggerSP
-Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
-{
- DebuggerSP debugger_sp (new Debugger(log_callback, baton));
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- g_debugger_list_ptr->push_back(debugger_sp);
- }
- debugger_sp->InstanceInitialize ();
- return debugger_sp;
+DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
+ void *baton) {
+ DebuggerSP debugger_sp(new Debugger(log_callback, baton));
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ g_debugger_list_ptr->push_back(debugger_sp);
+ }
+ debugger_sp->InstanceInitialize();
+ return debugger_sp;
}
-void
-Debugger::Destroy (DebuggerSP &debugger_sp)
-{
- if (!debugger_sp)
- return;
-
- debugger_sp->Clear();
+void Debugger::Destroy(DebuggerSP &debugger_sp) {
+ if (!debugger_sp)
+ return;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- if ((*pos).get() == debugger_sp.get())
- {
- g_debugger_list_ptr->erase (pos);
- return;
- }
- }
+ debugger_sp->Clear();
+
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos).get() == debugger_sp.get()) {
+ g_debugger_list_ptr->erase(pos);
+ return;
+ }
}
+ }
}
DebuggerSP
-Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
-{
- DebuggerSP debugger_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- if ((*pos)->m_instance_name == instance_name)
- {
- debugger_sp = *pos;
- break;
- }
- }
+Debugger::FindDebuggerWithInstanceName(const ConstString &instance_name) {
+ DebuggerSP debugger_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos)->m_instance_name == instance_name) {
+ debugger_sp = *pos;
+ break;
+ }
}
- return debugger_sp;
-}
-
-TargetSP
-Debugger::FindTargetWithProcessID (lldb::pid_t pid)
-{
- TargetSP target_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
- if (target_sp)
- break;
- }
+ }
+ return debugger_sp;
+}
+
+TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) {
+ TargetSP target_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
+ if (target_sp)
+ break;
}
- return target_sp;
-}
-
-TargetSP
-Debugger::FindTargetWithProcess (Process *process)
-{
- TargetSP target_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
- if (target_sp)
- break;
- }
+ }
+ return target_sp;
+}
+
+TargetSP Debugger::FindTargetWithProcess(Process *process) {
+ TargetSP target_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
+ if (target_sp)
+ break;
}
- return target_sp;
-}
-
-Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
- UserID(g_unique_id++),
- Properties(OptionValuePropertiesSP(new OptionValueProperties())),
- m_input_file_sp(new StreamFile(stdin, false)),
- m_output_file_sp(new StreamFile(stdout, false)),
- m_error_file_sp(new StreamFile(stderr, false)),
- m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
- m_terminal_state(),
- m_target_list(*this),
- m_platform_list(),
- m_listener_sp(Listener::MakeListener("lldb.Debugger")),
- m_source_manager_ap(),
- m_source_file_cache(),
- m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
- m_input_reader_stack(),
- m_instance_name(),
- m_loaded_plugins(),
- m_event_handler_thread(),
- m_io_handler_thread(),
- m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
- m_forward_listener_sp(),
- m_clear_once()
-{
- char instance_cstr[256];
- snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
- m_instance_name.SetCString(instance_cstr);
- if (log_callback)
- m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
- m_command_interpreter_ap->Initialize ();
- // Always add our default platform to the platform list
- PlatformSP default_platform_sp (Platform::GetHostPlatform());
- assert(default_platform_sp);
- m_platform_list.Append (default_platform_sp, true);
-
- m_collection_sp->Initialize (g_properties);
- m_collection_sp->AppendProperty (ConstString("target"),
- ConstString("Settings specify to debugging targets."),
- true,
- Target::GetGlobalProperties()->GetValueProperties());
- m_collection_sp->AppendProperty (ConstString("platform"),
- ConstString("Platform settings."),
- true,
- Platform::GetGlobalPlatformProperties()->GetValueProperties());
- if (m_command_interpreter_ap)
- {
- m_collection_sp->AppendProperty (ConstString("interpreter"),
- ConstString("Settings specify to the debugger's command interpreter."),
- true,
- m_command_interpreter_ap->GetValueProperties());
+ }
+ return target_sp;
+}
+
+Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
+ : UserID(g_unique_id++),
+ Properties(OptionValuePropertiesSP(new OptionValueProperties())),
+ m_input_file_sp(new StreamFile(stdin, false)),
+ m_output_file_sp(new StreamFile(stdout, false)),
+ m_error_file_sp(new StreamFile(stderr, false)),
+ m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
+ m_terminal_state(), m_target_list(*this), m_platform_list(),
+ m_listener_sp(Listener::MakeListener("lldb.Debugger")),
+ m_source_manager_ap(), m_source_file_cache(),
+ m_command_interpreter_ap(
+ new CommandInterpreter(*this, eScriptLanguageDefault, false)),
+ m_input_reader_stack(), m_instance_name(), m_loaded_plugins(),
+ m_event_handler_thread(), m_io_handler_thread(),
+ m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
+ m_forward_listener_sp(), m_clear_once() {
+ char instance_cstr[256];
+ snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
+ m_instance_name.SetCString(instance_cstr);
+ if (log_callback)
+ m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton));
+ m_command_interpreter_ap->Initialize();
+ // Always add our default platform to the platform list
+ PlatformSP default_platform_sp(Platform::GetHostPlatform());
+ assert(default_platform_sp);
+ m_platform_list.Append(default_platform_sp, true);
+
+ m_collection_sp->Initialize(g_properties);
+ m_collection_sp->AppendProperty(
+ ConstString("target"),
+ ConstString("Settings specify to debugging targets."), true,
+ Target::GetGlobalProperties()->GetValueProperties());
+ m_collection_sp->AppendProperty(
+ ConstString("platform"), ConstString("Platform settings."), true,
+ Platform::GetGlobalPlatformProperties()->GetValueProperties());
+ if (m_command_interpreter_ap) {
+ m_collection_sp->AppendProperty(
+ ConstString("interpreter"),
+ ConstString("Settings specify to the debugger's command interpreter."),
+ true, m_command_interpreter_ap->GetValueProperties());
+ }
+ OptionValueSInt64 *term_width =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(
+ nullptr, ePropertyTerminalWidth);
+ term_width->SetMinimumValue(10);
+ term_width->SetMaximumValue(1024);
+
+ // Turn off use-color if this is a dumb terminal.
+ const char *term = getenv("TERM");
+ if (term && !strcmp(term, "dumb"))
+ SetUseColor(false);
+}
+
+Debugger::~Debugger() { Clear(); }
+
+void Debugger::Clear() {
+ //----------------------------------------------------------------------
+ // Make sure we call this function only once. With the C++ global
+ // destructor chain having a list of debuggers and with code that can be
+ // running on other threads, we need to ensure this doesn't happen
+ // multiple times.
+ //
+ // The following functions call Debugger::Clear():
+ // Debugger::~Debugger();
+ // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
+ // static void Debugger::Terminate();
+ //----------------------------------------------------------------------
+ std::call_once(m_clear_once, [this]() {
+ ClearIOHandlers();
+ StopIOHandlerThread();
+ StopEventHandlerThread();
+ m_listener_sp->Clear();
+ int num_targets = m_target_list.GetNumTargets();
+ for (int i = 0; i < num_targets; i++) {
+ TargetSP target_sp(m_target_list.GetTargetAtIndex(i));
+ if (target_sp) {
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Finalize();
+ target_sp->Destroy();
+ }
}
- OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(nullptr, ePropertyTerminalWidth);
- term_width->SetMinimumValue(10);
- term_width->SetMaximumValue(1024);
+ m_broadcaster_manager_sp->Clear();
+
+ // Close the input file _before_ we close the input read communications
+ // class
+ // as it does NOT own the input file, our m_input_file does.
+ m_terminal_state.Clear();
+ if (m_input_file_sp)
+ m_input_file_sp->GetFile().Close();
- // Turn off use-color if this is a dumb terminal.
- const char *term = getenv ("TERM");
- if (term && !strcmp (term, "dumb"))
- SetUseColor (false);
+ m_command_interpreter_ap->Clear();
+ });
}
-Debugger::~Debugger ()
-{
- Clear();
+bool Debugger::GetCloseInputOnEOF() const {
+ // return m_input_comm.GetCloseOnEOF();
+ return false;
}
-void
-Debugger::Clear()
-{
- //----------------------------------------------------------------------
- // Make sure we call this function only once. With the C++ global
- // destructor chain having a list of debuggers and with code that can be
- // running on other threads, we need to ensure this doesn't happen
- // multiple times.
- //
- // The following functions call Debugger::Clear():
- // Debugger::~Debugger();
- // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
- // static void Debugger::Terminate();
- //----------------------------------------------------------------------
- std::call_once(m_clear_once, [this]() {
- ClearIOHandlers();
- StopIOHandlerThread();
- StopEventHandlerThread();
- m_listener_sp->Clear();
- int num_targets = m_target_list.GetNumTargets();
- for (int i = 0; i < num_targets; i++)
- {
- TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
- if (target_sp)
- {
- ProcessSP process_sp (target_sp->GetProcessSP());
- if (process_sp)
- process_sp->Finalize();
- target_sp->Destroy();
- }
- }
- m_broadcaster_manager_sp->Clear ();
-
- // Close the input file _before_ we close the input read communications class
- // as it does NOT own the input file, our m_input_file does.
- m_terminal_state.Clear();
- if (m_input_file_sp)
- m_input_file_sp->GetFile().Close ();
-
- m_command_interpreter_ap->Clear();
- });
-}
-
-bool
-Debugger::GetCloseInputOnEOF () const
-{
-// return m_input_comm.GetCloseOnEOF();
- return false;
+void Debugger::SetCloseInputOnEOF(bool b) {
+ // m_input_comm.SetCloseOnEOF(b);
}
-void
-Debugger::SetCloseInputOnEOF (bool b)
-{
-// m_input_comm.SetCloseOnEOF(b);
+bool Debugger::GetAsyncExecution() {
+ return !m_command_interpreter_ap->GetSynchronous();
}
-bool
-Debugger::GetAsyncExecution ()
-{
- return !m_command_interpreter_ap->GetSynchronous();
+void Debugger::SetAsyncExecution(bool async_execution) {
+ m_command_interpreter_ap->SetSynchronous(!async_execution);
}
-void
-Debugger::SetAsyncExecution (bool async_execution)
-{
- m_command_interpreter_ap->SetSynchronous (!async_execution);
+void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership) {
+ if (m_input_file_sp)
+ m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership);
+ else
+ m_input_file_sp.reset(new StreamFile(fh, tranfer_ownership));
+
+ File &in_file = m_input_file_sp->GetFile();
+ if (!in_file.IsValid())
+ in_file.SetStream(stdin, true);
+
+ // Save away the terminal state if that is relevant, so that we can restore it
+ // in RestoreInputState.
+ SaveInputTerminalState();
}
-void
-Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
-{
- if (m_input_file_sp)
- m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
- else
- m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
+void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) {
+ if (m_output_file_sp)
+ m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership);
+ else
+ m_output_file_sp.reset(new StreamFile(fh, tranfer_ownership));
- File &in_file = m_input_file_sp->GetFile();
- if (!in_file.IsValid())
- in_file.SetStream (stdin, true);
+ File &out_file = m_output_file_sp->GetFile();
+ if (!out_file.IsValid())
+ out_file.SetStream(stdout, false);
- // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
- SaveInputTerminalState ();
+ // do not create the ScriptInterpreter just for setting the output file handle
+ // as the constructor will know how to do the right thing on its own
+ const bool can_create = false;
+ ScriptInterpreter *script_interpreter =
+ GetCommandInterpreter().GetScriptInterpreter(can_create);
+ if (script_interpreter)
+ script_interpreter->ResetOutputFileHandle(fh);
}
-void
-Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
-{
- if (m_output_file_sp)
- m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
- else
- m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
-
- File &out_file = m_output_file_sp->GetFile();
- if (!out_file.IsValid())
- out_file.SetStream (stdout, false);
-
- // do not create the ScriptInterpreter just for setting the output file handle
- // as the constructor will know how to do the right thing on its own
- const bool can_create = false;
- ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
- if (script_interpreter)
- script_interpreter->ResetOutputFileHandle (fh);
-}
-
-void
-Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
-{
- if (m_error_file_sp)
- m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
- else
- m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
-
- File &err_file = m_error_file_sp->GetFile();
- if (!err_file.IsValid())
- err_file.SetStream (stderr, false);
+void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) {
+ if (m_error_file_sp)
+ m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership);
+ else
+ m_error_file_sp.reset(new StreamFile(fh, tranfer_ownership));
+
+ File &err_file = m_error_file_sp->GetFile();
+ if (!err_file.IsValid())
+ err_file.SetStream(stderr, false);
}
-void
-Debugger::SaveInputTerminalState ()
-{
- if (m_input_file_sp)
- {
- File &in_file = m_input_file_sp->GetFile();
- if (in_file.GetDescriptor() != File::kInvalidDescriptor)
- m_terminal_state.Save(in_file.GetDescriptor(), true);
+void Debugger::SaveInputTerminalState() {
+ if (m_input_file_sp) {
+ File &in_file = m_input_file_sp->GetFile();
+ if (in_file.GetDescriptor() != File::kInvalidDescriptor)
+ m_terminal_state.Save(in_file.GetDescriptor(), true);
+ }
+}
+
+void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); }
+
+ExecutionContext Debugger::GetSelectedExecutionContext() {
+ ExecutionContext exe_ctx;
+ TargetSP target_sp(GetSelectedTarget());
+ exe_ctx.SetTargetSP(target_sp);
+
+ if (target_sp) {
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ exe_ctx.SetProcessSP(process_sp);
+ if (process_sp && !process_sp->IsRunning()) {
+ ThreadSP thread_sp(process_sp->GetThreadList().GetSelectedThread());
+ if (thread_sp) {
+ exe_ctx.SetThreadSP(thread_sp);
+ exe_ctx.SetFrameSP(thread_sp->GetSelectedFrame());
+ if (exe_ctx.GetFramePtr() == nullptr)
+ exe_ctx.SetFrameSP(thread_sp->GetStackFrameAtIndex(0));
+ }
}
+ }
+ return exe_ctx;
}
-void
-Debugger::RestoreInputTerminalState ()
-{
- m_terminal_state.Restore();
+void Debugger::DispatchInputInterrupt() {
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
+ if (reader_sp)
+ reader_sp->Interrupt();
}
-ExecutionContext
-Debugger::GetSelectedExecutionContext ()
-{
- ExecutionContext exe_ctx;
- TargetSP target_sp(GetSelectedTarget());
- exe_ctx.SetTargetSP (target_sp);
-
- if (target_sp)
- {
- ProcessSP process_sp (target_sp->GetProcessSP());
- exe_ctx.SetProcessSP (process_sp);
- if (process_sp && !process_sp->IsRunning())
- {
- ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
- if (thread_sp)
- {
- exe_ctx.SetThreadSP (thread_sp);
- exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
- if (exe_ctx.GetFramePtr() == nullptr)
- exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
- }
- }
- }
- return exe_ctx;
+void Debugger::DispatchInputEndOfFile() {
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
+ if (reader_sp)
+ reader_sp->GotEOF();
}
-void
-Debugger::DispatchInputInterrupt()
-{
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+void Debugger::ClearIOHandlers() {
+ // The bottom input reader should be the main debugger input reader. We do
+ // not want to close that one here.
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ while (m_input_reader_stack.GetSize() > 1) {
IOHandlerSP reader_sp(m_input_reader_stack.Top());
if (reader_sp)
- reader_sp->Interrupt();
+ PopIOHandler(reader_sp);
+ }
}
-void
-Debugger::DispatchInputEndOfFile()
-{
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+void Debugger::ExecuteIOHandlers() {
+ while (true) {
IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (reader_sp)
- reader_sp->GotEOF();
-}
+ if (!reader_sp)
+ break;
-void
-Debugger::ClearIOHandlers()
-{
- // The bottom input reader should be the main debugger input reader. We do not want to close that one here.
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- while (m_input_reader_stack.GetSize() > 1)
- {
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (reader_sp)
- PopIOHandler(reader_sp);
- }
-}
+ reader_sp->Run();
-void
-Debugger::ExecuteIOHandlers()
-{
- while (true)
- {
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (!reader_sp)
- break;
-
- reader_sp->Run();
-
- // Remove all input readers that are done from the top of the stack
- while (true)
- {
- IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
- if (top_reader_sp && top_reader_sp->GetIsDone())
- PopIOHandler (top_reader_sp);
- else
- break;
- }
+ // Remove all input readers that are done from the top of the stack
+ while (true) {
+ IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
+ if (top_reader_sp && top_reader_sp->GetIsDone())
+ PopIOHandler(top_reader_sp);
+ else
+ break;
}
- ClearIOHandlers();
+ }
+ ClearIOHandlers();
}
-bool
-Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
-{
- return m_input_reader_stack.IsTop (reader_sp);
+bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
+ return m_input_reader_stack.IsTop(reader_sp);
}
-bool
-Debugger::CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type)
-{
- return m_input_reader_stack.CheckTopIOHandlerTypes (top_type, second_top_type);
+bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
+ IOHandler::Type second_top_type) {
+ return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
}
-void
-Debugger::PrintAsync (const char *s, size_t len, bool is_stdout)
-{
- lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
- m_input_reader_stack.PrintAsync(stream.get(), s, len);
+void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
+ lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
+ m_input_reader_stack.PrintAsync(stream.get(), s, len);
}
-ConstString
-Debugger::GetTopIOHandlerControlSequence(char ch)
-{
- return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
+ConstString Debugger::GetTopIOHandlerControlSequence(char ch) {
+ return m_input_reader_stack.GetTopIOHandlerControlSequence(ch);
}
-const char *
-Debugger::GetIOHandlerCommandPrefix()
-{
- return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
+const char *Debugger::GetIOHandlerCommandPrefix() {
+ return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
}
-const char *
-Debugger::GetIOHandlerHelpPrologue()
-{
- return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
+const char *Debugger::GetIOHandlerHelpPrologue() {
+ return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
}
-void
-Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
-{
- PushIOHandler (reader_sp);
+void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
+ PushIOHandler(reader_sp);
- IOHandlerSP top_reader_sp = reader_sp;
- while (top_reader_sp)
- {
- top_reader_sp->Run();
+ IOHandlerSP top_reader_sp = reader_sp;
+ while (top_reader_sp) {
+ top_reader_sp->Run();
- if (top_reader_sp.get() == reader_sp.get())
- {
- if (PopIOHandler (reader_sp))
- break;
- }
+ if (top_reader_sp.get() == reader_sp.get()) {
+ if (PopIOHandler(reader_sp))
+ break;
+ }
- while (true)
- {
- top_reader_sp = m_input_reader_stack.Top();
- if (top_reader_sp && top_reader_sp->GetIsDone())
- PopIOHandler (top_reader_sp);
- else
- break;
- }
+ while (true) {
+ top_reader_sp = m_input_reader_stack.Top();
+ if (top_reader_sp && top_reader_sp->GetIsDone())
+ PopIOHandler(top_reader_sp);
+ else
+ break;
}
-}
+ }
+}
+
+void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in,
+ StreamFileSP &out,
+ StreamFileSP &err) {
+ // Before an IOHandler runs, it must have in/out/err streams.
+ // This function is called when one ore more of the streams
+ // are nullptr. We use the top input reader's in/out/err streams,
+ // or fall back to the debugger file handles, or we fall back
+ // onto stdin/stdout/stderr as a last resort.
+
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
+ // If no STDIN has been set, then set it appropriately
+ if (!in) {
+ if (top_reader_sp)
+ in = top_reader_sp->GetInputStreamFile();
+ else
+ in = GetInputFile();
-void
-Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
-{
- // Before an IOHandler runs, it must have in/out/err streams.
- // This function is called when one ore more of the streams
- // are nullptr. We use the top input reader's in/out/err streams,
- // or fall back to the debugger file handles, or we fall back
- // onto stdin/stdout/stderr as a last resort.
-
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
- // If no STDIN has been set, then set it appropriately
+ // If there is nothing, use stdin
if (!in)
- {
- if (top_reader_sp)
- in = top_reader_sp->GetInputStreamFile();
- else
- in = GetInputFile();
-
- // If there is nothing, use stdin
- if (!in)
- in = StreamFileSP(new StreamFile(stdin, false));
- }
- // If no STDOUT has been set, then set it appropriately
+ in = StreamFileSP(new StreamFile(stdin, false));
+ }
+ // If no STDOUT has been set, then set it appropriately
+ if (!out) {
+ if (top_reader_sp)
+ out = top_reader_sp->GetOutputStreamFile();
+ else
+ out = GetOutputFile();
+
+ // If there is nothing, use stdout
if (!out)
- {
- if (top_reader_sp)
- out = top_reader_sp->GetOutputStreamFile();
- else
- out = GetOutputFile();
-
- // If there is nothing, use stdout
- if (!out)
- out = StreamFileSP(new StreamFile(stdout, false));
- }
- // If no STDERR has been set, then set it appropriately
+ out = StreamFileSP(new StreamFile(stdout, false));
+ }
+ // If no STDERR has been set, then set it appropriately
+ if (!err) {
+ if (top_reader_sp)
+ err = top_reader_sp->GetErrorStreamFile();
+ else
+ err = GetErrorFile();
+
+ // If there is nothing, use stderr
if (!err)
- {
- if (top_reader_sp)
- err = top_reader_sp->GetErrorStreamFile();
- else
- err = GetErrorFile();
-
- // If there is nothing, use stderr
- if (!err)
- err = StreamFileSP(new StreamFile(stdout, false));
- }
+ err = StreamFileSP(new StreamFile(stdout, false));
+ }
}
-void
-Debugger::PushIOHandler(const IOHandlerSP &reader_sp)
-{
- if (!reader_sp)
- return;
+void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) {
+ if (!reader_sp)
+ return;
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- // Get the current top input reader...
- IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
+ // Get the current top input reader...
+ IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
- // Don't push the same IO handler twice...
- if (reader_sp == top_reader_sp)
- return;
+ // Don't push the same IO handler twice...
+ if (reader_sp == top_reader_sp)
+ return;
- // Push our new input reader
- m_input_reader_stack.Push(reader_sp);
- reader_sp->Activate();
+ // Push our new input reader
+ m_input_reader_stack.Push(reader_sp);
+ reader_sp->Activate();
- // Interrupt the top input reader to it will exit its Run() function
- // and let this new input reader take over
- if (top_reader_sp)
- {
- top_reader_sp->Deactivate();
- top_reader_sp->Cancel();
- }
+ // Interrupt the top input reader to it will exit its Run() function
+ // and let this new input reader take over
+ if (top_reader_sp) {
+ top_reader_sp->Deactivate();
+ top_reader_sp->Cancel();
+ }
}
-bool
-Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp)
-{
- if (!pop_reader_sp)
- return false;
+bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
+ if (!pop_reader_sp)
+ return false;
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- // The reader on the stop of the stack is done, so let the next
- // read on the stack refresh its prompt and if there is one...
- if (m_input_reader_stack.IsEmpty())
- return false;
+ // The reader on the stop of the stack is done, so let the next
+ // read on the stack refresh its prompt and if there is one...
+ if (m_input_reader_stack.IsEmpty())
+ return false;
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (pop_reader_sp != reader_sp)
- return false;
+ if (pop_reader_sp != reader_sp)
+ return false;
- reader_sp->Deactivate();
- reader_sp->Cancel();
- m_input_reader_stack.Pop();
+ reader_sp->Deactivate();
+ reader_sp->Cancel();
+ m_input_reader_stack.Pop();
- reader_sp = m_input_reader_stack.Top();
- if (reader_sp)
- reader_sp->Activate();
+ reader_sp = m_input_reader_stack.Top();
+ if (reader_sp)
+ reader_sp->Activate();
- return true;
+ return true;
}
-StreamSP
-Debugger::GetAsyncOutputStream ()
-{
- return StreamSP (new StreamAsynchronousIO (*this, true));
+StreamSP Debugger::GetAsyncOutputStream() {
+ return StreamSP(new StreamAsynchronousIO(*this, true));
}
-StreamSP
-Debugger::GetAsyncErrorStream ()
-{
- return StreamSP (new StreamAsynchronousIO (*this, false));
-}
+StreamSP Debugger::GetAsyncErrorStream() {
+ return StreamSP(new StreamAsynchronousIO(*this, false));
+}
-size_t
-Debugger::GetNumDebuggers()
-{
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- return g_debugger_list_ptr->size();
- }
- return 0;
+size_t Debugger::GetNumDebuggers() {
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ return g_debugger_list_ptr->size();
+ }
+ return 0;
}
-lldb::DebuggerSP
-Debugger::GetDebuggerAtIndex (size_t index)
-{
- DebuggerSP debugger_sp;
-
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- if (index < g_debugger_list_ptr->size())
- debugger_sp = g_debugger_list_ptr->at(index);
- }
+lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) {
+ DebuggerSP debugger_sp;
- return debugger_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ if (index < g_debugger_list_ptr->size())
+ debugger_sp = g_debugger_list_ptr->at(index);
+ }
+
+ return debugger_sp;
}
-DebuggerSP
-Debugger::FindDebuggerWithID (lldb::user_id_t id)
-{
- DebuggerSP debugger_sp;
+DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
+ DebuggerSP debugger_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- if ((*pos)->GetID() == id)
- {
- debugger_sp = *pos;
- break;
- }
- }
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos)->GetID() == id) {
+ debugger_sp = *pos;
+ break;
+ }
}
- return debugger_sp;
+ }
+ return debugger_sp;
}
#if 0
@@ -1258,582 +1187,535 @@ TestPromptFormats (StackFrame *frame)
}
#endif
-bool
-Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
- const SymbolContext *sc,
- const SymbolContext *prev_sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- Stream &s)
-{
- FormatEntity::Entry format_entry;
-
- if (format == nullptr)
- {
- if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
- format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
- if (format == nullptr)
- {
- FormatEntity::Parse("${addr}: ", format_entry);
- format = &format_entry;
- }
+bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
+ const SymbolContext *sc,
+ const SymbolContext *prev_sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, Stream &s) {
+ FormatEntity::Entry format_entry;
+
+ if (format == nullptr) {
+ if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
+ format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ if (format == nullptr) {
+ FormatEntity::Parse("${addr}: ", format_entry);
+ format = &format_entry;
}
- bool function_changed = false;
- bool initial_function = false;
- if (prev_sc && (prev_sc->function || prev_sc->symbol))
- {
- if (sc && (sc->function || sc->symbol))
- {
- if (prev_sc->symbol && sc->symbol)
- {
- if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
- {
- function_changed = true;
- }
- }
- else if (prev_sc->function && sc->function)
- {
- if (prev_sc->function->GetMangled() != sc->function->GetMangled())
- {
- function_changed = true;
- }
- }
+ }
+ bool function_changed = false;
+ bool initial_function = false;
+ if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
+ if (sc && (sc->function || sc->symbol)) {
+ if (prev_sc->symbol && sc->symbol) {
+ if (!sc->symbol->Compare(prev_sc->symbol->GetName(),
+ prev_sc->symbol->GetType())) {
+ function_changed = true;
+ }
+ } else if (prev_sc->function && sc->function) {
+ if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
+ function_changed = true;
}
+ }
}
- // The first context on a list of instructions will have a prev_sc that
- // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
- // would return false. But we do get a prev_sc pointer.
- if ((sc && (sc->function || sc->symbol))
- && prev_sc && (prev_sc->function == nullptr && prev_sc->symbol == nullptr))
- {
- initial_function = true;
+ }
+ // The first context on a list of instructions will have a prev_sc that
+ // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
+ // would return false. But we do get a prev_sc pointer.
+ if ((sc && (sc->function || sc->symbol)) && prev_sc &&
+ (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
+ initial_function = true;
+ }
+ return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr,
+ function_changed, initial_function);
+}
+
+void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
+ void *baton) {
+ // For simplicity's sake, I am not going to deal with how to close down any
+ // open logging streams, I just redirect everything from here on out to the
+ // callback.
+ m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton));
+}
+
+bool Debugger::EnableLog(const char *channel, const char **categories,
+ const char *log_file, uint32_t log_options,
+ Stream &error_stream) {
+ StreamSP log_stream_sp;
+ if (m_log_callback_stream_sp) {
+ log_stream_sp = m_log_callback_stream_sp;
+ // For now when using the callback mode you always get thread & timestamp.
+ log_options |=
+ LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
+ } else if (log_file == nullptr || *log_file == '\0') {
+ log_stream_sp = GetOutputFile();
+ } else {
+ LogStreamMap::iterator pos = m_log_streams.find(log_file);
+ if (pos != m_log_streams.end())
+ log_stream_sp = pos->second.lock();
+ if (!log_stream_sp) {
+ uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
+ if (!(log_options & LLDB_LOG_OPTION_APPEND))
+ options |= File::eOpenOptionTruncate;
+
+ log_stream_sp.reset(new StreamFile(log_file, options));
+ m_log_streams[log_file] = log_stream_sp;
}
- return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, function_changed, initial_function);
-}
+ }
+ assert(log_stream_sp);
-void
-Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
-{
- // For simplicity's sake, I am not going to deal with how to close down any
- // open logging streams, I just redirect everything from here on out to the
- // callback.
- m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
-}
+ if (log_options == 0)
+ log_options =
+ LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
-bool
-Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
-{
- StreamSP log_stream_sp;
- if (m_log_callback_stream_sp)
- {
- log_stream_sp = m_log_callback_stream_sp;
- // For now when using the callback mode you always get thread & timestamp.
- log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
- }
- else if (log_file == nullptr || *log_file == '\0')
- {
- log_stream_sp = GetOutputFile();
- }
- else
- {
- LogStreamMap::iterator pos = m_log_streams.find(log_file);
- if (pos != m_log_streams.end())
- log_stream_sp = pos->second.lock();
- if (!log_stream_sp)
- {
- uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate
- | File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
- if (! (log_options & LLDB_LOG_OPTION_APPEND))
- options |= File::eOpenOptionTruncate;
-
- log_stream_sp.reset (new StreamFile (log_file, options));
- m_log_streams[log_file] = log_stream_sp;
- }
- }
- assert(log_stream_sp);
-
- if (log_options == 0)
- log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
-
- return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, error_stream);
+ return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories,
+ error_stream);
}
-SourceManager &
-Debugger::GetSourceManager ()
-{
- if (!m_source_manager_ap)
- m_source_manager_ap.reset (new SourceManager (shared_from_this()));
- return *m_source_manager_ap;
+SourceManager &Debugger::GetSourceManager() {
+ if (!m_source_manager_ap)
+ m_source_manager_ap.reset(new SourceManager(shared_from_this()));
+ return *m_source_manager_ap;
}
// This function handles events that were broadcast by the process.
-void
-Debugger::HandleBreakpointEvent (const EventSP &event_sp)
-{
- using namespace lldb;
- const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
-
-// if (event_type & eBreakpointEventTypeAdded
-// || event_type & eBreakpointEventTypeRemoved
-// || event_type & eBreakpointEventTypeEnabled
-// || event_type & eBreakpointEventTypeDisabled
-// || event_type & eBreakpointEventTypeCommandChanged
-// || event_type & eBreakpointEventTypeConditionChanged
-// || event_type & eBreakpointEventTypeIgnoreChanged
-// || event_type & eBreakpointEventTypeLocationsResolved)
-// {
-// // Don't do anything about these events, since the breakpoint commands already echo these actions.
-// }
-//
- if (event_type & eBreakpointEventTypeLocationsAdded)
- {
- uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
- if (num_new_locations > 0)
- {
- BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
- StreamSP output_sp (GetAsyncOutputStream());
- if (output_sp)
- {
- output_sp->Printf("%d location%s added to breakpoint %d\n",
- num_new_locations,
- num_new_locations == 1 ? "" : "s",
- breakpoint->GetID());
- output_sp->Flush();
- }
- }
+void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
+ using namespace lldb;
+ const uint32_t event_type =
+ Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
+ event_sp);
+
+ // if (event_type & eBreakpointEventTypeAdded
+ // || event_type & eBreakpointEventTypeRemoved
+ // || event_type & eBreakpointEventTypeEnabled
+ // || event_type & eBreakpointEventTypeDisabled
+ // || event_type & eBreakpointEventTypeCommandChanged
+ // || event_type & eBreakpointEventTypeConditionChanged
+ // || event_type & eBreakpointEventTypeIgnoreChanged
+ // || event_type & eBreakpointEventTypeLocationsResolved)
+ // {
+ // // Don't do anything about these events, since the breakpoint
+ // commands already echo these actions.
+ // }
+ //
+ if (event_type & eBreakpointEventTypeLocationsAdded) {
+ uint32_t num_new_locations =
+ Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
+ event_sp);
+ if (num_new_locations > 0) {
+ BreakpointSP breakpoint =
+ Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
+ StreamSP output_sp(GetAsyncOutputStream());
+ if (output_sp) {
+ output_sp->Printf("%d location%s added to breakpoint %d\n",
+ num_new_locations, num_new_locations == 1 ? "" : "s",
+ breakpoint->GetID());
+ output_sp->Flush();
+ }
}
-// else if (event_type & eBreakpointEventTypeLocationsRemoved)
-// {
-// // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
-// }
-// else if (event_type & eBreakpointEventTypeLocationsResolved)
-// {
-// // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
-// }
-}
-
-size_t
-Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
-{
- size_t total_bytes = 0;
- if (stream == nullptr)
- stream = GetOutputFile().get();
-
- if (stream)
- {
- // The process has stuff waiting for stdout; get it and write it out to the appropriate place.
- if (process == nullptr)
- {
- TargetSP target_sp = GetTargetList().GetSelectedTarget();
- if (target_sp)
- process = target_sp->GetProcessSP().get();
- }
- if (process)
- {
- Error error;
- size_t len;
- char stdio_buffer[1024];
- while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
- {
- stream->Write(stdio_buffer, len);
- total_bytes += len;
- }
- }
- stream->Flush();
+ }
+ // else if (event_type & eBreakpointEventTypeLocationsRemoved)
+ // {
+ // // These locations just get disabled, not sure it is worth spamming
+ // folks about this on the command line.
+ // }
+ // else if (event_type & eBreakpointEventTypeLocationsResolved)
+ // {
+ // // This might be an interesting thing to note, but I'm going to
+ // leave it quiet for now, it just looked noisy.
+ // }
+}
+
+size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) {
+ size_t total_bytes = 0;
+ if (stream == nullptr)
+ stream = GetOutputFile().get();
+
+ if (stream) {
+ // The process has stuff waiting for stdout; get it and write it out to the
+ // appropriate place.
+ if (process == nullptr) {
+ TargetSP target_sp = GetTargetList().GetSelectedTarget();
+ if (target_sp)
+ process = target_sp->GetProcessSP().get();
}
- return total_bytes;
-}
-
-size_t
-Debugger::GetProcessSTDERR (Process *process, Stream *stream)
-{
- size_t total_bytes = 0;
- if (stream == nullptr)
- stream = GetOutputFile().get();
-
- if (stream)
- {
- // The process has stuff waiting for stderr; get it and write it out to the appropriate place.
- if (process == nullptr)
- {
- TargetSP target_sp = GetTargetList().GetSelectedTarget();
- if (target_sp)
- process = target_sp->GetProcessSP().get();
- }
- if (process)
- {
- Error error;
- size_t len;
- char stdio_buffer[1024];
- while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
- {
- stream->Write(stdio_buffer, len);
- total_bytes += len;
- }
- }
- stream->Flush();
+ if (process) {
+ Error error;
+ size_t len;
+ char stdio_buffer[1024];
+ while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
+ error)) > 0) {
+ stream->Write(stdio_buffer, len);
+ total_bytes += len;
+ }
+ }
+ stream->Flush();
+ }
+ return total_bytes;
+}
+
+size_t Debugger::GetProcessSTDERR(Process *process, Stream *stream) {
+ size_t total_bytes = 0;
+ if (stream == nullptr)
+ stream = GetOutputFile().get();
+
+ if (stream) {
+ // The process has stuff waiting for stderr; get it and write it out to the
+ // appropriate place.
+ if (process == nullptr) {
+ TargetSP target_sp = GetTargetList().GetSelectedTarget();
+ if (target_sp)
+ process = target_sp->GetProcessSP().get();
}
- return total_bytes;
+ if (process) {
+ Error error;
+ size_t len;
+ char stdio_buffer[1024];
+ while ((len = process->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
+ error)) > 0) {
+ stream->Write(stdio_buffer, len);
+ total_bytes += len;
+ }
+ }
+ stream->Flush();
+ }
+ return total_bytes;
}
-
// This function handles events that were broadcast by the process.
-void
-Debugger::HandleProcessEvent (const EventSP &event_sp)
-{
- using namespace lldb;
- const uint32_t event_type = event_sp->GetType();
- ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
-
- StreamSP output_stream_sp = GetAsyncOutputStream();
- StreamSP error_stream_sp = GetAsyncErrorStream();
- const bool gui_enabled = IsForwardingEvents();
-
- if (!gui_enabled)
- {
- bool pop_process_io_handler = false;
- assert (process_sp);
-
- bool state_is_stopped = false;
- const bool got_state_changed = (event_type & Process::eBroadcastBitStateChanged) != 0;
- const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
- const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
- if (got_state_changed)
- {
- StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
- state_is_stopped = StateIsStoppedState(event_state, false);
- }
-
- // Display running state changes first before any STDIO
- if (got_state_changed && !state_is_stopped)
- {
- Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
- }
-
- // Now display and STDOUT
- if (got_stdout || got_state_changed)
- {
- GetProcessSTDOUT (process_sp.get(), output_stream_sp.get());
- }
-
- // Now display and STDERR
- if (got_stderr || got_state_changed)
- {
- GetProcessSTDERR (process_sp.get(), error_stream_sp.get());
- }
+void Debugger::HandleProcessEvent(const EventSP &event_sp) {
+ using namespace lldb;
+ const uint32_t event_type = event_sp->GetType();
+ ProcessSP process_sp =
+ (event_type == Process::eBroadcastBitStructuredData)
+ ? EventDataStructuredData::GetProcessFromEvent(event_sp.get())
+ : Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
+
+ StreamSP output_stream_sp = GetAsyncOutputStream();
+ StreamSP error_stream_sp = GetAsyncErrorStream();
+ const bool gui_enabled = IsForwardingEvents();
+
+ if (!gui_enabled) {
+ bool pop_process_io_handler = false;
+ assert(process_sp);
+
+ bool state_is_stopped = false;
+ const bool got_state_changed =
+ (event_type & Process::eBroadcastBitStateChanged) != 0;
+ const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
+ const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
+ const bool got_structured_data =
+ (event_type & Process::eBroadcastBitStructuredData) != 0;
+
+ if (got_state_changed) {
+ StateType event_state =
+ Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+ state_is_stopped = StateIsStoppedState(event_state, false);
+ }
- // Now display any stopped state changes after any STDIO
- if (got_state_changed && state_is_stopped)
- {
- Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
- }
+ // Display running state changes first before any STDIO
+ if (got_state_changed && !state_is_stopped) {
+ Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
+ pop_process_io_handler);
+ }
- output_stream_sp->Flush();
- error_stream_sp->Flush();
+ // Now display and STDOUT
+ if (got_stdout || got_state_changed) {
+ GetProcessSTDOUT(process_sp.get(), output_stream_sp.get());
+ }
- if (pop_process_io_handler)
- process_sp->PopProcessIOHandler();
+ // Now display and STDERR
+ if (got_stderr || got_state_changed) {
+ GetProcessSTDERR(process_sp.get(), error_stream_sp.get());
}
-}
-void
-Debugger::HandleThreadEvent (const EventSP &event_sp)
-{
- // At present the only thread event we handle is the Frame Changed event,
- // and all we do for that is just reprint the thread status for that thread.
- using namespace lldb;
- const uint32_t event_type = event_sp->GetType();
- if (event_type == Thread::eBroadcastBitStackChanged ||
- event_type == Thread::eBroadcastBitThreadSelected )
- {
- ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
- if (thread_sp)
- {
- thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1);
+ // Give structured data events an opportunity to display.
+ if (got_structured_data) {
+ StructuredDataPluginSP plugin_sp =
+ EventDataStructuredData::GetPluginFromEvent(event_sp.get());
+ if (plugin_sp) {
+ auto structured_data_sp =
+ EventDataStructuredData::GetObjectFromEvent(event_sp.get());
+ if (output_stream_sp) {
+ StreamString content_stream;
+ Error error =
+ plugin_sp->GetDescription(structured_data_sp, content_stream);
+ if (error.Success()) {
+ if (!content_stream.GetString().empty()) {
+ // Add newline.
+ content_stream.PutChar('\n');
+ content_stream.Flush();
+
+ // Print it.
+ output_stream_sp->PutCString(content_stream.GetString());
+ }
+ } else {
+ error_stream_sp->Printf("Failed to print structured "
+ "data with plugin %s: %s",
+ plugin_sp->GetPluginName().AsCString(),
+ error.AsCString());
+ }
}
+ }
}
-}
-
-bool
-Debugger::IsForwardingEvents ()
-{
- return (bool)m_forward_listener_sp;
-}
-
-void
-Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
-{
- m_forward_listener_sp = listener_sp;
-}
-
-void
-Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
-{
- m_forward_listener_sp.reset();
-}
+ // Now display any stopped state changes after any STDIO
+ if (got_state_changed && state_is_stopped) {
+ Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
+ pop_process_io_handler);
+ }
-void
-Debugger::DefaultEventHandler()
-{
- ListenerSP listener_sp(GetListener());
- ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
- ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
- ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
- BroadcastEventSpec target_event_spec (broadcaster_class_target,
- Target::eBroadcastBitBreakpointChanged);
-
- BroadcastEventSpec process_event_spec (broadcaster_class_process,
- Process::eBroadcastBitStateChanged |
- Process::eBroadcastBitSTDOUT |
- Process::eBroadcastBitSTDERR);
-
- BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
- Thread::eBroadcastBitStackChanged |
- Thread::eBroadcastBitThreadSelected );
-
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, target_event_spec);
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, process_event_spec);
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, thread_event_spec);
- listener_sp->StartListeningForEvents (m_command_interpreter_ap.get(),
- CommandInterpreter::eBroadcastBitQuitCommandReceived |
- CommandInterpreter::eBroadcastBitAsynchronousOutputData |
- CommandInterpreter::eBroadcastBitAsynchronousErrorData );
-
- // Let the thread that spawned us know that we have started up and
- // that we are now listening to all required events so no events get missed
- m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
-
- bool done = false;
- while (!done)
- {
- EventSP event_sp;
- if (listener_sp->WaitForEvent(nullptr, event_sp))
- {
- if (event_sp)
- {
- Broadcaster *broadcaster = event_sp->GetBroadcaster();
- if (broadcaster)
- {
- uint32_t event_type = event_sp->GetType();
- ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
- if (broadcaster_class == broadcaster_class_process)
- {
- HandleProcessEvent (event_sp);
- }
- else if (broadcaster_class == broadcaster_class_target)
- {
- if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
- {
- HandleBreakpointEvent (event_sp);
- }
- }
- else if (broadcaster_class == broadcaster_class_thread)
- {
- HandleThreadEvent (event_sp);
- }
- else if (broadcaster == m_command_interpreter_ap.get())
- {
- if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
- {
- done = true;
- }
- else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
- {
- const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
- if (data && data[0])
- {
- StreamSP error_sp (GetAsyncErrorStream());
- if (error_sp)
- {
- error_sp->PutCString(data);
- error_sp->Flush();
- }
- }
- }
- else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
- {
- const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
- if (data && data[0])
- {
- StreamSP output_sp (GetAsyncOutputStream());
- if (output_sp)
- {
- output_sp->PutCString(data);
- output_sp->Flush();
- }
- }
- }
- }
+ output_stream_sp->Flush();
+ error_stream_sp->Flush();
+
+ if (pop_process_io_handler)
+ process_sp->PopProcessIOHandler();
+ }
+}
+
+void Debugger::HandleThreadEvent(const EventSP &event_sp) {
+ // At present the only thread event we handle is the Frame Changed event,
+ // and all we do for that is just reprint the thread status for that thread.
+ using namespace lldb;
+ const uint32_t event_type = event_sp->GetType();
+ const bool stop_format = true;
+ if (event_type == Thread::eBroadcastBitStackChanged ||
+ event_type == Thread::eBroadcastBitThreadSelected) {
+ ThreadSP thread_sp(
+ Thread::ThreadEventData::GetThreadFromEvent(event_sp.get()));
+ if (thread_sp) {
+ thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format);
+ }
+ }
+}
+
+bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; }
+
+void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) {
+ m_forward_listener_sp = listener_sp;
+}
+
+void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
+ m_forward_listener_sp.reset();
+}
+
+void Debugger::DefaultEventHandler() {
+ ListenerSP listener_sp(GetListener());
+ ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
+ BroadcastEventSpec target_event_spec(broadcaster_class_target,
+ Target::eBroadcastBitBreakpointChanged);
+
+ BroadcastEventSpec process_event_spec(
+ broadcaster_class_process,
+ Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT |
+ Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData);
+
+ BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
+ Thread::eBroadcastBitStackChanged |
+ Thread::eBroadcastBitThreadSelected);
+
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ target_event_spec);
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ process_event_spec);
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ thread_event_spec);
+ listener_sp->StartListeningForEvents(
+ m_command_interpreter_ap.get(),
+ CommandInterpreter::eBroadcastBitQuitCommandReceived |
+ CommandInterpreter::eBroadcastBitAsynchronousOutputData |
+ CommandInterpreter::eBroadcastBitAsynchronousErrorData);
+
+ // Let the thread that spawned us know that we have started up and
+ // that we are now listening to all required events so no events get missed
+ m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
+
+ bool done = false;
+ while (!done) {
+ EventSP event_sp;
+ if (listener_sp->GetEvent(event_sp, llvm::None)) {
+ if (event_sp) {
+ Broadcaster *broadcaster = event_sp->GetBroadcaster();
+ if (broadcaster) {
+ uint32_t event_type = event_sp->GetType();
+ ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
+ if (broadcaster_class == broadcaster_class_process) {
+ HandleProcessEvent(event_sp);
+ } else if (broadcaster_class == broadcaster_class_target) {
+ if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(
+ event_sp.get())) {
+ HandleBreakpointEvent(event_sp);
+ }
+ } else if (broadcaster_class == broadcaster_class_thread) {
+ HandleThreadEvent(event_sp);
+ } else if (broadcaster == m_command_interpreter_ap.get()) {
+ if (event_type &
+ CommandInterpreter::eBroadcastBitQuitCommandReceived) {
+ done = true;
+ } else if (event_type &
+ CommandInterpreter::eBroadcastBitAsynchronousErrorData) {
+ const char *data = reinterpret_cast<const char *>(
+ EventDataBytes::GetBytesFromEvent(event_sp.get()));
+ if (data && data[0]) {
+ StreamSP error_sp(GetAsyncErrorStream());
+ if (error_sp) {
+ error_sp->PutCString(data);
+ error_sp->Flush();
+ }
+ }
+ } else if (event_type & CommandInterpreter::
+ eBroadcastBitAsynchronousOutputData) {
+ const char *data = reinterpret_cast<const char *>(
+ EventDataBytes::GetBytesFromEvent(event_sp.get()));
+ if (data && data[0]) {
+ StreamSP output_sp(GetAsyncOutputStream());
+ if (output_sp) {
+ output_sp->PutCString(data);
+ output_sp->Flush();
}
-
- if (m_forward_listener_sp)
- m_forward_listener_sp->AddEvent(event_sp);
+ }
}
+ }
}
- }
-}
-
-lldb::thread_result_t
-Debugger::EventHandlerThread (lldb::thread_arg_t arg)
-{
- ((Debugger *)arg)->DefaultEventHandler();
- return NULL;
-}
-bool
-Debugger::StartEventHandlerThread()
-{
- if (!m_event_handler_thread.IsJoinable())
- {
- // We must synchronize with the DefaultEventHandler() thread to ensure
- // it is up and running and listening to events before we return from
- // this function. We do this by listening to events for the
- // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
- ListenerSP listener_sp(Listener::MakeListener("lldb.debugger.event-handler"));
- listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
-
- // Use larger 8MB stack for this thread
- m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler",
- EventHandlerThread,
- this,
- nullptr,
- g_debugger_event_thread_stack_bytes);
-
- // Make sure DefaultEventHandler() is running and listening to events before we return
- // from this function. We are only listening for events of type
- // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
- // to wait an infinite amount of time for it (nullptr timeout as the first parameter)
- lldb::EventSP event_sp;
- listener_sp->WaitForEvent(nullptr, event_sp);
+ if (m_forward_listener_sp)
+ m_forward_listener_sp->AddEvent(event_sp);
+ }
}
- return m_event_handler_thread.IsJoinable();
+ }
+}
+
+lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
+ ((Debugger *)arg)->DefaultEventHandler();
+ return NULL;
+}
+
+bool Debugger::StartEventHandlerThread() {
+ if (!m_event_handler_thread.IsJoinable()) {
+ // We must synchronize with the DefaultEventHandler() thread to ensure
+ // it is up and running and listening to events before we return from
+ // this function. We do this by listening to events for the
+ // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
+ ListenerSP listener_sp(
+ Listener::MakeListener("lldb.debugger.event-handler"));
+ listener_sp->StartListeningForEvents(&m_sync_broadcaster,
+ eBroadcastBitEventThreadIsListening);
+
+ // Use larger 8MB stack for this thread
+ m_event_handler_thread = ThreadLauncher::LaunchThread(
+ "lldb.debugger.event-handler", EventHandlerThread, this, nullptr,
+ g_debugger_event_thread_stack_bytes);
+
+ // Make sure DefaultEventHandler() is running and listening to events before
+ // we return
+ // from this function. We are only listening for events of type
+ // eBroadcastBitEventThreadIsListening so we don't need to check the event,
+ // we just need
+ // to wait an infinite amount of time for it (nullptr timeout as the first
+ // parameter)
+ lldb::EventSP event_sp;
+ listener_sp->GetEvent(event_sp, llvm::None);
+ }
+ return m_event_handler_thread.IsJoinable();
+}
+
+void Debugger::StopEventHandlerThread() {
+ if (m_event_handler_thread.IsJoinable()) {
+ GetCommandInterpreter().BroadcastEvent(
+ CommandInterpreter::eBroadcastBitQuitCommandReceived);
+ m_event_handler_thread.Join(nullptr);
+ }
+}
+
+lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
+ Debugger *debugger = (Debugger *)arg;
+ debugger->ExecuteIOHandlers();
+ debugger->StopEventHandlerThread();
+ return NULL;
+}
+
+bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
+
+bool Debugger::StartIOHandlerThread() {
+ if (!m_io_handler_thread.IsJoinable())
+ m_io_handler_thread = ThreadLauncher::LaunchThread(
+ "lldb.debugger.io-handler", IOHandlerThread, this, nullptr,
+ 8 * 1024 * 1024); // Use larger 8MB stack for this thread
+ return m_io_handler_thread.IsJoinable();
+}
+
+void Debugger::StopIOHandlerThread() {
+ if (m_io_handler_thread.IsJoinable()) {
+ if (m_input_file_sp)
+ m_input_file_sp->GetFile().Close();
+ m_io_handler_thread.Join(nullptr);
+ }
}
-void
-Debugger::StopEventHandlerThread()
-{
- if (m_event_handler_thread.IsJoinable())
- {
- GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
- m_event_handler_thread.Join(nullptr);
- }
+void Debugger::JoinIOHandlerThread() {
+ if (HasIOHandlerThread()) {
+ thread_result_t result;
+ m_io_handler_thread.Join(&result);
+ m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
+ }
}
-lldb::thread_result_t
-Debugger::IOHandlerThread (lldb::thread_arg_t arg)
-{
- Debugger *debugger = (Debugger *)arg;
- debugger->ExecuteIOHandlers();
- debugger->StopEventHandlerThread();
- return NULL;
+Target *Debugger::GetDummyTarget() {
+ return m_target_list.GetDummyTarget(*this).get();
}
-bool
-Debugger::HasIOHandlerThread()
-{
- return m_io_handler_thread.IsJoinable();
-}
+Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
+ Target *target = nullptr;
+ if (!prefer_dummy) {
+ target = m_target_list.GetSelectedTarget().get();
+ if (target)
+ return target;
+ }
-bool
-Debugger::StartIOHandlerThread()
-{
- if (!m_io_handler_thread.IsJoinable())
- m_io_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.io-handler",
- IOHandlerThread,
- this,
- nullptr,
- 8*1024*1024); // Use larger 8MB stack for this thread
- return m_io_handler_thread.IsJoinable();
+ return GetDummyTarget();
}
-void
-Debugger::StopIOHandlerThread()
-{
- if (m_io_handler_thread.IsJoinable())
- {
- if (m_input_file_sp)
- m_input_file_sp->GetFile().Close();
- m_io_handler_thread.Join(nullptr);
- }
-}
+Error Debugger::RunREPL(LanguageType language, const char *repl_options) {
+ Error err;
+ FileSpec repl_executable;
-void
-Debugger::JoinIOHandlerThread()
-{
- if (HasIOHandlerThread())
- {
- thread_result_t result;
- m_io_handler_thread.Join(&result);
- m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
- }
-}
+ if (language == eLanguageTypeUnknown) {
+ std::set<LanguageType> repl_languages;
-Target *
-Debugger::GetDummyTarget()
-{
- return m_target_list.GetDummyTarget (*this).get();
-}
+ Language::GetLanguagesSupportingREPLs(repl_languages);
-Target *
-Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
-{
- Target *target = nullptr;
- if (!prefer_dummy)
- {
- target = m_target_list.GetSelectedTarget().get();
- if (target)
- return target;
+ if (repl_languages.size() == 1) {
+ language = *repl_languages.begin();
+ } else if (repl_languages.empty()) {
+ err.SetErrorStringWithFormat(
+ "LLDB isn't configured with REPL support for any languages.");
+ return err;
+ } else {
+ err.SetErrorStringWithFormat(
+ "Multiple possible REPL languages. Please specify a language.");
+ return err;
}
-
- return GetDummyTarget();
-}
+ }
-Error
-Debugger::RunREPL (LanguageType language, const char *repl_options)
-{
- Error err;
- FileSpec repl_executable;
-
- if (language == eLanguageTypeUnknown)
- {
- std::set<LanguageType> repl_languages;
-
- Language::GetLanguagesSupportingREPLs(repl_languages);
-
- if (repl_languages.size() == 1)
- {
- language = *repl_languages.begin();
- }
- else if (repl_languages.empty())
- {
- err.SetErrorStringWithFormat("LLDB isn't configured with REPL support for any languages.");
- return err;
- }
- else
- {
- err.SetErrorStringWithFormat("Multiple possible REPL languages. Please specify a language.");
- return err;
- }
- }
+ Target *const target =
+ nullptr; // passing in an empty target means the REPL must create one
- Target *const target = nullptr; // passing in an empty target means the REPL must create one
-
- REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
+ REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
- if (!err.Success())
- {
- return err;
- }
-
- if (!repl_sp)
- {
- err.SetErrorStringWithFormat("couldn't find a REPL for %s", Language::GetNameForLanguageType(language));
- return err;
- }
-
- repl_sp->SetCompilerOptions(repl_options);
- repl_sp->RunLoop();
-
+ if (!err.Success()) {
+ return err;
+ }
+
+ if (!repl_sp) {
+ err.SetErrorStringWithFormat("couldn't find a REPL for %s",
+ Language::GetNameForLanguageType(language));
return err;
+ }
+
+ repl_sp->SetCompilerOptions(repl_options);
+ repl_sp->RunLoop();
+
+ return err;
}