130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 104a33d318SGreg Clayton #include "lldb/Core/Debugger.h" 114a33d318SGreg Clayton 12df370550SEugene Zelenko // C Includes 13df370550SEugene Zelenko // C++ Includes 144a33d318SGreg Clayton #include <map> 15*16ff8604SSaleem Abdulrasool #include <mutex> 164a33d318SGreg Clayton 17df370550SEugene Zelenko // Other libraries and framework includes 18705b1809SJason Molenda #include "llvm/ADT/StringRef.h" 19df370550SEugene Zelenko #include "llvm/Support/DynamicLibrary.h" 204becb37eSEnrico Granata 21df370550SEugene Zelenko // Project includes 2230fdc8d8SChris Lattner #include "lldb/lldb-private.h" 23554f68d3SGreg Clayton #include "lldb/Core/FormatEntity.h" 241f746071SGreg Clayton #include "lldb/Core/Module.h" 250d5a2bd6SJim Ingham #include "lldb/Core/PluginInterface.h" 26e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h" 277349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 2830fdc8d8SChris Lattner #include "lldb/Core/State.h" 295b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h" 30228063cdSJim Ingham #include "lldb/Core/StreamCallback.h" 3144d93782SGreg Clayton #include "lldb/Core/StreamFile.h" 321b654882SGreg Clayton #include "lldb/Core/StreamString.h" 33705b1809SJason Molenda #include "lldb/Core/StructuredData.h" 3430fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 354becb37eSEnrico Granata #include "lldb/Core/ValueObject.h" 366d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 375548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 385548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h" 39894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h" 403e7e915dSSean Callanan #include "lldb/Expression/REPL.h" 4193a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h" 4242ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h" 43a3406614SGreg Clayton #include "lldb/Host/Terminal.h" 4439de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h" 456611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 46633a29cfSZachary Turner #include "lldb/Interpreter/OptionValueProperties.h" 4767cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h" 4867cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 491f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 501f746071SGreg Clayton #include "lldb/Symbol/Function.h" 511f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 526d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h" 5330fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 543e7e915dSSean Callanan #include "lldb/Target/Language.h" 5530fdc8d8SChris Lattner #include "lldb/Target/Process.h" 561b654882SGreg Clayton #include "lldb/Target/RegisterContext.h" 575fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h" 581b654882SGreg Clayton #include "lldb/Target/StopInfo.h" 5984a53dfbSEnrico Granata #include "lldb/Target/Target.h" 6030fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 615a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h" 6230fdc8d8SChris Lattner 6330fdc8d8SChris Lattner using namespace lldb; 6430fdc8d8SChris Lattner using namespace lldb_private; 6530fdc8d8SChris Lattner 66ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1; 677c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024; 68ebc1bb27SCaroline Tice 691b654882SGreg Clayton #pragma mark Static Functions 701b654882SGreg Clayton 71*16ff8604SSaleem Abdulrasool static std::recursive_mutex & 721b654882SGreg Clayton GetDebuggerListMutex() 731b654882SGreg Clayton { 74*16ff8604SSaleem Abdulrasool static std::recursive_mutex g_mutex; 751b654882SGreg Clayton return g_mutex; 761b654882SGreg Clayton } 771b654882SGreg Clayton 781b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList; 791b654882SGreg Clayton 801b654882SGreg Clayton static DebuggerList & 811b654882SGreg Clayton GetDebuggerList() 821b654882SGreg Clayton { 831b654882SGreg Clayton // hide the static debugger list inside a singleton accessor to avoid 846a7f3338SBruce Mitchener // global init constructors 851b654882SGreg Clayton static DebuggerList g_list; 861b654882SGreg Clayton return g_list; 871b654882SGreg Clayton } 88e372b98dSGreg Clayton 89e372b98dSGreg Clayton OptionEnumValueElement 9067cc0636SGreg Clayton g_show_disassembly_enum_values[] = 91e372b98dSGreg Clayton { 9267cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, 938be74995SMohit K. Bhakkad { Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", "Show disassembly when there is no debug information."}, 9467cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, 9567cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, 96df370550SEugene Zelenko { 0, nullptr, nullptr } 97e372b98dSGreg Clayton }; 98e372b98dSGreg Clayton 9967cc0636SGreg Clayton OptionEnumValueElement 10067cc0636SGreg Clayton g_language_enumerators[] = 10167cc0636SGreg Clayton { 10267cc0636SGreg Clayton { eScriptLanguageNone, "none", "Disable scripting languages."}, 10367cc0636SGreg Clayton { eScriptLanguagePython, "python", "Select python as the default scripting language."}, 10467cc0636SGreg Clayton { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."}, 105df370550SEugene Zelenko { 0, nullptr, nullptr } 10667cc0636SGreg Clayton }; 107e372b98dSGreg Clayton 10867cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" 10967cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 1106ab659a9SJason Molenda #define IS_OPTIMIZED "{${function.is-optimized} [opt]}" 11167cc0636SGreg Clayton 1120769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ 11367cc0636SGreg Clayton "{, ${frame.pc}}"\ 11467cc0636SGreg Clayton MODULE_WITH_FUNC\ 11567cc0636SGreg Clayton FILE_AND_LINE\ 1160769b2b1SMichael Sartain "{, name = '${thread.name}'}"\ 1170769b2b1SMichael Sartain "{, queue = '${thread.queue}'}"\ 118705b1809SJason Molenda "{, activity = '${thread.info.activity.name}'}" \ 119705b1809SJason Molenda "{, ${thread.info.trace_messages} messages}" \ 12067cc0636SGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 12167cc0636SGreg Clayton "{\\nReturn value: ${thread.return-value}}"\ 12230fadafeSJim Ingham "{\\nCompleted expression: ${thread.completed-expression}}"\ 12367cc0636SGreg Clayton "\\n" 12467cc0636SGreg Clayton 12567cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 12667cc0636SGreg Clayton MODULE_WITH_FUNC\ 12767cc0636SGreg Clayton FILE_AND_LINE\ 1286ab659a9SJason Molenda IS_OPTIMIZED\ 12967cc0636SGreg Clayton "\\n" 13067cc0636SGreg Clayton 131c980fa92SJason Molenda // Three parts to this disassembly format specification: 132c980fa92SJason Molenda // 1. If this is a new function/symbol (no previous symbol/function), print 133c980fa92SJason Molenda // dylib`funcname:\n 134c980fa92SJason Molenda // 2. If this is a symbol context change (different from previous symbol/function), print 135c980fa92SJason Molenda // dylib`funcname:\n 136c980fa92SJason Molenda // 3. print 137c980fa92SJason Molenda // address <+offset>: 138c980fa92SJason Molenda #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}>}: " 139c980fa92SJason Molenda 140c980fa92SJason Molenda // gdb's disassembly format can be emulated with 141c980fa92SJason Molenda // ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: 142c980fa92SJason Molenda 143c980fa92SJason Molenda // lldb's original format for disassembly would look like this format string - 144c980fa92SJason Molenda // {${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}}: 145c980fa92SJason Molenda 146754a9369SGreg Clayton static PropertyDefinition 147754a9369SGreg Clayton g_properties[] = 14867cc0636SGreg Clayton { 149df370550SEugene Zelenko { "auto-confirm", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "If true all confirmation prompts will receive their default reply." }, 150df370550SEugene Zelenko { "disassembly-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_DISASSEMBLY_FORMAT, nullptr, "The default disassembly format string to use when disassembling instruction sequences." }, 151df370550SEugene Zelenko { "frame-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_FRAME_FORMAT, nullptr, "The default frame format string to use when displaying stack frame information for threads." }, 152df370550SEugene Zelenko { "notify-void", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Notify the user explicitly if an expression returns void (default: false)." }, 153df370550SEugene Zelenko { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", nullptr, "The debugger command line prompt displayed for the user." }, 154df370550SEugene Zelenko { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, nullptr, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 155df370550SEugene Zelenko { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , nullptr, nullptr, "The number of disassembly lines to show when displaying a stopped context." }, 156df370550SEugene Zelenko { "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." }, 157df370550SEugene Zelenko { "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." }, 158df370550SEugene Zelenko { "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." }, 159df370550SEugene Zelenko { "term-width", OptionValue::eTypeSInt64 , true, 80 , nullptr, nullptr, "The maximum number of columns to use for displaying text." }, 160df370550SEugene Zelenko { "thread-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use when displaying thread information." }, 161df370550SEugene Zelenko { "use-external-editor", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Whether to use an external editor or not." }, 162df370550SEugene Zelenko { "use-color", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "Whether to use Ansi color codes or not." }, 163df370550SEugene Zelenko { "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically display small structs in one-liner format (default: true)." }, 164df370550SEugene Zelenko { "auto-indent", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true)." }, 165df370550SEugene Zelenko { "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)." }, 166df370550SEugene Zelenko { "tab-size", OptionValue::eTypeUInt64 , true, 4 , nullptr, nullptr, "The tab size to use when indenting code in multi-line input mode (default: 4)." }, 167df370550SEugene Zelenko { "escape-non-printables", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." }, 168df370550SEugene Zelenko { nullptr, OptionValue::eTypeInvalid , true, 0 , nullptr, nullptr, nullptr } 16967cc0636SGreg Clayton }; 17067cc0636SGreg Clayton 17167cc0636SGreg Clayton enum 17267cc0636SGreg Clayton { 17367cc0636SGreg Clayton ePropertyAutoConfirm = 0, 174aff1b357SJason Molenda ePropertyDisassemblyFormat, 17567cc0636SGreg Clayton ePropertyFrameFormat, 17667cc0636SGreg Clayton ePropertyNotiftVoid, 17767cc0636SGreg Clayton ePropertyPrompt, 17867cc0636SGreg Clayton ePropertyScriptLanguage, 17967cc0636SGreg Clayton ePropertyStopDisassemblyCount, 18067cc0636SGreg Clayton ePropertyStopDisassemblyDisplay, 18167cc0636SGreg Clayton ePropertyStopLineCountAfter, 18267cc0636SGreg Clayton ePropertyStopLineCountBefore, 18367cc0636SGreg Clayton ePropertyTerminalWidth, 18467cc0636SGreg Clayton ePropertyThreadFormat, 185c3ce7f27SMichael Sartain ePropertyUseExternalEditor, 186c3ce7f27SMichael Sartain ePropertyUseColor, 187ebdc1ac0SEnrico Granata ePropertyAutoOneLineSummaries, 1886681041dSSean Callanan ePropertyAutoIndent, 1896681041dSSean Callanan ePropertyPrintDecls, 1906681041dSSean Callanan ePropertyTabSize, 191ebdc1ac0SEnrico Granata ePropertyEscapeNonPrintables 19267cc0636SGreg Clayton }; 19367cc0636SGreg Clayton 194df370550SEugene Zelenko LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr; 1954c05410fSGreg Clayton 1964c05410fSGreg Clayton Error 1974c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 1984c05410fSGreg Clayton VarSetOperationType op, 1994c05410fSGreg Clayton const char *property_path, 2004c05410fSGreg Clayton const char *value) 2014c05410fSGreg Clayton { 20284a53dfbSEnrico Granata bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0; 203ebdc1ac0SEnrico Granata bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0; 20484a53dfbSEnrico Granata TargetSP target_sp; 205397ddd5fSEnrico Granata LoadScriptFromSymFile load_script_old_value; 20684a53dfbSEnrico Granata if (is_load_script && exe_ctx->GetTargetSP()) 20784a53dfbSEnrico Granata { 20884a53dfbSEnrico Granata target_sp = exe_ctx->GetTargetSP(); 20984a53dfbSEnrico Granata load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 21084a53dfbSEnrico Granata } 2114c05410fSGreg Clayton Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 2124c05410fSGreg Clayton if (error.Success()) 2134c05410fSGreg Clayton { 21484a53dfbSEnrico Granata // FIXME it would be nice to have "on-change" callbacks for properties 2154c05410fSGreg Clayton if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 2164c05410fSGreg Clayton { 2174c05410fSGreg Clayton const char *new_prompt = GetPrompt(); 218c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 219c3ce7f27SMichael Sartain if (str.length()) 220c3ce7f27SMichael Sartain new_prompt = str.c_str(); 22144d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 2224c05410fSGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 2234c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 2244c05410fSGreg Clayton } 225c3ce7f27SMichael Sartain else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0) 226c3ce7f27SMichael Sartain { 227c3ce7f27SMichael Sartain // use-color changed. Ping the prompt so it can reset the ansi terminal codes. 228c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 229c3ce7f27SMichael Sartain } 230397ddd5fSEnrico Granata else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) 23184a53dfbSEnrico Granata { 232397ddd5fSEnrico Granata if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue) 23384a53dfbSEnrico Granata { 23484a53dfbSEnrico Granata std::list<Error> errors; 2359730339bSEnrico Granata StreamString feedback_stream; 2369730339bSEnrico Granata if (!target_sp->LoadScriptingResources(errors,&feedback_stream)) 23784a53dfbSEnrico Granata { 23844d93782SGreg Clayton StreamFileSP stream_sp (GetErrorFile()); 23944d93782SGreg Clayton if (stream_sp) 24044d93782SGreg Clayton { 24184a53dfbSEnrico Granata for (auto error : errors) 24284a53dfbSEnrico Granata { 24344d93782SGreg Clayton stream_sp->Printf("%s\n",error.AsCString()); 24484a53dfbSEnrico Granata } 2459730339bSEnrico Granata if (feedback_stream.GetSize()) 24644d93782SGreg Clayton stream_sp->Printf("%s",feedback_stream.GetData()); 24744d93782SGreg Clayton } 24884a53dfbSEnrico Granata } 24984a53dfbSEnrico Granata } 25084a53dfbSEnrico Granata } 251ebdc1ac0SEnrico Granata else if (is_escape_non_printables) 252ebdc1ac0SEnrico Granata { 253ebdc1ac0SEnrico Granata DataVisualization::ForceUpdate(); 254ebdc1ac0SEnrico Granata } 2554c05410fSGreg Clayton } 2564c05410fSGreg Clayton return error; 2574c05410fSGreg Clayton } 2584c05410fSGreg Clayton 25967cc0636SGreg Clayton bool 26067cc0636SGreg Clayton Debugger::GetAutoConfirm () const 26167cc0636SGreg Clayton { 26267cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 263df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); 26467cc0636SGreg Clayton } 26567cc0636SGreg Clayton 266554f68d3SGreg Clayton const FormatEntity::Entry * 267aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const 268aff1b357SJason Molenda { 269aff1b357SJason Molenda const uint32_t idx = ePropertyDisassemblyFormat; 270df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 271aff1b357SJason Molenda } 272aff1b357SJason Molenda 273554f68d3SGreg Clayton const FormatEntity::Entry * 27467cc0636SGreg Clayton Debugger::GetFrameFormat() const 27567cc0636SGreg Clayton { 27667cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 277df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 27867cc0636SGreg Clayton } 27967cc0636SGreg Clayton 28067cc0636SGreg Clayton bool 28167cc0636SGreg Clayton Debugger::GetNotifyVoid () const 28267cc0636SGreg Clayton { 28367cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 284df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); 28567cc0636SGreg Clayton } 28667cc0636SGreg Clayton 28767cc0636SGreg Clayton const char * 28867cc0636SGreg Clayton Debugger::GetPrompt() const 28967cc0636SGreg Clayton { 29067cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 291df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, g_properties[idx].default_cstr_value); 29267cc0636SGreg Clayton } 29367cc0636SGreg Clayton 29467cc0636SGreg Clayton void 29567cc0636SGreg Clayton Debugger::SetPrompt(const char *p) 29667cc0636SGreg Clayton { 29767cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 298df370550SEugene Zelenko m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p); 29967cc0636SGreg Clayton const char *new_prompt = GetPrompt(); 300c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 301c3ce7f27SMichael Sartain if (str.length()) 302c3ce7f27SMichael Sartain new_prompt = str.c_str(); 30344d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 30467cc0636SGreg Clayton } 30567cc0636SGreg Clayton 306554f68d3SGreg Clayton const FormatEntity::Entry * 30767cc0636SGreg Clayton Debugger::GetThreadFormat() const 30867cc0636SGreg Clayton { 30967cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 310df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); 31167cc0636SGreg Clayton } 31267cc0636SGreg Clayton 31367cc0636SGreg Clayton lldb::ScriptLanguage 31467cc0636SGreg Clayton Debugger::GetScriptLanguage() const 31567cc0636SGreg Clayton { 31667cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 317df370550SEugene Zelenko return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value); 31867cc0636SGreg Clayton } 31967cc0636SGreg Clayton 32067cc0636SGreg Clayton bool 32167cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 32267cc0636SGreg Clayton { 32367cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 324df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, script_lang); 32567cc0636SGreg Clayton } 32667cc0636SGreg Clayton 32767cc0636SGreg Clayton uint32_t 32867cc0636SGreg Clayton Debugger::GetTerminalWidth () const 32967cc0636SGreg Clayton { 33067cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 331df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value); 33267cc0636SGreg Clayton } 33367cc0636SGreg Clayton 33467cc0636SGreg Clayton bool 33567cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width) 33667cc0636SGreg Clayton { 33767cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 338df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width); 33967cc0636SGreg Clayton } 34067cc0636SGreg Clayton 34167cc0636SGreg Clayton bool 34267cc0636SGreg Clayton Debugger::GetUseExternalEditor () const 34367cc0636SGreg Clayton { 34467cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 345df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); 34667cc0636SGreg Clayton } 34767cc0636SGreg Clayton 34867cc0636SGreg Clayton bool 34967cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b) 35067cc0636SGreg Clayton { 35167cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 352df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 35367cc0636SGreg Clayton } 35467cc0636SGreg Clayton 355c3ce7f27SMichael Sartain bool 356c3ce7f27SMichael Sartain Debugger::GetUseColor () const 357c3ce7f27SMichael Sartain { 358c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 359df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0); 360c3ce7f27SMichael Sartain } 361c3ce7f27SMichael Sartain 362c3ce7f27SMichael Sartain bool 363c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b) 364c3ce7f27SMichael Sartain { 365c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 366df370550SEugene Zelenko bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 367c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 368c3ce7f27SMichael Sartain return ret; 369c3ce7f27SMichael Sartain } 370c3ce7f27SMichael Sartain 37167cc0636SGreg Clayton uint32_t 37267cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const 37367cc0636SGreg Clayton { 37467cc0636SGreg Clayton const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 375df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value); 37667cc0636SGreg Clayton } 37767cc0636SGreg Clayton 37867cc0636SGreg Clayton Debugger::StopDisassemblyType 37967cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const 38067cc0636SGreg Clayton { 38167cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 382df370550SEugene Zelenko return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value); 38367cc0636SGreg Clayton } 38467cc0636SGreg Clayton 38567cc0636SGreg Clayton uint32_t 38667cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const 38767cc0636SGreg Clayton { 38867cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 389df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value); 39067cc0636SGreg Clayton } 391e372b98dSGreg Clayton 392553fad5cSEnrico Granata bool 39390a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const 394553fad5cSEnrico Granata { 39590a8db30SEnrico Granata const uint32_t idx = ePropertyAutoOneLineSummaries; 396df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 397ebdc1ac0SEnrico Granata } 398553fad5cSEnrico Granata 399ebdc1ac0SEnrico Granata bool 400ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const 401ebdc1ac0SEnrico Granata { 402ebdc1ac0SEnrico Granata const uint32_t idx = ePropertyEscapeNonPrintables; 403df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 404553fad5cSEnrico Granata } 405553fad5cSEnrico Granata 4066681041dSSean Callanan bool 4076681041dSSean Callanan Debugger::GetAutoIndent () const 4086681041dSSean Callanan { 4096681041dSSean Callanan const uint32_t idx = ePropertyAutoIndent; 410df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 4116681041dSSean Callanan } 4126681041dSSean Callanan 4136681041dSSean Callanan bool 4146681041dSSean Callanan Debugger::SetAutoIndent (bool b) 4156681041dSSean Callanan { 4166681041dSSean Callanan const uint32_t idx = ePropertyAutoIndent; 417df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 4186681041dSSean Callanan } 4196681041dSSean Callanan 4206681041dSSean Callanan bool 4216681041dSSean Callanan Debugger::GetPrintDecls () const 4226681041dSSean Callanan { 4236681041dSSean Callanan const uint32_t idx = ePropertyPrintDecls; 424df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); 4256681041dSSean Callanan } 4266681041dSSean Callanan 4276681041dSSean Callanan bool 4286681041dSSean Callanan Debugger::SetPrintDecls (bool b) 4296681041dSSean Callanan { 4306681041dSSean Callanan const uint32_t idx = ePropertyPrintDecls; 431df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 4326681041dSSean Callanan } 4336681041dSSean Callanan 4346681041dSSean Callanan uint32_t 4356681041dSSean Callanan Debugger::GetTabSize () const 4366681041dSSean Callanan { 4376681041dSSean Callanan const uint32_t idx = ePropertyTabSize; 438df370550SEugene Zelenko return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_properties[idx].default_uint_value); 4396681041dSSean Callanan } 4406681041dSSean Callanan 4416681041dSSean Callanan bool 4426681041dSSean Callanan Debugger::SetTabSize (uint32_t tab_size) 4436681041dSSean Callanan { 4446681041dSSean Callanan const uint32_t idx = ePropertyTabSize; 445df370550SEugene Zelenko return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size); 4466681041dSSean Callanan } 4476681041dSSean Callanan 4481b654882SGreg Clayton #pragma mark Debugger 4491b654882SGreg Clayton 45067cc0636SGreg Clayton //const DebuggerPropertiesSP & 45167cc0636SGreg Clayton //Debugger::GetSettings() const 45267cc0636SGreg Clayton //{ 45367cc0636SGreg Clayton // return m_properties_sp; 45467cc0636SGreg Clayton //} 45567cc0636SGreg Clayton // 45699d0faf2SGreg Clayton 457e6e2bb38SZachary Turner static bool lldb_initialized = false; 45830fdc8d8SChris Lattner void 4595fb8f797SGreg Clayton Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) 46030fdc8d8SChris Lattner { 461e6e2bb38SZachary Turner assert(!lldb_initialized && "Debugger::Initialize called more than once!"); 462e6e2bb38SZachary Turner 463f196c931SRobert Flack lldb_initialized = true; 4645fb8f797SGreg Clayton g_load_plugin_callback = load_plugin_callback; 46599d0faf2SGreg Clayton } 46630fdc8d8SChris Lattner 467e6e2bb38SZachary Turner void 46830fdc8d8SChris Lattner Debugger::Terminate () 46930fdc8d8SChris Lattner { 470e6e2bb38SZachary Turner assert(lldb_initialized && "Debugger::Terminate called without a matching Debugger::Initialize!"); 471e6e2bb38SZachary Turner 47299d0faf2SGreg Clayton // Clear our master list of debugger objects 473*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 474f3cd1819SOleksiy Vyalov auto& debuggers = GetDebuggerList(); 475f3cd1819SOleksiy Vyalov for (const auto& debugger: debuggers) 476f3cd1819SOleksiy Vyalov debugger->Clear(); 477f3cd1819SOleksiy Vyalov 478f3cd1819SOleksiy Vyalov debuggers.clear(); 47930fdc8d8SChris Lattner } 48030fdc8d8SChris Lattner 48120bd37f7SCaroline Tice void 48220bd37f7SCaroline Tice Debugger::SettingsInitialize () 48320bd37f7SCaroline Tice { 4846920b52bSGreg Clayton Target::SettingsInitialize (); 48520bd37f7SCaroline Tice } 48620bd37f7SCaroline Tice 48720bd37f7SCaroline Tice void 48820bd37f7SCaroline Tice Debugger::SettingsTerminate () 48920bd37f7SCaroline Tice { 4906920b52bSGreg Clayton Target::SettingsTerminate (); 49120bd37f7SCaroline Tice } 49220bd37f7SCaroline Tice 49321dfcd9dSEnrico Granata bool 494e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error) 49521dfcd9dSEnrico Granata { 4965fb8f797SGreg Clayton if (g_load_plugin_callback) 497e743c782SEnrico Granata { 49858a559c0SZachary Turner llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error); 49958a559c0SZachary Turner if (dynlib.isValid()) 50021dfcd9dSEnrico Granata { 50158a559c0SZachary Turner m_loaded_plugins.push_back(dynlib); 50221dfcd9dSEnrico Granata return true; 50321dfcd9dSEnrico Granata } 5045fb8f797SGreg Clayton } 5055fb8f797SGreg Clayton else 5065fb8f797SGreg Clayton { 5075fb8f797SGreg Clayton // The g_load_plugin_callback is registered in SBDebugger::Initialize() 5085fb8f797SGreg Clayton // and if the public API layer isn't available (code is linking against 5095fb8f797SGreg Clayton // all of the internal LLDB static libraries), then we can't load plugins 5105fb8f797SGreg Clayton error.SetErrorString("Public API layer is not available"); 5115fb8f797SGreg Clayton } 51221dfcd9dSEnrico Granata return false; 51321dfcd9dSEnrico Granata } 51421dfcd9dSEnrico Granata 51521dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 516df370550SEugene Zelenko LoadPluginCallback(void *baton, 51721dfcd9dSEnrico Granata FileSpec::FileType file_type, 518df370550SEugene Zelenko const FileSpec &file_spec) 51921dfcd9dSEnrico Granata { 52021dfcd9dSEnrico Granata Error error; 52121dfcd9dSEnrico Granata 52221dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 5233cf443ddSMichael Sartain static ConstString g_solibext("so"); 52421dfcd9dSEnrico Granata 52521dfcd9dSEnrico Granata if (!baton) 52621dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 52721dfcd9dSEnrico Granata 52821dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 52921dfcd9dSEnrico Granata 53021dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 53121dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 53221dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 53321dfcd9dSEnrico Granata // file type information. 53421dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 53521dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 53621dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 53721dfcd9dSEnrico Granata { 53821dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 53921dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 54021dfcd9dSEnrico Granata 5413cf443ddSMichael Sartain if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 5423cf443ddSMichael Sartain plugin_file_spec.GetFileNameExtension() != g_solibext) 5433cf443ddSMichael Sartain { 54421dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 5453cf443ddSMichael Sartain } 54621dfcd9dSEnrico Granata 547e743c782SEnrico Granata Error plugin_load_error; 548e743c782SEnrico Granata debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 54921dfcd9dSEnrico Granata 55021dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 55121dfcd9dSEnrico Granata } 55221dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 55321dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 55421dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 55521dfcd9dSEnrico Granata { 55621dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 55721dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 5586a7f3338SBruce Mitchener // might be enumerating a file system that doesn't have correct file type 55921dfcd9dSEnrico Granata // information. 56021dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 56121dfcd9dSEnrico Granata } 56221dfcd9dSEnrico Granata 56321dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 56421dfcd9dSEnrico Granata } 56521dfcd9dSEnrico Granata 56621dfcd9dSEnrico Granata void 56721dfcd9dSEnrico Granata Debugger::InstanceInitialize () 56821dfcd9dSEnrico Granata { 56921dfcd9dSEnrico Granata FileSpec dir_spec; 57021dfcd9dSEnrico Granata const bool find_directories = true; 57121dfcd9dSEnrico Granata const bool find_files = true; 57221dfcd9dSEnrico Granata const bool find_other = true; 57321dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 57442ff0ad8SZachary Turner if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) 57521dfcd9dSEnrico Granata { 57621dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 57721dfcd9dSEnrico Granata { 57821dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 57921dfcd9dSEnrico Granata find_directories, 58021dfcd9dSEnrico Granata find_files, 58121dfcd9dSEnrico Granata find_other, 58221dfcd9dSEnrico Granata LoadPluginCallback, 58321dfcd9dSEnrico Granata this); 58421dfcd9dSEnrico Granata } 58521dfcd9dSEnrico Granata } 58621dfcd9dSEnrico Granata 58742ff0ad8SZachary Turner if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) 58821dfcd9dSEnrico Granata { 58921dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 59021dfcd9dSEnrico Granata { 59121dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 59221dfcd9dSEnrico Granata find_directories, 59321dfcd9dSEnrico Granata find_files, 59421dfcd9dSEnrico Granata find_other, 59521dfcd9dSEnrico Granata LoadPluginCallback, 59621dfcd9dSEnrico Granata this); 59721dfcd9dSEnrico Granata } 59821dfcd9dSEnrico Granata } 599e8cd0c98SGreg Clayton 600e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 60121dfcd9dSEnrico Granata } 60221dfcd9dSEnrico Granata 6036611103cSGreg Clayton DebuggerSP 604228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 6056611103cSGreg Clayton { 606228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 607e6e2bb38SZachary Turner if (lldb_initialized) 6086611103cSGreg Clayton { 609*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 6106611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 6116611103cSGreg Clayton } 61221dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 6136611103cSGreg Clayton return debugger_sp; 6146611103cSGreg Clayton } 6156611103cSGreg Clayton 616e02657b1SCaroline Tice void 6174d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 618e02657b1SCaroline Tice { 619df370550SEugene Zelenko if (!debugger_sp) 620e02657b1SCaroline Tice return; 621e02657b1SCaroline Tice 6228314c525SJim Ingham debugger_sp->Clear(); 6238314c525SJim Ingham 624e6e2bb38SZachary Turner if (lldb_initialized) 625c15f55e2SGreg Clayton { 626*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 627e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 628e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 629e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 630e02657b1SCaroline Tice { 631e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 632e02657b1SCaroline Tice { 633e02657b1SCaroline Tice debugger_list.erase (pos); 634e02657b1SCaroline Tice return; 635e02657b1SCaroline Tice } 636e02657b1SCaroline Tice } 637e02657b1SCaroline Tice } 638c15f55e2SGreg Clayton } 639e02657b1SCaroline Tice 6404d122c40SGreg Clayton DebuggerSP 6413df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 6423df9a8dfSCaroline Tice { 6434d122c40SGreg Clayton DebuggerSP debugger_sp; 644e6e2bb38SZachary Turner if (lldb_initialized) 6456920b52bSGreg Clayton { 646*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 6476920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 6486920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 6496920b52bSGreg Clayton 6506920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 6516920b52bSGreg Clayton { 652df370550SEugene Zelenko if ((*pos)->m_instance_name == instance_name) 6536920b52bSGreg Clayton { 6546920b52bSGreg Clayton debugger_sp = *pos; 6556920b52bSGreg Clayton break; 6566920b52bSGreg Clayton } 6576920b52bSGreg Clayton } 6586920b52bSGreg Clayton } 6593df9a8dfSCaroline Tice return debugger_sp; 6603df9a8dfSCaroline Tice } 6616611103cSGreg Clayton 6626611103cSGreg Clayton TargetSP 6636611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 6646611103cSGreg Clayton { 6654d122c40SGreg Clayton TargetSP target_sp; 666e6e2bb38SZachary Turner if (lldb_initialized) 667c15f55e2SGreg Clayton { 668*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 6696611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 6706611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 6716611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 6726611103cSGreg Clayton { 6736611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 6746611103cSGreg Clayton if (target_sp) 6756611103cSGreg Clayton break; 6766611103cSGreg Clayton } 677c15f55e2SGreg Clayton } 6786611103cSGreg Clayton return target_sp; 6796611103cSGreg Clayton } 6806611103cSGreg Clayton 681e4e45924SGreg Clayton TargetSP 682e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 683e4e45924SGreg Clayton { 684e4e45924SGreg Clayton TargetSP target_sp; 685e6e2bb38SZachary Turner if (lldb_initialized) 686c15f55e2SGreg Clayton { 687*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 688e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 689e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 690e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 691e4e45924SGreg Clayton { 692e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 693e4e45924SGreg Clayton if (target_sp) 694e4e45924SGreg Clayton break; 695e4e45924SGreg Clayton } 696c15f55e2SGreg Clayton } 697e4e45924SGreg Clayton return target_sp; 698e4e45924SGreg Clayton } 699e4e45924SGreg Clayton 700e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) : 701e6481c7eSJason Molenda UserID(g_unique_id++), 702e6481c7eSJason Molenda Properties(OptionValuePropertiesSP(new OptionValueProperties())), 703e6481c7eSJason Molenda m_input_file_sp(new StreamFile(stdin, false)), 704e6481c7eSJason Molenda m_output_file_sp(new StreamFile(stdout, false)), 705e6481c7eSJason Molenda m_error_file_sp(new StreamFile(stderr, false)), 706583bbb1dSJim Ingham m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()), 707e6481c7eSJason Molenda m_terminal_state(), 708e6481c7eSJason Molenda m_target_list(*this), 709e6481c7eSJason Molenda m_platform_list(), 710583bbb1dSJim Ingham m_listener_sp(Listener::MakeListener("lldb.Debugger")), 711e6481c7eSJason Molenda m_source_manager_ap(), 712e6481c7eSJason Molenda m_source_file_cache(), 713e6481c7eSJason Molenda m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)), 714e6481c7eSJason Molenda m_input_reader_stack(), 715e6481c7eSJason Molenda m_instance_name(), 716afa91e33SGreg Clayton m_loaded_plugins(), 717afa91e33SGreg Clayton m_event_handler_thread(), 718afa91e33SGreg Clayton m_io_handler_thread(), 7194329fe42SGreg Clayton m_sync_broadcaster(nullptr, "lldb.debugger.sync"), 7204329fe42SGreg Clayton m_forward_listener_sp(), 7214329fe42SGreg Clayton m_clear_once() 72230fdc8d8SChris Lattner { 72367cc0636SGreg Clayton char instance_cstr[256]; 72467cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 72567cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 726228063cdSJim Ingham if (log_callback) 727228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 7286611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 729ded470d3SGreg Clayton // Always add our default platform to the platform list 730615eb7e6SGreg Clayton PlatformSP default_platform_sp (Platform::GetHostPlatform()); 731df370550SEugene Zelenko assert(default_platform_sp); 732ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 73367cc0636SGreg Clayton 734754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 73567cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 73667cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 73767cc0636SGreg Clayton true, 73867cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 73963acdfdeSOleksiy Vyalov m_collection_sp->AppendProperty (ConstString("platform"), 74063acdfdeSOleksiy Vyalov ConstString("Platform settings."), 74163acdfdeSOleksiy Vyalov true, 74263acdfdeSOleksiy Vyalov Platform::GetGlobalPlatformProperties()->GetValueProperties()); 743df370550SEugene Zelenko if (m_command_interpreter_ap) 744754a9369SGreg Clayton { 745754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 746754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 747754a9369SGreg Clayton true, 748754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 749754a9369SGreg Clayton } 750df370550SEugene Zelenko OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(nullptr, ePropertyTerminalWidth); 75167cc0636SGreg Clayton term_width->SetMinimumValue(10); 75267cc0636SGreg Clayton term_width->SetMaximumValue(1024); 753c3ce7f27SMichael Sartain 754c3ce7f27SMichael Sartain // Turn off use-color if this is a dumb terminal. 755c3ce7f27SMichael Sartain const char *term = getenv ("TERM"); 756c3ce7f27SMichael Sartain if (term && !strcmp (term, "dumb")) 757c3ce7f27SMichael Sartain SetUseColor (false); 75830fdc8d8SChris Lattner } 75930fdc8d8SChris Lattner 76030fdc8d8SChris Lattner Debugger::~Debugger () 76130fdc8d8SChris Lattner { 7628314c525SJim Ingham Clear(); 7638314c525SJim Ingham } 7648314c525SJim Ingham 7658314c525SJim Ingham void 7668314c525SJim Ingham Debugger::Clear() 7678314c525SJim Ingham { 7684329fe42SGreg Clayton //---------------------------------------------------------------------- 7694329fe42SGreg Clayton // Make sure we call this function only once. With the C++ global 7704329fe42SGreg Clayton // destructor chain having a list of debuggers and with code that can be 7714329fe42SGreg Clayton // running on other threads, we need to ensure this doesn't happen 7724329fe42SGreg Clayton // multiple times. 7734329fe42SGreg Clayton // 7744329fe42SGreg Clayton // The following functions call Debugger::Clear(): 7754329fe42SGreg Clayton // Debugger::~Debugger(); 7764329fe42SGreg Clayton // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp); 7774329fe42SGreg Clayton // static void Debugger::Terminate(); 7784329fe42SGreg Clayton //---------------------------------------------------------------------- 7794329fe42SGreg Clayton std::call_once(m_clear_once, [this]() { 78044d93782SGreg Clayton ClearIOHandlers(); 78144d93782SGreg Clayton StopIOHandlerThread(); 78244d93782SGreg Clayton StopEventHandlerThread(); 783583bbb1dSJim Ingham m_listener_sp->Clear(); 7846611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 7856611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 7866611103cSGreg Clayton { 787ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 788ccbc08e6SGreg Clayton if (target_sp) 789ccbc08e6SGreg Clayton { 790ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 7916611103cSGreg Clayton if (process_sp) 7921fd07059SJim Ingham process_sp->Finalize(); 793ccbc08e6SGreg Clayton target_sp->Destroy(); 7946611103cSGreg Clayton } 79530fdc8d8SChris Lattner } 796583bbb1dSJim Ingham m_broadcaster_manager_sp->Clear (); 79730fdc8d8SChris Lattner 7980d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 7990d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 800c5917d9aSJim Ingham m_terminal_state.Clear(); 80144d93782SGreg Clayton if (m_input_file_sp) 80244d93782SGreg Clayton m_input_file_sp->GetFile().Close (); 8030c4129f2SGreg Clayton 8040c4129f2SGreg Clayton m_command_interpreter_ap->Clear(); 8054329fe42SGreg Clayton }); 8068314c525SJim Ingham } 80730fdc8d8SChris Lattner 80830fdc8d8SChris Lattner bool 809fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 810fc3f027dSGreg Clayton { 81144d93782SGreg Clayton // return m_input_comm.GetCloseOnEOF(); 81244d93782SGreg Clayton return false; 813fc3f027dSGreg Clayton } 814fc3f027dSGreg Clayton 815fc3f027dSGreg Clayton void 816fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 817fc3f027dSGreg Clayton { 81844d93782SGreg Clayton // m_input_comm.SetCloseOnEOF(b); 819fc3f027dSGreg Clayton } 820fc3f027dSGreg Clayton 821fc3f027dSGreg Clayton bool 82230fdc8d8SChris Lattner Debugger::GetAsyncExecution () 82330fdc8d8SChris Lattner { 8246611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 82530fdc8d8SChris Lattner } 82630fdc8d8SChris Lattner 82730fdc8d8SChris Lattner void 82830fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 82930fdc8d8SChris Lattner { 8306611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 83130fdc8d8SChris Lattner } 83230fdc8d8SChris Lattner 83330fdc8d8SChris Lattner void 83430fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 83530fdc8d8SChris Lattner { 83644d93782SGreg Clayton if (m_input_file_sp) 83744d93782SGreg Clayton m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership); 83844d93782SGreg Clayton else 83944d93782SGreg Clayton m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 84044d93782SGreg Clayton 84144d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 842df370550SEugene Zelenko if (!in_file.IsValid()) 84351b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 84430fdc8d8SChris Lattner 845c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 846c5917d9aSJim Ingham SaveInputTerminalState (); 84730fdc8d8SChris Lattner } 84830fdc8d8SChris Lattner 84930fdc8d8SChris Lattner void 85030fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 85130fdc8d8SChris Lattner { 85244d93782SGreg Clayton if (m_output_file_sp) 85344d93782SGreg Clayton m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership); 85444d93782SGreg Clayton else 85544d93782SGreg Clayton m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 85644d93782SGreg Clayton 85744d93782SGreg Clayton File &out_file = m_output_file_sp->GetFile(); 858df370550SEugene Zelenko if (!out_file.IsValid()) 85951b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 8602f88aadfSCaroline Tice 861b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 862b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 863b588726eSEnrico Granata const bool can_create = false; 864b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 865b588726eSEnrico Granata if (script_interpreter) 866b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 86730fdc8d8SChris Lattner } 86830fdc8d8SChris Lattner 86930fdc8d8SChris Lattner void 87030fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 87130fdc8d8SChris Lattner { 87244d93782SGreg Clayton if (m_error_file_sp) 87344d93782SGreg Clayton m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership); 87444d93782SGreg Clayton else 87544d93782SGreg Clayton m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 87644d93782SGreg Clayton 87744d93782SGreg Clayton File &err_file = m_error_file_sp->GetFile(); 878df370550SEugene Zelenko if (!err_file.IsValid()) 87951b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 88030fdc8d8SChris Lattner } 88130fdc8d8SChris Lattner 882c5917d9aSJim Ingham void 883c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 884c5917d9aSJim Ingham { 88544d93782SGreg Clayton if (m_input_file_sp) 88644d93782SGreg Clayton { 88744d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 888c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 889c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 890c5917d9aSJim Ingham } 89144d93782SGreg Clayton } 892c5917d9aSJim Ingham 893c5917d9aSJim Ingham void 894c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 895c5917d9aSJim Ingham { 896c5917d9aSJim Ingham m_terminal_state.Restore(); 897c5917d9aSJim Ingham } 898c5917d9aSJim Ingham 89930fdc8d8SChris Lattner ExecutionContext 9002976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 90130fdc8d8SChris Lattner { 90230fdc8d8SChris Lattner ExecutionContext exe_ctx; 903c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 904c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 90530fdc8d8SChris Lattner 90630fdc8d8SChris Lattner if (target_sp) 90730fdc8d8SChris Lattner { 908c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 909c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 910df370550SEugene Zelenko if (process_sp && !process_sp->IsRunning()) 91130fdc8d8SChris Lattner { 912c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 913c14ee32dSGreg Clayton if (thread_sp) 91430fdc8d8SChris Lattner { 915c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 916c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 917df370550SEugene Zelenko if (exe_ctx.GetFramePtr() == nullptr) 918c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 91930fdc8d8SChris Lattner } 92030fdc8d8SChris Lattner } 92130fdc8d8SChris Lattner } 92230fdc8d8SChris Lattner return exe_ctx; 92330fdc8d8SChris Lattner } 92430fdc8d8SChris Lattner 92530fdc8d8SChris Lattner void 926efed6131SCaroline Tice Debugger::DispatchInputInterrupt() 927efed6131SCaroline Tice { 928*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 92944d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 930efed6131SCaroline Tice if (reader_sp) 93144d93782SGreg Clayton reader_sp->Interrupt(); 932efed6131SCaroline Tice } 933efed6131SCaroline Tice 934efed6131SCaroline Tice void 935efed6131SCaroline Tice Debugger::DispatchInputEndOfFile() 936efed6131SCaroline Tice { 937*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 93844d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 939efed6131SCaroline Tice if (reader_sp) 94044d93782SGreg Clayton reader_sp->GotEOF(); 941efed6131SCaroline Tice } 942efed6131SCaroline Tice 943efed6131SCaroline Tice void 94444d93782SGreg Clayton Debugger::ClearIOHandlers() 9453d6086f6SCaroline Tice { 946b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 947*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 948d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 9493d6086f6SCaroline Tice { 95044d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 9513d6086f6SCaroline Tice if (reader_sp) 9524446487dSPavel Labath PopIOHandler(reader_sp); 9533d6086f6SCaroline Tice } 9543d6086f6SCaroline Tice } 9553d6086f6SCaroline Tice 9563d6086f6SCaroline Tice void 9579aaab558SSiva Chandra Debugger::ExecuteIOHandlers() 958969ed3d1SCaroline Tice { 959df370550SEugene Zelenko while (true) 960969ed3d1SCaroline Tice { 96144d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 96230fdc8d8SChris Lattner if (!reader_sp) 96330fdc8d8SChris Lattner break; 96430fdc8d8SChris Lattner 96544d93782SGreg Clayton reader_sp->Run(); 96644d93782SGreg Clayton 96744d93782SGreg Clayton // Remove all input readers that are done from the top of the stack 968df370550SEugene Zelenko while (true) 96930fdc8d8SChris Lattner { 97044d93782SGreg Clayton IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); 97144d93782SGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 9724446487dSPavel Labath PopIOHandler (top_reader_sp); 97330fdc8d8SChris Lattner else 97430fdc8d8SChris Lattner break; 97530fdc8d8SChris Lattner } 97630fdc8d8SChris Lattner } 97744d93782SGreg Clayton ClearIOHandlers(); 97844d93782SGreg Clayton } 97930fdc8d8SChris Lattner 98044d93782SGreg Clayton bool 98144d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp) 98244d93782SGreg Clayton { 98344d93782SGreg Clayton return m_input_reader_stack.IsTop (reader_sp); 98444d93782SGreg Clayton } 98530fdc8d8SChris Lattner 9866681041dSSean Callanan bool 9876681041dSSean Callanan Debugger::CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type) 9886681041dSSean Callanan { 9896681041dSSean Callanan return m_input_reader_stack.CheckTopIOHandlerTypes (top_type, second_top_type); 9906681041dSSean Callanan } 9916681041dSSean Callanan 9924446487dSPavel Labath void 9934446487dSPavel Labath Debugger::PrintAsync (const char *s, size_t len, bool is_stdout) 9944446487dSPavel Labath { 9954446487dSPavel Labath lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile(); 9964446487dSPavel Labath m_input_reader_stack.PrintAsync(stream.get(), s, len); 9974446487dSPavel Labath } 99844d93782SGreg Clayton 99944d93782SGreg Clayton ConstString 100044d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch) 100144d93782SGreg Clayton { 100244d93782SGreg Clayton return m_input_reader_stack.GetTopIOHandlerControlSequence (ch); 100330fdc8d8SChris Lattner } 100430fdc8d8SChris Lattner 1005a487aa4cSKate Stone const char * 1006a487aa4cSKate Stone Debugger::GetIOHandlerCommandPrefix() 1007a487aa4cSKate Stone { 1008a487aa4cSKate Stone return m_input_reader_stack.GetTopIOHandlerCommandPrefix(); 1009a487aa4cSKate Stone } 1010a487aa4cSKate Stone 1011a487aa4cSKate Stone const char * 1012a487aa4cSKate Stone Debugger::GetIOHandlerHelpPrologue() 1013a487aa4cSKate Stone { 1014a487aa4cSKate Stone return m_input_reader_stack.GetTopIOHandlerHelpPrologue(); 1015a487aa4cSKate Stone } 1016a487aa4cSKate Stone 101730fdc8d8SChris Lattner void 101844d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp) 101944d93782SGreg Clayton { 102044d93782SGreg Clayton PushIOHandler (reader_sp); 1021577508dfSGreg Clayton 1022577508dfSGreg Clayton IOHandlerSP top_reader_sp = reader_sp; 1023577508dfSGreg Clayton while (top_reader_sp) 1024577508dfSGreg Clayton { 1025577508dfSGreg Clayton top_reader_sp->Run(); 1026577508dfSGreg Clayton 1027577508dfSGreg Clayton if (top_reader_sp.get() == reader_sp.get()) 1028577508dfSGreg Clayton { 1029577508dfSGreg Clayton if (PopIOHandler (reader_sp)) 1030577508dfSGreg Clayton break; 1031577508dfSGreg Clayton } 1032577508dfSGreg Clayton 1033df370550SEugene Zelenko while (true) 1034577508dfSGreg Clayton { 1035577508dfSGreg Clayton top_reader_sp = m_input_reader_stack.Top(); 1036577508dfSGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 10374446487dSPavel Labath PopIOHandler (top_reader_sp); 1038577508dfSGreg Clayton else 1039577508dfSGreg Clayton break; 1040577508dfSGreg Clayton } 1041577508dfSGreg Clayton } 104244d93782SGreg Clayton } 104344d93782SGreg Clayton 104444d93782SGreg Clayton void 104544d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, StreamFileSP &out, StreamFileSP &err) 104644d93782SGreg Clayton { 104744d93782SGreg Clayton // Before an IOHandler runs, it must have in/out/err streams. 104844d93782SGreg Clayton // This function is called when one ore more of the streams 1049df370550SEugene Zelenko // are nullptr. We use the top input reader's in/out/err streams, 105044d93782SGreg Clayton // or fall back to the debugger file handles, or we fall back 105144d93782SGreg Clayton // onto stdin/stdout/stderr as a last resort. 105244d93782SGreg Clayton 1053*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 105444d93782SGreg Clayton IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); 105544d93782SGreg Clayton // If no STDIN has been set, then set it appropriately 105644d93782SGreg Clayton if (!in) 105744d93782SGreg Clayton { 105844d93782SGreg Clayton if (top_reader_sp) 105944d93782SGreg Clayton in = top_reader_sp->GetInputStreamFile(); 106044d93782SGreg Clayton else 106144d93782SGreg Clayton in = GetInputFile(); 106244d93782SGreg Clayton 106344d93782SGreg Clayton // If there is nothing, use stdin 106444d93782SGreg Clayton if (!in) 106544d93782SGreg Clayton in = StreamFileSP(new StreamFile(stdin, false)); 106644d93782SGreg Clayton } 106744d93782SGreg Clayton // If no STDOUT has been set, then set it appropriately 106844d93782SGreg Clayton if (!out) 106944d93782SGreg Clayton { 107044d93782SGreg Clayton if (top_reader_sp) 107144d93782SGreg Clayton out = top_reader_sp->GetOutputStreamFile(); 107244d93782SGreg Clayton else 107344d93782SGreg Clayton out = GetOutputFile(); 107444d93782SGreg Clayton 107544d93782SGreg Clayton // If there is nothing, use stdout 107644d93782SGreg Clayton if (!out) 107744d93782SGreg Clayton out = StreamFileSP(new StreamFile(stdout, false)); 107844d93782SGreg Clayton } 107944d93782SGreg Clayton // If no STDERR has been set, then set it appropriately 108044d93782SGreg Clayton if (!err) 108144d93782SGreg Clayton { 108244d93782SGreg Clayton if (top_reader_sp) 108344d93782SGreg Clayton err = top_reader_sp->GetErrorStreamFile(); 108444d93782SGreg Clayton else 108544d93782SGreg Clayton err = GetErrorFile(); 108644d93782SGreg Clayton 108744d93782SGreg Clayton // If there is nothing, use stderr 108844d93782SGreg Clayton if (!err) 108944d93782SGreg Clayton err = StreamFileSP(new StreamFile(stdout, false)); 109044d93782SGreg Clayton } 109144d93782SGreg Clayton } 109244d93782SGreg Clayton 109344d93782SGreg Clayton void 109444d93782SGreg Clayton Debugger::PushIOHandler(const IOHandlerSP &reader_sp) 109530fdc8d8SChris Lattner { 109630fdc8d8SChris Lattner if (!reader_sp) 109730fdc8d8SChris Lattner return; 1098b44880caSCaroline Tice 1099*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 11004446487dSPavel Labath 11014446487dSPavel Labath // Get the current top input reader... 110244d93782SGreg Clayton IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); 1103b44880caSCaroline Tice 1104b4874f1aSGreg Clayton // Don't push the same IO handler twice... 11054446487dSPavel Labath if (reader_sp == top_reader_sp) 11064446487dSPavel Labath return; 11074446487dSPavel Labath 110844d93782SGreg Clayton // Push our new input reader 1109d5a0a01bSCaroline Tice m_input_reader_stack.Push(reader_sp); 11104446487dSPavel Labath reader_sp->Activate(); 111144d93782SGreg Clayton 111244d93782SGreg Clayton // Interrupt the top input reader to it will exit its Run() function 111344d93782SGreg Clayton // and let this new input reader take over 111444d93782SGreg Clayton if (top_reader_sp) 11154446487dSPavel Labath { 111644d93782SGreg Clayton top_reader_sp->Deactivate(); 11174446487dSPavel Labath top_reader_sp->Cancel(); 111830fdc8d8SChris Lattner } 1119b4874f1aSGreg Clayton } 112030fdc8d8SChris Lattner 112130fdc8d8SChris Lattner bool 112244d93782SGreg Clayton Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) 112330fdc8d8SChris Lattner { 11244446487dSPavel Labath if (!pop_reader_sp) 11254446487dSPavel Labath return false; 112630fdc8d8SChris Lattner 1127*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); 112844d93782SGreg Clayton 112930fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 11306a7f3338SBruce Mitchener // read on the stack refresh its prompt and if there is one... 11314446487dSPavel Labath if (m_input_reader_stack.IsEmpty()) 11324446487dSPavel Labath return false; 11334446487dSPavel Labath 113444d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 113530fdc8d8SChris Lattner 11364446487dSPavel Labath if (pop_reader_sp != reader_sp) 11374446487dSPavel Labath return false; 11384446487dSPavel Labath 113944d93782SGreg Clayton reader_sp->Deactivate(); 1140b4874f1aSGreg Clayton reader_sp->Cancel(); 1141d5a0a01bSCaroline Tice m_input_reader_stack.Pop(); 114230fdc8d8SChris Lattner 1143d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 114430fdc8d8SChris Lattner if (reader_sp) 114544d93782SGreg Clayton reader_sp->Activate(); 114644d93782SGreg Clayton 114744d93782SGreg Clayton return true; 114830fdc8d8SChris Lattner } 11496611103cSGreg Clayton 11505b52f0c7SJim Ingham StreamSP 11515b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 11525b52f0c7SJim Ingham { 11534446487dSPavel Labath return StreamSP (new StreamAsynchronousIO (*this, true)); 11545b52f0c7SJim Ingham } 11555b52f0c7SJim Ingham 11565b52f0c7SJim Ingham StreamSP 11575b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 11585b52f0c7SJim Ingham { 11594446487dSPavel Labath return StreamSP (new StreamAsynchronousIO (*this, false)); 11605b52f0c7SJim Ingham } 11615b52f0c7SJim Ingham 1162c7bece56SGreg Clayton size_t 1163061858ceSEnrico Granata Debugger::GetNumDebuggers() 1164061858ceSEnrico Granata { 1165e6e2bb38SZachary Turner if (lldb_initialized) 1166c15f55e2SGreg Clayton { 1167*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 1168061858ceSEnrico Granata return GetDebuggerList().size(); 1169061858ceSEnrico Granata } 1170c15f55e2SGreg Clayton return 0; 1171c15f55e2SGreg Clayton } 1172061858ceSEnrico Granata 1173061858ceSEnrico Granata lldb::DebuggerSP 1174c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1175061858ceSEnrico Granata { 1176061858ceSEnrico Granata DebuggerSP debugger_sp; 1177061858ceSEnrico Granata 1178e6e2bb38SZachary Turner if (lldb_initialized) 1179c15f55e2SGreg Clayton { 1180*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 1181061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1182061858ceSEnrico Granata 1183061858ceSEnrico Granata if (index < debugger_list.size()) 1184061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1185c15f55e2SGreg Clayton } 1186061858ceSEnrico Granata 1187061858ceSEnrico Granata return debugger_sp; 1188061858ceSEnrico Granata } 1189061858ceSEnrico Granata 1190ebc1bb27SCaroline Tice DebuggerSP 1191ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1192ebc1bb27SCaroline Tice { 11934d122c40SGreg Clayton DebuggerSP debugger_sp; 1194ebc1bb27SCaroline Tice 1195e6e2bb38SZachary Turner if (lldb_initialized) 1196c15f55e2SGreg Clayton { 1197*16ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(GetDebuggerListMutex()); 1198ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1199ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1200ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1201ebc1bb27SCaroline Tice { 1202df370550SEugene Zelenko if ((*pos)->GetID() == id) 1203ebc1bb27SCaroline Tice { 1204ebc1bb27SCaroline Tice debugger_sp = *pos; 1205ebc1bb27SCaroline Tice break; 1206ebc1bb27SCaroline Tice } 1207ebc1bb27SCaroline Tice } 1208c15f55e2SGreg Clayton } 1209ebc1bb27SCaroline Tice return debugger_sp; 1210ebc1bb27SCaroline Tice } 12113df9a8dfSCaroline Tice 12122643b905SSaleem Abdulrasool #if 0 12131b654882SGreg Clayton static void 1214b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame) 12151b654882SGreg Clayton { 1216df370550SEugene Zelenko if (frame == nullptr) 12171b654882SGreg Clayton return; 12181b654882SGreg Clayton 12191b654882SGreg Clayton StreamString s; 12201b654882SGreg Clayton const char *prompt_format = 12211b654882SGreg Clayton "{addr = '${addr}'\n}" 1222aff1b357SJason Molenda "{addr-file-or-load = '${addr-file-or-load}'\n}" 1223aff1b357SJason Molenda "{current-pc-arrow = '${current-pc-arrow}'\n}" 12241b654882SGreg Clayton "{process.id = '${process.id}'\n}" 12251b654882SGreg Clayton "{process.name = '${process.name}'\n}" 12261b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 12271b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 12281b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 12291b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 12301b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 12311b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 12321b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 12331b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 12341b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 12351b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 12361b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 12371b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 12381b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 12391b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 12401b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 12411b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 12421b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 12431b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 12441b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 12451b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 12461b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 12471b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 12481b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 12491b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 12501b654882SGreg Clayton "{function.id = '${function.id}'\n}" 1251aff1b357SJason Molenda "{function.changed = '${function.changed}'\n}" 1252aff1b357SJason Molenda "{function.initial-function = '${function.initial-function}'\n}" 12531b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1254aff1b357SJason Molenda "{function.name-without-args = '${function.name-without-args}'\n}" 1255ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 12561b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 1257aff1b357SJason Molenda "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}" 12581b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 12591b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 12601b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 12611b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 12621b654882SGreg Clayton "{line.number = '${line.number}'\n}" 12631b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 12641b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 12651b654882SGreg Clayton ; 12661b654882SGreg Clayton 12671b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 12681b654882SGreg Clayton ExecutionContext exe_ctx; 12690603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 1270c3ce7f27SMichael Sartain if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 12711b654882SGreg Clayton { 12721b654882SGreg Clayton printf("%s\n", s.GetData()); 12731b654882SGreg Clayton } 12741b654882SGreg Clayton else 12751b654882SGreg Clayton { 12761b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 12771b654882SGreg Clayton } 12781b654882SGreg Clayton } 12792643b905SSaleem Abdulrasool #endif 12801b654882SGreg Clayton 1281c3ce7f27SMichael Sartain bool 1282554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format, 1283aff1b357SJason Molenda const SymbolContext *sc, 1284aff1b357SJason Molenda const SymbolContext *prev_sc, 1285aff1b357SJason Molenda const ExecutionContext *exe_ctx, 1286aff1b357SJason Molenda const Address *addr, 1287aff1b357SJason Molenda Stream &s) 1288aff1b357SJason Molenda { 1289554f68d3SGreg Clayton FormatEntity::Entry format_entry; 1290554f68d3SGreg Clayton 1291df370550SEugene Zelenko if (format == nullptr) 1292aff1b357SJason Molenda { 1293df370550SEugene Zelenko if (exe_ctx != nullptr && exe_ctx->HasTargetScope()) 1294aff1b357SJason Molenda format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat(); 1295df370550SEugene Zelenko if (format == nullptr) 1296554f68d3SGreg Clayton { 1297554f68d3SGreg Clayton FormatEntity::Parse("${addr}: ", format_entry); 1298554f68d3SGreg Clayton format = &format_entry; 1299554f68d3SGreg Clayton } 1300aff1b357SJason Molenda } 1301aff1b357SJason Molenda bool function_changed = false; 1302aff1b357SJason Molenda bool initial_function = false; 1303aff1b357SJason Molenda if (prev_sc && (prev_sc->function || prev_sc->symbol)) 1304aff1b357SJason Molenda { 1305aff1b357SJason Molenda if (sc && (sc->function || sc->symbol)) 1306aff1b357SJason Molenda { 1307aff1b357SJason Molenda if (prev_sc->symbol && sc->symbol) 1308aff1b357SJason Molenda { 1309aff1b357SJason Molenda if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType())) 1310aff1b357SJason Molenda { 1311aff1b357SJason Molenda function_changed = true; 1312aff1b357SJason Molenda } 1313aff1b357SJason Molenda } 1314aff1b357SJason Molenda else if (prev_sc->function && sc->function) 1315aff1b357SJason Molenda { 1316aff1b357SJason Molenda if (prev_sc->function->GetMangled() != sc->function->GetMangled()) 1317aff1b357SJason Molenda { 1318aff1b357SJason Molenda function_changed = true; 1319aff1b357SJason Molenda } 1320aff1b357SJason Molenda } 1321aff1b357SJason Molenda } 1322aff1b357SJason Molenda } 1323aff1b357SJason Molenda // The first context on a list of instructions will have a prev_sc that 1324aff1b357SJason Molenda // has no Function or Symbol -- if SymbolContext had an IsValid() method, it 1325aff1b357SJason Molenda // would return false. But we do get a prev_sc pointer. 1326aff1b357SJason Molenda if ((sc && (sc->function || sc->symbol)) 1327df370550SEugene Zelenko && prev_sc && (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) 1328aff1b357SJason Molenda { 1329aff1b357SJason Molenda initial_function = true; 1330aff1b357SJason Molenda } 1331df370550SEugene Zelenko return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, function_changed, initial_function); 1332aff1b357SJason Molenda } 1333aff1b357SJason Molenda 1334228063cdSJim Ingham void 1335228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 1336228063cdSJim Ingham { 13374f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 13384f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 13394f02b22dSJim Ingham // callback. 1340228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 1341228063cdSJim Ingham } 1342228063cdSJim Ingham 1343228063cdSJim Ingham bool 1344228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 1345228063cdSJim Ingham { 1346228063cdSJim Ingham StreamSP log_stream_sp; 13479a028519SSean Callanan if (m_log_callback_stream_sp) 1348228063cdSJim Ingham { 1349228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 1350228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 1351228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 1352228063cdSJim Ingham } 1353df370550SEugene Zelenko else if (log_file == nullptr || *log_file == '\0') 1354228063cdSJim Ingham { 135544d93782SGreg Clayton log_stream_sp = GetOutputFile(); 1356228063cdSJim Ingham } 1357228063cdSJim Ingham else 1358228063cdSJim Ingham { 1359228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 1360c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 1361c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 1362c1b2ccfdSGreg Clayton if (!log_stream_sp) 1363228063cdSJim Ingham { 13648ac06996SPavel Labath uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate 13658ac06996SPavel Labath | File::eOpenOptionCloseOnExec | File::eOpenOptionAppend; 13668ac06996SPavel Labath if (! (log_options & LLDB_LOG_OPTION_APPEND)) 13678ac06996SPavel Labath options |= File::eOpenOptionTruncate; 13688ac06996SPavel Labath 13698ac06996SPavel Labath log_stream_sp.reset (new StreamFile (log_file, options)); 1370228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 1371228063cdSJim Ingham } 1372228063cdSJim Ingham } 1373df370550SEugene Zelenko assert(log_stream_sp); 1374228063cdSJim Ingham 1375228063cdSJim Ingham if (log_options == 0) 1376228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 1377228063cdSJim Ingham 13789c9ecce0STamas Berghammer return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, error_stream); 1379228063cdSJim Ingham } 1380228063cdSJim Ingham 13819585fbfcSGreg Clayton SourceManager & 13829585fbfcSGreg Clayton Debugger::GetSourceManager () 13839585fbfcSGreg Clayton { 1384df370550SEugene Zelenko if (!m_source_manager_ap) 13859585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 13869585fbfcSGreg Clayton return *m_source_manager_ap; 13879585fbfcSGreg Clayton } 13889585fbfcSGreg Clayton 138944d93782SGreg Clayton // This function handles events that were broadcast by the process. 139044d93782SGreg Clayton void 139144d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp) 139244d93782SGreg Clayton { 139344d93782SGreg Clayton using namespace lldb; 139444d93782SGreg Clayton const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp); 139544d93782SGreg Clayton 139644d93782SGreg Clayton // if (event_type & eBreakpointEventTypeAdded 139744d93782SGreg Clayton // || event_type & eBreakpointEventTypeRemoved 139844d93782SGreg Clayton // || event_type & eBreakpointEventTypeEnabled 139944d93782SGreg Clayton // || event_type & eBreakpointEventTypeDisabled 140044d93782SGreg Clayton // || event_type & eBreakpointEventTypeCommandChanged 140144d93782SGreg Clayton // || event_type & eBreakpointEventTypeConditionChanged 140244d93782SGreg Clayton // || event_type & eBreakpointEventTypeIgnoreChanged 140344d93782SGreg Clayton // || event_type & eBreakpointEventTypeLocationsResolved) 140444d93782SGreg Clayton // { 140544d93782SGreg Clayton // // Don't do anything about these events, since the breakpoint commands already echo these actions. 140644d93782SGreg Clayton // } 140744d93782SGreg Clayton // 140844d93782SGreg Clayton if (event_type & eBreakpointEventTypeLocationsAdded) 140944d93782SGreg Clayton { 141044d93782SGreg Clayton uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp); 141144d93782SGreg Clayton if (num_new_locations > 0) 141244d93782SGreg Clayton { 141344d93782SGreg Clayton BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 14144446487dSPavel Labath StreamSP output_sp (GetAsyncOutputStream()); 141544d93782SGreg Clayton if (output_sp) 141644d93782SGreg Clayton { 141744d93782SGreg Clayton output_sp->Printf("%d location%s added to breakpoint %d\n", 141844d93782SGreg Clayton num_new_locations, 141944d93782SGreg Clayton num_new_locations == 1 ? "" : "s", 142044d93782SGreg Clayton breakpoint->GetID()); 14214446487dSPavel Labath output_sp->Flush(); 142244d93782SGreg Clayton } 142344d93782SGreg Clayton } 142444d93782SGreg Clayton } 142544d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsRemoved) 142644d93782SGreg Clayton // { 142744d93782SGreg Clayton // // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 142844d93782SGreg Clayton // } 142944d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsResolved) 143044d93782SGreg Clayton // { 143144d93782SGreg Clayton // // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 143244d93782SGreg Clayton // } 143344d93782SGreg Clayton } 143444d93782SGreg Clayton 143544d93782SGreg Clayton size_t 143644d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream) 143744d93782SGreg Clayton { 143844d93782SGreg Clayton size_t total_bytes = 0; 1439df370550SEugene Zelenko if (stream == nullptr) 144044d93782SGreg Clayton stream = GetOutputFile().get(); 144144d93782SGreg Clayton 144244d93782SGreg Clayton if (stream) 144344d93782SGreg Clayton { 144444d93782SGreg Clayton // The process has stuff waiting for stdout; get it and write it out to the appropriate place. 1445df370550SEugene Zelenko if (process == nullptr) 144644d93782SGreg Clayton { 144744d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 144844d93782SGreg Clayton if (target_sp) 144944d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 145044d93782SGreg Clayton } 145144d93782SGreg Clayton if (process) 145244d93782SGreg Clayton { 145344d93782SGreg Clayton Error error; 145444d93782SGreg Clayton size_t len; 145544d93782SGreg Clayton char stdio_buffer[1024]; 145644d93782SGreg Clayton while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 145744d93782SGreg Clayton { 145844d93782SGreg Clayton stream->Write(stdio_buffer, len); 145944d93782SGreg Clayton total_bytes += len; 146044d93782SGreg Clayton } 146144d93782SGreg Clayton } 146244d93782SGreg Clayton stream->Flush(); 146344d93782SGreg Clayton } 146444d93782SGreg Clayton return total_bytes; 146544d93782SGreg Clayton } 146644d93782SGreg Clayton 146744d93782SGreg Clayton size_t 146844d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream) 146944d93782SGreg Clayton { 147044d93782SGreg Clayton size_t total_bytes = 0; 1471df370550SEugene Zelenko if (stream == nullptr) 147244d93782SGreg Clayton stream = GetOutputFile().get(); 147344d93782SGreg Clayton 147444d93782SGreg Clayton if (stream) 147544d93782SGreg Clayton { 147644d93782SGreg Clayton // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 1477df370550SEugene Zelenko if (process == nullptr) 147844d93782SGreg Clayton { 147944d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 148044d93782SGreg Clayton if (target_sp) 148144d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 148244d93782SGreg Clayton } 148344d93782SGreg Clayton if (process) 148444d93782SGreg Clayton { 148544d93782SGreg Clayton Error error; 148644d93782SGreg Clayton size_t len; 148744d93782SGreg Clayton char stdio_buffer[1024]; 148844d93782SGreg Clayton while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 148944d93782SGreg Clayton { 149044d93782SGreg Clayton stream->Write(stdio_buffer, len); 149144d93782SGreg Clayton total_bytes += len; 149244d93782SGreg Clayton } 149344d93782SGreg Clayton } 149444d93782SGreg Clayton stream->Flush(); 149544d93782SGreg Clayton } 149644d93782SGreg Clayton return total_bytes; 149744d93782SGreg Clayton } 149844d93782SGreg Clayton 1499dc6224e0SGreg Clayton 150044d93782SGreg Clayton // This function handles events that were broadcast by the process. 150144d93782SGreg Clayton void 150244d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp) 150344d93782SGreg Clayton { 150444d93782SGreg Clayton using namespace lldb; 150544d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 150644d93782SGreg Clayton ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 150744d93782SGreg Clayton 15084446487dSPavel Labath StreamSP output_stream_sp = GetAsyncOutputStream(); 15094446487dSPavel Labath StreamSP error_stream_sp = GetAsyncErrorStream(); 151044d93782SGreg Clayton const bool gui_enabled = IsForwardingEvents(); 151144d93782SGreg Clayton 1512b4874f1aSGreg Clayton if (!gui_enabled) 1513b4874f1aSGreg Clayton { 1514b4874f1aSGreg Clayton bool pop_process_io_handler = false; 151544d93782SGreg Clayton assert (process_sp); 151644d93782SGreg Clayton 15174446487dSPavel Labath bool state_is_stopped = false; 15184446487dSPavel Labath const bool got_state_changed = (event_type & Process::eBroadcastBitStateChanged) != 0; 15194446487dSPavel Labath const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0; 15204446487dSPavel Labath const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0; 15214446487dSPavel Labath if (got_state_changed) 152244d93782SGreg Clayton { 15234446487dSPavel Labath StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get()); 15244446487dSPavel Labath state_is_stopped = StateIsStoppedState(event_state, false); 152544d93782SGreg Clayton } 1526b4874f1aSGreg Clayton 15274446487dSPavel Labath // Display running state changes first before any STDIO 15284446487dSPavel Labath if (got_state_changed && !state_is_stopped) 152944d93782SGreg Clayton { 15304446487dSPavel Labath Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler); 153144d93782SGreg Clayton } 1532b4874f1aSGreg Clayton 15334446487dSPavel Labath // Now display and STDOUT 15344446487dSPavel Labath if (got_stdout || got_state_changed) 153544d93782SGreg Clayton { 15364446487dSPavel Labath GetProcessSTDOUT (process_sp.get(), output_stream_sp.get()); 153744d93782SGreg Clayton } 1538b4874f1aSGreg Clayton 15394446487dSPavel Labath // Now display and STDERR 15404446487dSPavel Labath if (got_stderr || got_state_changed) 1541b4874f1aSGreg Clayton { 15424446487dSPavel Labath GetProcessSTDERR (process_sp.get(), error_stream_sp.get()); 1543b4874f1aSGreg Clayton } 1544b4874f1aSGreg Clayton 15454446487dSPavel Labath // Now display any stopped state changes after any STDIO 15464446487dSPavel Labath if (got_state_changed && state_is_stopped) 1547b4874f1aSGreg Clayton { 15484446487dSPavel Labath Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler); 154944d93782SGreg Clayton } 155044d93782SGreg Clayton 15514446487dSPavel Labath output_stream_sp->Flush(); 15524446487dSPavel Labath error_stream_sp->Flush(); 155344d93782SGreg Clayton 1554b4874f1aSGreg Clayton if (pop_process_io_handler) 1555b4874f1aSGreg Clayton process_sp->PopProcessIOHandler(); 1556b4874f1aSGreg Clayton } 1557b4874f1aSGreg Clayton } 1558b4874f1aSGreg Clayton 155944d93782SGreg Clayton void 156044d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp) 156144d93782SGreg Clayton { 156244d93782SGreg Clayton // At present the only thread event we handle is the Frame Changed event, 156344d93782SGreg Clayton // and all we do for that is just reprint the thread status for that thread. 156444d93782SGreg Clayton using namespace lldb; 156544d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 156644d93782SGreg Clayton if (event_type == Thread::eBroadcastBitStackChanged || 156744d93782SGreg Clayton event_type == Thread::eBroadcastBitThreadSelected ) 156844d93782SGreg Clayton { 156944d93782SGreg Clayton ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get())); 157044d93782SGreg Clayton if (thread_sp) 157144d93782SGreg Clayton { 15724446487dSPavel Labath thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1); 157344d93782SGreg Clayton } 157444d93782SGreg Clayton } 157544d93782SGreg Clayton } 157644d93782SGreg Clayton 157744d93782SGreg Clayton bool 157844d93782SGreg Clayton Debugger::IsForwardingEvents () 157944d93782SGreg Clayton { 158044d93782SGreg Clayton return (bool)m_forward_listener_sp; 158144d93782SGreg Clayton } 158244d93782SGreg Clayton 158344d93782SGreg Clayton void 158444d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp) 158544d93782SGreg Clayton { 158644d93782SGreg Clayton m_forward_listener_sp = listener_sp; 158744d93782SGreg Clayton } 158844d93782SGreg Clayton 158944d93782SGreg Clayton void 159044d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp) 159144d93782SGreg Clayton { 159244d93782SGreg Clayton m_forward_listener_sp.reset(); 159344d93782SGreg Clayton } 159444d93782SGreg Clayton 159544d93782SGreg Clayton 159644d93782SGreg Clayton void 159744d93782SGreg Clayton Debugger::DefaultEventHandler() 159844d93782SGreg Clayton { 1599583bbb1dSJim Ingham ListenerSP listener_sp(GetListener()); 160044d93782SGreg Clayton ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 160144d93782SGreg Clayton ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 160244d93782SGreg Clayton ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 160344d93782SGreg Clayton BroadcastEventSpec target_event_spec (broadcaster_class_target, 160444d93782SGreg Clayton Target::eBroadcastBitBreakpointChanged); 160544d93782SGreg Clayton 160644d93782SGreg Clayton BroadcastEventSpec process_event_spec (broadcaster_class_process, 160744d93782SGreg Clayton Process::eBroadcastBitStateChanged | 160844d93782SGreg Clayton Process::eBroadcastBitSTDOUT | 160944d93782SGreg Clayton Process::eBroadcastBitSTDERR); 161044d93782SGreg Clayton 161144d93782SGreg Clayton BroadcastEventSpec thread_event_spec (broadcaster_class_thread, 161244d93782SGreg Clayton Thread::eBroadcastBitStackChanged | 161344d93782SGreg Clayton Thread::eBroadcastBitThreadSelected ); 161444d93782SGreg Clayton 1615583bbb1dSJim Ingham listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, target_event_spec); 1616583bbb1dSJim Ingham listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, process_event_spec); 1617583bbb1dSJim Ingham listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, thread_event_spec); 1618583bbb1dSJim Ingham listener_sp->StartListeningForEvents (m_command_interpreter_ap.get(), 161944d93782SGreg Clayton CommandInterpreter::eBroadcastBitQuitCommandReceived | 162044d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousOutputData | 162144d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousErrorData ); 162244d93782SGreg Clayton 1623afa91e33SGreg Clayton // Let the thread that spawned us know that we have started up and 1624afa91e33SGreg Clayton // that we are now listening to all required events so no events get missed 1625afa91e33SGreg Clayton m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening); 1626afa91e33SGreg Clayton 162744d93782SGreg Clayton bool done = false; 162844d93782SGreg Clayton while (!done) 162944d93782SGreg Clayton { 163044d93782SGreg Clayton EventSP event_sp; 1631583bbb1dSJim Ingham if (listener_sp->WaitForEvent(nullptr, event_sp)) 163244d93782SGreg Clayton { 163344d93782SGreg Clayton if (event_sp) 163444d93782SGreg Clayton { 163544d93782SGreg Clayton Broadcaster *broadcaster = event_sp->GetBroadcaster(); 163644d93782SGreg Clayton if (broadcaster) 163744d93782SGreg Clayton { 163844d93782SGreg Clayton uint32_t event_type = event_sp->GetType(); 163944d93782SGreg Clayton ConstString broadcaster_class (broadcaster->GetBroadcasterClass()); 164044d93782SGreg Clayton if (broadcaster_class == broadcaster_class_process) 164144d93782SGreg Clayton { 164244d93782SGreg Clayton HandleProcessEvent (event_sp); 164344d93782SGreg Clayton } 164444d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_target) 164544d93782SGreg Clayton { 164644d93782SGreg Clayton if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get())) 164744d93782SGreg Clayton { 164844d93782SGreg Clayton HandleBreakpointEvent (event_sp); 164944d93782SGreg Clayton } 165044d93782SGreg Clayton } 165144d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_thread) 165244d93782SGreg Clayton { 165344d93782SGreg Clayton HandleThreadEvent (event_sp); 165444d93782SGreg Clayton } 165544d93782SGreg Clayton else if (broadcaster == m_command_interpreter_ap.get()) 165644d93782SGreg Clayton { 165744d93782SGreg Clayton if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived) 165844d93782SGreg Clayton { 165944d93782SGreg Clayton done = true; 166044d93782SGreg Clayton } 166144d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData) 166244d93782SGreg Clayton { 166344d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 166444d93782SGreg Clayton if (data && data[0]) 166544d93782SGreg Clayton { 16664446487dSPavel Labath StreamSP error_sp (GetAsyncErrorStream()); 166744d93782SGreg Clayton if (error_sp) 166844d93782SGreg Clayton { 166944d93782SGreg Clayton error_sp->PutCString(data); 167044d93782SGreg Clayton error_sp->Flush(); 167144d93782SGreg Clayton } 167244d93782SGreg Clayton } 167344d93782SGreg Clayton } 167444d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData) 167544d93782SGreg Clayton { 167644d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 167744d93782SGreg Clayton if (data && data[0]) 167844d93782SGreg Clayton { 16794446487dSPavel Labath StreamSP output_sp (GetAsyncOutputStream()); 168044d93782SGreg Clayton if (output_sp) 168144d93782SGreg Clayton { 168244d93782SGreg Clayton output_sp->PutCString(data); 168344d93782SGreg Clayton output_sp->Flush(); 168444d93782SGreg Clayton } 168544d93782SGreg Clayton } 168644d93782SGreg Clayton } 168744d93782SGreg Clayton } 168844d93782SGreg Clayton } 168944d93782SGreg Clayton 169044d93782SGreg Clayton if (m_forward_listener_sp) 169144d93782SGreg Clayton m_forward_listener_sp->AddEvent(event_sp); 169244d93782SGreg Clayton } 169344d93782SGreg Clayton } 169444d93782SGreg Clayton } 169544d93782SGreg Clayton } 169644d93782SGreg Clayton 169744d93782SGreg Clayton lldb::thread_result_t 169844d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg) 169944d93782SGreg Clayton { 170044d93782SGreg Clayton ((Debugger *)arg)->DefaultEventHandler(); 170144d93782SGreg Clayton return NULL; 170244d93782SGreg Clayton } 170344d93782SGreg Clayton 170444d93782SGreg Clayton bool 170544d93782SGreg Clayton Debugger::StartEventHandlerThread() 170644d93782SGreg Clayton { 1707acee96aeSZachary Turner if (!m_event_handler_thread.IsJoinable()) 1708807b6b32SGreg Clayton { 1709afa91e33SGreg Clayton // We must synchronize with the DefaultEventHandler() thread to ensure 1710afa91e33SGreg Clayton // it is up and running and listening to events before we return from 1711afa91e33SGreg Clayton // this function. We do this by listening to events for the 1712afa91e33SGreg Clayton // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster 1713583bbb1dSJim Ingham ListenerSP listener_sp(Listener::MakeListener("lldb.debugger.event-handler")); 1714583bbb1dSJim Ingham listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening); 1715afa91e33SGreg Clayton 17167c2896a2SZachary Turner // Use larger 8MB stack for this thread 1717df370550SEugene Zelenko m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", 1718df370550SEugene Zelenko EventHandlerThread, 1719afa91e33SGreg Clayton this, 1720df370550SEugene Zelenko nullptr, 17217c2896a2SZachary Turner g_debugger_event_thread_stack_bytes); 1722afa91e33SGreg Clayton 1723afa91e33SGreg Clayton // Make sure DefaultEventHandler() is running and listening to events before we return 1724afa91e33SGreg Clayton // from this function. We are only listening for events of type 1725afa91e33SGreg Clayton // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need 1726df370550SEugene Zelenko // to wait an infinite amount of time for it (nullptr timeout as the first parameter) 1727afa91e33SGreg Clayton lldb::EventSP event_sp; 1728583bbb1dSJim Ingham listener_sp->WaitForEvent(nullptr, event_sp); 1729807b6b32SGreg Clayton } 1730acee96aeSZachary Turner return m_event_handler_thread.IsJoinable(); 173144d93782SGreg Clayton } 173244d93782SGreg Clayton 173344d93782SGreg Clayton void 173444d93782SGreg Clayton Debugger::StopEventHandlerThread() 173544d93782SGreg Clayton { 1736acee96aeSZachary Turner if (m_event_handler_thread.IsJoinable()) 173744d93782SGreg Clayton { 173844d93782SGreg Clayton GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived); 173939de3110SZachary Turner m_event_handler_thread.Join(nullptr); 174044d93782SGreg Clayton } 174144d93782SGreg Clayton } 174244d93782SGreg Clayton 174344d93782SGreg Clayton lldb::thread_result_t 174444d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg) 174544d93782SGreg Clayton { 174644d93782SGreg Clayton Debugger *debugger = (Debugger *)arg; 17479aaab558SSiva Chandra debugger->ExecuteIOHandlers(); 174844d93782SGreg Clayton debugger->StopEventHandlerThread(); 174944d93782SGreg Clayton return NULL; 175044d93782SGreg Clayton } 175144d93782SGreg Clayton 175244d93782SGreg Clayton bool 17536681041dSSean Callanan Debugger::HasIOHandlerThread() 17546681041dSSean Callanan { 17556681041dSSean Callanan return m_io_handler_thread.IsJoinable(); 17566681041dSSean Callanan } 17576681041dSSean Callanan 17586681041dSSean Callanan bool 175944d93782SGreg Clayton Debugger::StartIOHandlerThread() 176044d93782SGreg Clayton { 1761acee96aeSZachary Turner if (!m_io_handler_thread.IsJoinable()) 1762807b6b32SGreg Clayton m_io_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.io-handler", 1763807b6b32SGreg Clayton IOHandlerThread, 1764807b6b32SGreg Clayton this, 1765df370550SEugene Zelenko nullptr, 1766807b6b32SGreg Clayton 8*1024*1024); // Use larger 8MB stack for this thread 1767acee96aeSZachary Turner return m_io_handler_thread.IsJoinable(); 176844d93782SGreg Clayton } 176944d93782SGreg Clayton 177044d93782SGreg Clayton void 177144d93782SGreg Clayton Debugger::StopIOHandlerThread() 177244d93782SGreg Clayton { 1773acee96aeSZachary Turner if (m_io_handler_thread.IsJoinable()) 177444d93782SGreg Clayton { 177544d93782SGreg Clayton if (m_input_file_sp) 177644d93782SGreg Clayton m_input_file_sp->GetFile().Close(); 177739de3110SZachary Turner m_io_handler_thread.Join(nullptr); 177844d93782SGreg Clayton } 177944d93782SGreg Clayton } 178044d93782SGreg Clayton 17816681041dSSean Callanan void 17826681041dSSean Callanan Debugger::JoinIOHandlerThread() 17836681041dSSean Callanan { 17846681041dSSean Callanan if (HasIOHandlerThread()) 17856681041dSSean Callanan { 17866681041dSSean Callanan thread_result_t result; 17876681041dSSean Callanan m_io_handler_thread.Join(&result); 17886681041dSSean Callanan m_io_handler_thread = LLDB_INVALID_HOST_THREAD; 17896681041dSSean Callanan } 17906681041dSSean Callanan } 17916681041dSSean Callanan 1792893c932aSJim Ingham Target * 1793893c932aSJim Ingham Debugger::GetDummyTarget() 1794893c932aSJim Ingham { 1795893c932aSJim Ingham return m_target_list.GetDummyTarget (*this).get(); 1796893c932aSJim Ingham } 1797893c932aSJim Ingham 1798893c932aSJim Ingham Target * 179933df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) 1800893c932aSJim Ingham { 180133df7cd3SJim Ingham Target *target = nullptr; 180233df7cd3SJim Ingham if (!prefer_dummy) 180333df7cd3SJim Ingham { 180433df7cd3SJim Ingham target = m_target_list.GetSelectedTarget().get(); 180533df7cd3SJim Ingham if (target) 180633df7cd3SJim Ingham return target; 180733df7cd3SJim Ingham } 1808893c932aSJim Ingham 1809893c932aSJim Ingham return GetDummyTarget(); 1810893c932aSJim Ingham } 181144d93782SGreg Clayton 18123e7e915dSSean Callanan Error 18133e7e915dSSean Callanan Debugger::RunREPL (LanguageType language, const char *repl_options) 18143e7e915dSSean Callanan { 18153e7e915dSSean Callanan Error err; 18163e7e915dSSean Callanan FileSpec repl_executable; 18173e7e915dSSean Callanan 181897f84e87SSean Callanan if (language == eLanguageTypeUnknown) 181997f84e87SSean Callanan { 182097f84e87SSean Callanan std::set<LanguageType> repl_languages; 182197f84e87SSean Callanan 182297f84e87SSean Callanan Language::GetLanguagesSupportingREPLs(repl_languages); 182397f84e87SSean Callanan 182497f84e87SSean Callanan if (repl_languages.size() == 1) 182597f84e87SSean Callanan { 182697f84e87SSean Callanan language = *repl_languages.begin(); 182797f84e87SSean Callanan } 1828df370550SEugene Zelenko else if (repl_languages.empty()) 182997f84e87SSean Callanan { 183007612026SKate Stone err.SetErrorStringWithFormat("LLDB isn't configured with REPL support for any languages."); 183197f84e87SSean Callanan return err; 183297f84e87SSean Callanan } 183397f84e87SSean Callanan else 183497f84e87SSean Callanan { 183597f84e87SSean Callanan err.SetErrorStringWithFormat("Multiple possible REPL languages. Please specify a language."); 183697f84e87SSean Callanan return err; 183797f84e87SSean Callanan } 183897f84e87SSean Callanan } 183997f84e87SSean Callanan 18403e7e915dSSean Callanan Target *const target = nullptr; // passing in an empty target means the REPL must create one 18413e7e915dSSean Callanan 18423b682de6SSean Callanan REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options)); 18433e7e915dSSean Callanan 18443e7e915dSSean Callanan if (!err.Success()) 18453e7e915dSSean Callanan { 18463e7e915dSSean Callanan return err; 18473e7e915dSSean Callanan } 18483e7e915dSSean Callanan 18493e7e915dSSean Callanan if (!repl_sp) 18503e7e915dSSean Callanan { 18513e7e915dSSean Callanan err.SetErrorStringWithFormat("couldn't find a REPL for %s", Language::GetNameForLanguageType(language)); 18523e7e915dSSean Callanan return err; 18533e7e915dSSean Callanan } 18543e7e915dSSean Callanan 18553e7e915dSSean Callanan repl_sp->SetCompilerOptions(repl_options); 18563e7e915dSSean Callanan repl_sp->RunLoop(); 18573e7e915dSSean Callanan 18583e7e915dSSean Callanan return err; 18593e7e915dSSean Callanan } 1860