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