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 
124a33d318SGreg Clayton #include <map>
134a33d318SGreg Clayton 
14705b1809SJason Molenda #include "llvm/ADT/StringRef.h"
154becb37eSEnrico Granata 
1630fdc8d8SChris Lattner #include "lldb/lldb-private.h"
17554f68d3SGreg Clayton #include "lldb/Core/FormatEntity.h"
181f746071SGreg Clayton #include "lldb/Core/Module.h"
190d5a2bd6SJim Ingham #include "lldb/Core/PluginInterface.h"
20e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
217349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2230fdc8d8SChris Lattner #include "lldb/Core/State.h"
235b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
24228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
2544d93782SGreg Clayton #include "lldb/Core/StreamFile.h"
261b654882SGreg Clayton #include "lldb/Core/StreamString.h"
27705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
2830fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
294becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
306d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
315548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
325548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
33894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h"
343e7e915dSSean Callanan #include "lldb/Expression/REPL.h"
3593a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h"
3642ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h"
37a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
3839de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h"
396611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
40633a29cfSZachary Turner #include "lldb/Interpreter/OptionValueProperties.h"
4167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
431f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
441f746071SGreg Clayton #include "lldb/Symbol/Function.h"
451f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
466d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
4730fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
483e7e915dSSean Callanan #include "lldb/Target/Language.h"
4930fdc8d8SChris Lattner #include "lldb/Target/Process.h"
501b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
515fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h"
521b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5384a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5430fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
555a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5630fdc8d8SChris Lattner 
5758a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h"
5858a559c0SZachary Turner 
5930fdc8d8SChris Lattner using namespace lldb;
6030fdc8d8SChris Lattner using namespace lldb_private;
6130fdc8d8SChris Lattner 
6230fdc8d8SChris Lattner 
63ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
647c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
65ebc1bb27SCaroline Tice 
661b654882SGreg Clayton #pragma mark Static Functions
671b654882SGreg Clayton 
681b654882SGreg Clayton static Mutex &
691b654882SGreg Clayton GetDebuggerListMutex ()
701b654882SGreg Clayton {
711b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
721b654882SGreg Clayton     return g_mutex;
731b654882SGreg Clayton }
741b654882SGreg Clayton 
751b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
761b654882SGreg Clayton 
771b654882SGreg Clayton static DebuggerList &
781b654882SGreg Clayton GetDebuggerList()
791b654882SGreg Clayton {
801b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
816a7f3338SBruce Mitchener     // global init constructors
821b654882SGreg Clayton     static DebuggerList g_list;
831b654882SGreg Clayton     return g_list;
841b654882SGreg Clayton }
85e372b98dSGreg Clayton 
86e372b98dSGreg Clayton OptionEnumValueElement
8767cc0636SGreg Clayton g_show_disassembly_enum_values[] =
88e372b98dSGreg Clayton {
8967cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,          "never",            "Never show disassembly when displaying a stop context."},
90*8be74995SMohit K. Bhakkad     { Debugger::eStopDisassemblyTypeNoDebugInfo,    "no-debuginfo",     "Show disassembly when there is no debug information."},
9167cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource,       "no-source",        "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
9267cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,         "always",           "Always show disassembly when displaying a stop context."},
93e372b98dSGreg Clayton     { 0, NULL, NULL }
94e372b98dSGreg Clayton };
95e372b98dSGreg Clayton 
9667cc0636SGreg Clayton OptionEnumValueElement
9767cc0636SGreg Clayton g_language_enumerators[] =
9867cc0636SGreg Clayton {
9967cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
10067cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
10167cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
102a12993c9SGreg Clayton     { 0, NULL, NULL }
10367cc0636SGreg Clayton };
104e372b98dSGreg Clayton 
10567cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10667cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
1076ab659a9SJason Molenda #define IS_OPTIMIZED "{${function.is-optimized} [opt]}"
10867cc0636SGreg Clayton 
1090769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
11067cc0636SGreg Clayton     "{, ${frame.pc}}"\
11167cc0636SGreg Clayton     MODULE_WITH_FUNC\
11267cc0636SGreg Clayton     FILE_AND_LINE\
1130769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
1140769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
115705b1809SJason Molenda     "{, activity = '${thread.info.activity.name}'}" \
116705b1809SJason Molenda     "{, ${thread.info.trace_messages} messages}" \
11767cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
11867cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
11930fadafeSJim Ingham     "{\\nCompleted expression: ${thread.completed-expression}}"\
12067cc0636SGreg Clayton     "\\n"
12167cc0636SGreg Clayton 
12267cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
12367cc0636SGreg Clayton     MODULE_WITH_FUNC\
12467cc0636SGreg Clayton     FILE_AND_LINE\
1256ab659a9SJason Molenda     IS_OPTIMIZED\
12667cc0636SGreg Clayton     "\\n"
12767cc0636SGreg Clayton 
128c980fa92SJason Molenda // Three parts to this disassembly format specification:
129c980fa92SJason Molenda //   1. If this is a new function/symbol (no previous symbol/function), print
130c980fa92SJason Molenda //      dylib`funcname:\n
131c980fa92SJason Molenda //   2. If this is a symbol context change (different from previous symbol/function), print
132c980fa92SJason Molenda //      dylib`funcname:\n
133c980fa92SJason Molenda //   3. print
134c980fa92SJason Molenda //      address <+offset>:
135c980fa92SJason 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}>}: "
136c980fa92SJason Molenda 
137c980fa92SJason Molenda // gdb's disassembly format can be emulated with
138c980fa92SJason Molenda // ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
139c980fa92SJason Molenda 
140c980fa92SJason Molenda // lldb's original format for disassembly would look like this format string -
141c980fa92SJason 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}}:
142c980fa92SJason Molenda 
14367cc0636SGreg Clayton 
144754a9369SGreg Clayton static PropertyDefinition
145754a9369SGreg Clayton g_properties[] =
14667cc0636SGreg Clayton {
14767cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean     , true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
148554f68d3SGreg Clayton {   "disassembly-format",       OptionValue::eTypeFormatEntity, true, 0    , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
149554f68d3SGreg Clayton {   "frame-format",             OptionValue::eTypeFormatEntity, true, 0    , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
15067cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean     , true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1514c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString      , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
15267cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum        , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
15367cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64      , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
154*8be74995SMohit K. Bhakkad {   "stop-disassembly-display", OptionValue::eTypeEnum        , true, Debugger::eStopDisassemblyTypeNoDebugInfo, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
15567cc0636SGreg Clayton {   "stop-line-count-after",    OptionValue::eTypeSInt64      , true, 3    , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
15667cc0636SGreg Clayton {   "stop-line-count-before",   OptionValue::eTypeSInt64      , true, 3    , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
15767cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64      , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
158554f68d3SGreg Clayton {   "thread-format",            OptionValue::eTypeFormatEntity, true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
15967cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean     , true, false, NULL, NULL, "Whether to use an external editor or not." },
160c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean     , true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
16190a8db30SEnrico Granata {   "auto-one-line-summaries",  OptionValue::eTypeBoolean     , true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
1626681041dSSean Callanan {   "auto-indent",              OptionValue::eTypeBoolean     , true, true , NULL, NULL, "If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true)." },
1636681041dSSean Callanan {   "print-decls",              OptionValue::eTypeBoolean     , true, true , NULL, NULL, "If true, LLDB will print the values of variables declared in an expression. Currently only supported in the REPL (default: true)." },
1646681041dSSean Callanan {   "tab-size",                 OptionValue::eTypeUInt64      , true, 4    , NULL, NULL, "The tab size to use when indenting code in multi-line input mode (default: 4)." },
165ebdc1ac0SEnrico Granata {   "escape-non-printables",    OptionValue::eTypeBoolean     , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
16667cc0636SGreg Clayton {   NULL,                       OptionValue::eTypeInvalid     , true, 0    , NULL, NULL, NULL }
16767cc0636SGreg Clayton };
16867cc0636SGreg Clayton 
16967cc0636SGreg Clayton enum
17067cc0636SGreg Clayton {
17167cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
172aff1b357SJason Molenda     ePropertyDisassemblyFormat,
17367cc0636SGreg Clayton     ePropertyFrameFormat,
17467cc0636SGreg Clayton     ePropertyNotiftVoid,
17567cc0636SGreg Clayton     ePropertyPrompt,
17667cc0636SGreg Clayton     ePropertyScriptLanguage,
17767cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
17867cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
17967cc0636SGreg Clayton     ePropertyStopLineCountAfter,
18067cc0636SGreg Clayton     ePropertyStopLineCountBefore,
18167cc0636SGreg Clayton     ePropertyTerminalWidth,
18267cc0636SGreg Clayton     ePropertyThreadFormat,
183c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
184c3ce7f27SMichael Sartain     ePropertyUseColor,
185ebdc1ac0SEnrico Granata     ePropertyAutoOneLineSummaries,
1866681041dSSean Callanan     ePropertyAutoIndent,
1876681041dSSean Callanan     ePropertyPrintDecls,
1886681041dSSean Callanan     ePropertyTabSize,
189ebdc1ac0SEnrico Granata     ePropertyEscapeNonPrintables
19067cc0636SGreg Clayton };
19167cc0636SGreg Clayton 
1923a00691fSZachary Turner LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1934c05410fSGreg Clayton 
1944c05410fSGreg Clayton Error
1954c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1964c05410fSGreg Clayton                             VarSetOperationType op,
1974c05410fSGreg Clayton                             const char *property_path,
1984c05410fSGreg Clayton                             const char *value)
1994c05410fSGreg Clayton {
20084a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
201ebdc1ac0SEnrico Granata     bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
20284a53dfbSEnrico Granata     TargetSP target_sp;
203397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
20484a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
20584a53dfbSEnrico Granata     {
20684a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
20784a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
20884a53dfbSEnrico Granata     }
2094c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
2104c05410fSGreg Clayton     if (error.Success())
2114c05410fSGreg Clayton     {
21284a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
2134c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
2144c05410fSGreg Clayton         {
2154c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
216c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
217c3ce7f27SMichael Sartain             if (str.length())
218c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
21944d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
2204c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
2214c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
2224c05410fSGreg Clayton         }
223c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
224c3ce7f27SMichael Sartain         {
225c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
226c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
227c3ce7f27SMichael Sartain         }
228397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
22984a53dfbSEnrico Granata         {
230397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
23184a53dfbSEnrico Granata             {
23284a53dfbSEnrico Granata                 std::list<Error> errors;
2339730339bSEnrico Granata                 StreamString feedback_stream;
2349730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
23584a53dfbSEnrico Granata                 {
23644d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
23744d93782SGreg Clayton                     if (stream_sp)
23844d93782SGreg Clayton                     {
23984a53dfbSEnrico Granata                         for (auto error : errors)
24084a53dfbSEnrico Granata                         {
24144d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
24284a53dfbSEnrico Granata                         }
2439730339bSEnrico Granata                         if (feedback_stream.GetSize())
24444d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
24544d93782SGreg Clayton                     }
24684a53dfbSEnrico Granata                 }
24784a53dfbSEnrico Granata             }
24884a53dfbSEnrico Granata         }
249ebdc1ac0SEnrico Granata         else if (is_escape_non_printables)
250ebdc1ac0SEnrico Granata         {
251ebdc1ac0SEnrico Granata             DataVisualization::ForceUpdate();
252ebdc1ac0SEnrico Granata         }
2534c05410fSGreg Clayton     }
2544c05410fSGreg Clayton     return error;
2554c05410fSGreg Clayton }
2564c05410fSGreg Clayton 
25767cc0636SGreg Clayton bool
25867cc0636SGreg Clayton Debugger::GetAutoConfirm () const
25967cc0636SGreg Clayton {
26067cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
261754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
26267cc0636SGreg Clayton }
26367cc0636SGreg Clayton 
264554f68d3SGreg Clayton const FormatEntity::Entry *
265aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const
266aff1b357SJason Molenda {
267aff1b357SJason Molenda     const uint32_t idx = ePropertyDisassemblyFormat;
268554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
269aff1b357SJason Molenda }
270aff1b357SJason Molenda 
271554f68d3SGreg Clayton const FormatEntity::Entry *
27267cc0636SGreg Clayton Debugger::GetFrameFormat() const
27367cc0636SGreg Clayton {
27467cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
275554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
27667cc0636SGreg Clayton }
27767cc0636SGreg Clayton 
27867cc0636SGreg Clayton bool
27967cc0636SGreg Clayton Debugger::GetNotifyVoid () const
28067cc0636SGreg Clayton {
28167cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
282754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
28367cc0636SGreg Clayton }
28467cc0636SGreg Clayton 
28567cc0636SGreg Clayton const char *
28667cc0636SGreg Clayton Debugger::GetPrompt() const
28767cc0636SGreg Clayton {
28867cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
289754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
29067cc0636SGreg Clayton }
29167cc0636SGreg Clayton 
29267cc0636SGreg Clayton void
29367cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
29467cc0636SGreg Clayton {
29567cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
29667cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
29767cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
298c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
299c3ce7f27SMichael Sartain     if (str.length())
300c3ce7f27SMichael Sartain         new_prompt = str.c_str();
30144d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
30267cc0636SGreg Clayton }
30367cc0636SGreg Clayton 
304554f68d3SGreg Clayton const FormatEntity::Entry *
30567cc0636SGreg Clayton Debugger::GetThreadFormat() const
30667cc0636SGreg Clayton {
30767cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
308554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
30967cc0636SGreg Clayton }
31067cc0636SGreg Clayton 
31167cc0636SGreg Clayton lldb::ScriptLanguage
31267cc0636SGreg Clayton Debugger::GetScriptLanguage() const
31367cc0636SGreg Clayton {
31467cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
315754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
31667cc0636SGreg Clayton }
31767cc0636SGreg Clayton 
31867cc0636SGreg Clayton bool
31967cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
32067cc0636SGreg Clayton {
32167cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
32267cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
32367cc0636SGreg Clayton }
32467cc0636SGreg Clayton 
32567cc0636SGreg Clayton uint32_t
32667cc0636SGreg Clayton Debugger::GetTerminalWidth () const
32767cc0636SGreg Clayton {
32867cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
329754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
33067cc0636SGreg Clayton }
33167cc0636SGreg Clayton 
33267cc0636SGreg Clayton bool
33367cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
33467cc0636SGreg Clayton {
33567cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
33667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
33767cc0636SGreg Clayton }
33867cc0636SGreg Clayton 
33967cc0636SGreg Clayton bool
34067cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
34167cc0636SGreg Clayton {
34267cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
343754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
34467cc0636SGreg Clayton }
34567cc0636SGreg Clayton 
34667cc0636SGreg Clayton bool
34767cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
34867cc0636SGreg Clayton {
34967cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
35067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
35167cc0636SGreg Clayton }
35267cc0636SGreg Clayton 
353c3ce7f27SMichael Sartain bool
354c3ce7f27SMichael Sartain Debugger::GetUseColor () const
355c3ce7f27SMichael Sartain {
356c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
357c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
358c3ce7f27SMichael Sartain }
359c3ce7f27SMichael Sartain 
360c3ce7f27SMichael Sartain bool
361c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
362c3ce7f27SMichael Sartain {
363c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
364c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
365c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
366c3ce7f27SMichael Sartain     return ret;
367c3ce7f27SMichael Sartain }
368c3ce7f27SMichael Sartain 
36967cc0636SGreg Clayton uint32_t
37067cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
37167cc0636SGreg Clayton {
37267cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
373754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
37467cc0636SGreg Clayton }
37567cc0636SGreg Clayton 
37667cc0636SGreg Clayton Debugger::StopDisassemblyType
37767cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
37867cc0636SGreg Clayton {
37967cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
380754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
38167cc0636SGreg Clayton }
38267cc0636SGreg Clayton 
38367cc0636SGreg Clayton uint32_t
38467cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
38567cc0636SGreg Clayton {
38667cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
387754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
38867cc0636SGreg Clayton }
389e372b98dSGreg Clayton 
390553fad5cSEnrico Granata bool
39190a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
392553fad5cSEnrico Granata {
39390a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
394553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
395ebdc1ac0SEnrico Granata }
396553fad5cSEnrico Granata 
397ebdc1ac0SEnrico Granata bool
398ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const
399ebdc1ac0SEnrico Granata {
400ebdc1ac0SEnrico Granata     const uint32_t idx = ePropertyEscapeNonPrintables;
401ebdc1ac0SEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
402553fad5cSEnrico Granata }
403553fad5cSEnrico Granata 
4046681041dSSean Callanan bool
4056681041dSSean Callanan Debugger::GetAutoIndent () const
4066681041dSSean Callanan {
4076681041dSSean Callanan     const uint32_t idx = ePropertyAutoIndent;
4086681041dSSean Callanan     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
4096681041dSSean Callanan }
4106681041dSSean Callanan 
4116681041dSSean Callanan bool
4126681041dSSean Callanan Debugger::SetAutoIndent (bool b)
4136681041dSSean Callanan {
4146681041dSSean Callanan     const uint32_t idx = ePropertyAutoIndent;
4156681041dSSean Callanan     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
4166681041dSSean Callanan }
4176681041dSSean Callanan 
4186681041dSSean Callanan bool
4196681041dSSean Callanan Debugger::GetPrintDecls () const
4206681041dSSean Callanan {
4216681041dSSean Callanan     const uint32_t idx = ePropertyPrintDecls;
4226681041dSSean Callanan     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
4236681041dSSean Callanan }
4246681041dSSean Callanan 
4256681041dSSean Callanan bool
4266681041dSSean Callanan Debugger::SetPrintDecls (bool b)
4276681041dSSean Callanan {
4286681041dSSean Callanan     const uint32_t idx = ePropertyPrintDecls;
4296681041dSSean Callanan     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
4306681041dSSean Callanan }
4316681041dSSean Callanan 
4326681041dSSean Callanan uint32_t
4336681041dSSean Callanan Debugger::GetTabSize () const
4346681041dSSean Callanan {
4356681041dSSean Callanan     const uint32_t idx = ePropertyTabSize;
4366681041dSSean Callanan     return m_collection_sp->GetPropertyAtIndexAsUInt64 (NULL, idx, g_properties[idx].default_uint_value);
4376681041dSSean Callanan }
4386681041dSSean Callanan 
4396681041dSSean Callanan bool
4406681041dSSean Callanan Debugger::SetTabSize (uint32_t tab_size)
4416681041dSSean Callanan {
4426681041dSSean Callanan     const uint32_t idx = ePropertyTabSize;
4436681041dSSean Callanan     return m_collection_sp->SetPropertyAtIndexAsUInt64 (NULL, idx, tab_size);
4446681041dSSean Callanan }
4456681041dSSean Callanan 
4466681041dSSean Callanan 
4471b654882SGreg Clayton #pragma mark Debugger
4481b654882SGreg Clayton 
44967cc0636SGreg Clayton //const DebuggerPropertiesSP &
45067cc0636SGreg Clayton //Debugger::GetSettings() const
45167cc0636SGreg Clayton //{
45267cc0636SGreg Clayton //    return m_properties_sp;
45367cc0636SGreg Clayton //}
45467cc0636SGreg Clayton //
45599d0faf2SGreg Clayton 
456e6e2bb38SZachary Turner static bool lldb_initialized = false;
45730fdc8d8SChris Lattner void
4585fb8f797SGreg Clayton Debugger::Initialize(LoadPluginCallbackType load_plugin_callback)
45930fdc8d8SChris Lattner {
460e6e2bb38SZachary Turner     assert(!lldb_initialized && "Debugger::Initialize called more than once!");
461e6e2bb38SZachary Turner 
462f196c931SRobert Flack     lldb_initialized = true;
4635fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
46499d0faf2SGreg Clayton }
46530fdc8d8SChris Lattner 
466e6e2bb38SZachary Turner void
46730fdc8d8SChris Lattner Debugger::Terminate ()
46830fdc8d8SChris Lattner {
469e6e2bb38SZachary Turner     assert(lldb_initialized && "Debugger::Terminate called without a matching Debugger::Initialize!");
470e6e2bb38SZachary Turner 
47199d0faf2SGreg Clayton     // Clear our master list of debugger objects
47299d0faf2SGreg Clayton     Mutex::Locker locker (GetDebuggerListMutex ());
473f3cd1819SOleksiy Vyalov     auto& debuggers = GetDebuggerList();
474f3cd1819SOleksiy Vyalov     for (const auto& debugger: debuggers)
475f3cd1819SOleksiy Vyalov         debugger->Clear();
476f3cd1819SOleksiy Vyalov 
477f3cd1819SOleksiy Vyalov     debuggers.clear();
47830fdc8d8SChris Lattner }
47930fdc8d8SChris Lattner 
48020bd37f7SCaroline Tice void
48120bd37f7SCaroline Tice Debugger::SettingsInitialize ()
48220bd37f7SCaroline Tice {
4836920b52bSGreg Clayton     Target::SettingsInitialize ();
48420bd37f7SCaroline Tice }
48520bd37f7SCaroline Tice 
48620bd37f7SCaroline Tice void
48720bd37f7SCaroline Tice Debugger::SettingsTerminate ()
48820bd37f7SCaroline Tice {
4896920b52bSGreg Clayton     Target::SettingsTerminate ();
49020bd37f7SCaroline Tice }
49120bd37f7SCaroline Tice 
49221dfcd9dSEnrico Granata bool
493e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
49421dfcd9dSEnrico Granata {
4955fb8f797SGreg Clayton     if (g_load_plugin_callback)
496e743c782SEnrico Granata     {
49758a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
49858a559c0SZachary Turner         if (dynlib.isValid())
49921dfcd9dSEnrico Granata         {
50058a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
50121dfcd9dSEnrico Granata             return true;
50221dfcd9dSEnrico Granata         }
5035fb8f797SGreg Clayton     }
5045fb8f797SGreg Clayton     else
5055fb8f797SGreg Clayton     {
5065fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
5075fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
5085fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
5095fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
5105fb8f797SGreg Clayton     }
51121dfcd9dSEnrico Granata     return false;
51221dfcd9dSEnrico Granata }
51321dfcd9dSEnrico Granata 
51421dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
51521dfcd9dSEnrico Granata LoadPluginCallback
51621dfcd9dSEnrico Granata (
51721dfcd9dSEnrico Granata  void *baton,
51821dfcd9dSEnrico Granata  FileSpec::FileType file_type,
51921dfcd9dSEnrico Granata  const FileSpec &file_spec
52021dfcd9dSEnrico Granata  )
52121dfcd9dSEnrico Granata {
52221dfcd9dSEnrico Granata     Error error;
52321dfcd9dSEnrico Granata 
52421dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
5253cf443ddSMichael Sartain     static ConstString g_solibext("so");
52621dfcd9dSEnrico Granata 
52721dfcd9dSEnrico Granata     if (!baton)
52821dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
52921dfcd9dSEnrico Granata 
53021dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
53121dfcd9dSEnrico Granata 
53221dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
53321dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
53421dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
53521dfcd9dSEnrico Granata     // file type information.
53621dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
53721dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
53821dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
53921dfcd9dSEnrico Granata     {
54021dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
54121dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
54221dfcd9dSEnrico Granata 
5433cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
5443cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
5453cf443ddSMichael Sartain         {
54621dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
5473cf443ddSMichael Sartain         }
54821dfcd9dSEnrico Granata 
549e743c782SEnrico Granata         Error plugin_load_error;
550e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
55121dfcd9dSEnrico Granata 
55221dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
55321dfcd9dSEnrico Granata     }
55421dfcd9dSEnrico Granata 
55521dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
55621dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
55721dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
55821dfcd9dSEnrico Granata     {
55921dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
56021dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
5616a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
56221dfcd9dSEnrico Granata         // information.
56321dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
56421dfcd9dSEnrico Granata     }
56521dfcd9dSEnrico Granata 
56621dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
56721dfcd9dSEnrico Granata }
56821dfcd9dSEnrico Granata 
56921dfcd9dSEnrico Granata void
57021dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
57121dfcd9dSEnrico Granata {
57221dfcd9dSEnrico Granata     FileSpec dir_spec;
57321dfcd9dSEnrico Granata     const bool find_directories = true;
57421dfcd9dSEnrico Granata     const bool find_files = true;
57521dfcd9dSEnrico Granata     const bool find_other = true;
57621dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
57742ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
57821dfcd9dSEnrico Granata     {
57921dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
58021dfcd9dSEnrico Granata         {
58121dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
58221dfcd9dSEnrico Granata                                           find_directories,
58321dfcd9dSEnrico Granata                                           find_files,
58421dfcd9dSEnrico Granata                                           find_other,
58521dfcd9dSEnrico Granata                                           LoadPluginCallback,
58621dfcd9dSEnrico Granata                                           this);
58721dfcd9dSEnrico Granata         }
58821dfcd9dSEnrico Granata     }
58921dfcd9dSEnrico Granata 
59042ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
59121dfcd9dSEnrico Granata     {
59221dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
59321dfcd9dSEnrico Granata         {
59421dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
59521dfcd9dSEnrico Granata                                           find_directories,
59621dfcd9dSEnrico Granata                                           find_files,
59721dfcd9dSEnrico Granata                                           find_other,
59821dfcd9dSEnrico Granata                                           LoadPluginCallback,
59921dfcd9dSEnrico Granata                                           this);
60021dfcd9dSEnrico Granata         }
60121dfcd9dSEnrico Granata     }
602e8cd0c98SGreg Clayton 
603e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
60421dfcd9dSEnrico Granata }
60521dfcd9dSEnrico Granata 
6066611103cSGreg Clayton DebuggerSP
607228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
6086611103cSGreg Clayton {
609228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
610e6e2bb38SZachary Turner     if (lldb_initialized)
6116611103cSGreg Clayton     {
6126611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6136611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
6146611103cSGreg Clayton     }
61521dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
6166611103cSGreg Clayton     return debugger_sp;
6176611103cSGreg Clayton }
6186611103cSGreg Clayton 
619e02657b1SCaroline Tice void
6204d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
621e02657b1SCaroline Tice {
622e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
623e02657b1SCaroline Tice         return;
624e02657b1SCaroline Tice 
6258314c525SJim Ingham     debugger_sp->Clear();
6268314c525SJim Ingham 
627e6e2bb38SZachary Turner     if (lldb_initialized)
628c15f55e2SGreg Clayton     {
629e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
630e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
631e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
632e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
633e02657b1SCaroline Tice         {
634e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
635e02657b1SCaroline Tice             {
636e02657b1SCaroline Tice                 debugger_list.erase (pos);
637e02657b1SCaroline Tice                 return;
638e02657b1SCaroline Tice             }
639e02657b1SCaroline Tice         }
640e02657b1SCaroline Tice     }
641c15f55e2SGreg Clayton }
642e02657b1SCaroline Tice 
6434d122c40SGreg Clayton DebuggerSP
6443df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
6453df9a8dfSCaroline Tice {
6464d122c40SGreg Clayton     DebuggerSP debugger_sp;
647e6e2bb38SZachary Turner     if (lldb_initialized)
6486920b52bSGreg Clayton     {
6496920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6506920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6516920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6526920b52bSGreg Clayton 
6536920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6546920b52bSGreg Clayton         {
6556920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
6566920b52bSGreg Clayton             {
6576920b52bSGreg Clayton                 debugger_sp = *pos;
6586920b52bSGreg Clayton                 break;
6596920b52bSGreg Clayton             }
6606920b52bSGreg Clayton         }
6616920b52bSGreg Clayton     }
6623df9a8dfSCaroline Tice     return debugger_sp;
6633df9a8dfSCaroline Tice }
6646611103cSGreg Clayton 
6656611103cSGreg Clayton TargetSP
6666611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6676611103cSGreg Clayton {
6684d122c40SGreg Clayton     TargetSP target_sp;
669e6e2bb38SZachary Turner     if (lldb_initialized)
670c15f55e2SGreg Clayton     {
6716611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6726611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6736611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6746611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6756611103cSGreg Clayton         {
6766611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6776611103cSGreg Clayton             if (target_sp)
6786611103cSGreg Clayton                 break;
6796611103cSGreg Clayton         }
680c15f55e2SGreg Clayton     }
6816611103cSGreg Clayton     return target_sp;
6826611103cSGreg Clayton }
6836611103cSGreg Clayton 
684e4e45924SGreg Clayton TargetSP
685e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
686e4e45924SGreg Clayton {
687e4e45924SGreg Clayton     TargetSP target_sp;
688e6e2bb38SZachary Turner     if (lldb_initialized)
689c15f55e2SGreg Clayton     {
690e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
691e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
692e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
693e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
694e4e45924SGreg Clayton         {
695e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
696e4e45924SGreg Clayton             if (target_sp)
697e4e45924SGreg Clayton                 break;
698e4e45924SGreg Clayton         }
699c15f55e2SGreg Clayton     }
700e4e45924SGreg Clayton     return target_sp;
701e4e45924SGreg Clayton }
702e4e45924SGreg Clayton 
703e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
704e6481c7eSJason Molenda     UserID(g_unique_id++),
705e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
706e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
707e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
708e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
709e6481c7eSJason Molenda     m_terminal_state(),
710e6481c7eSJason Molenda     m_target_list(*this),
711e6481c7eSJason Molenda     m_platform_list(),
712e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
713e6481c7eSJason Molenda     m_source_manager_ap(),
714e6481c7eSJason Molenda     m_source_file_cache(),
715e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
716e6481c7eSJason Molenda     m_input_reader_stack(),
717e6481c7eSJason Molenda     m_instance_name(),
718afa91e33SGreg Clayton     m_loaded_plugins(),
719afa91e33SGreg Clayton     m_event_handler_thread (),
720afa91e33SGreg Clayton     m_io_handler_thread (),
721afa91e33SGreg Clayton     m_sync_broadcaster (NULL, "lldb.debugger.sync")
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());
731ded470d3SGreg Clayton     assert (default_platform_sp.get());
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());
743754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
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     }
75067cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, 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 {
76844d93782SGreg Clayton     ClearIOHandlers();
76944d93782SGreg Clayton     StopIOHandlerThread();
77044d93782SGreg Clayton     StopEventHandlerThread();
7711ed54f50SGreg Clayton     m_listener.Clear();
7726611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
7736611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7746611103cSGreg Clayton     {
775ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
776ccbc08e6SGreg Clayton         if (target_sp)
777ccbc08e6SGreg Clayton         {
778ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7796611103cSGreg Clayton             if (process_sp)
7801fd07059SJim Ingham                 process_sp->Finalize();
781ccbc08e6SGreg Clayton             target_sp->Destroy();
7826611103cSGreg Clayton         }
78330fdc8d8SChris Lattner     }
7844bddaeb5SJim Ingham     BroadcasterManager::Clear ();
78530fdc8d8SChris Lattner 
7860d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7870d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
788c5917d9aSJim Ingham     m_terminal_state.Clear();
78944d93782SGreg Clayton     if (m_input_file_sp)
79044d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7910c4129f2SGreg Clayton 
7920c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7938314c525SJim Ingham }
79430fdc8d8SChris Lattner 
79530fdc8d8SChris Lattner bool
796fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
797fc3f027dSGreg Clayton {
79844d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
79944d93782SGreg Clayton     return false;
800fc3f027dSGreg Clayton }
801fc3f027dSGreg Clayton 
802fc3f027dSGreg Clayton void
803fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
804fc3f027dSGreg Clayton {
80544d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
806fc3f027dSGreg Clayton }
807fc3f027dSGreg Clayton 
808fc3f027dSGreg Clayton bool
80930fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
81030fdc8d8SChris Lattner {
8116611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
81230fdc8d8SChris Lattner }
81330fdc8d8SChris Lattner 
81430fdc8d8SChris Lattner void
81530fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
81630fdc8d8SChris Lattner {
8176611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
81830fdc8d8SChris Lattner }
81930fdc8d8SChris Lattner 
82030fdc8d8SChris Lattner 
82130fdc8d8SChris Lattner void
82230fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
82330fdc8d8SChris Lattner {
82444d93782SGreg Clayton     if (m_input_file_sp)
82544d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
82644d93782SGreg Clayton     else
82744d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
82844d93782SGreg Clayton 
82944d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
83051b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
83151b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
83230fdc8d8SChris Lattner 
833c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
834c5917d9aSJim Ingham     SaveInputTerminalState ();
83530fdc8d8SChris Lattner }
83630fdc8d8SChris Lattner 
83730fdc8d8SChris Lattner void
83830fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
83930fdc8d8SChris Lattner {
84044d93782SGreg Clayton     if (m_output_file_sp)
84144d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
84244d93782SGreg Clayton     else
84344d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
84444d93782SGreg Clayton 
84544d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
84651b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
84751b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
8482f88aadfSCaroline Tice 
849b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
850b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
851b588726eSEnrico Granata     const bool can_create = false;
852b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
853b588726eSEnrico Granata     if (script_interpreter)
854b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
85530fdc8d8SChris Lattner }
85630fdc8d8SChris Lattner 
85730fdc8d8SChris Lattner void
85830fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
85930fdc8d8SChris Lattner {
86044d93782SGreg Clayton     if (m_error_file_sp)
86144d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
86244d93782SGreg Clayton     else
86344d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
86444d93782SGreg Clayton 
86544d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
86651b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
86751b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
86830fdc8d8SChris Lattner }
86930fdc8d8SChris Lattner 
870c5917d9aSJim Ingham void
871c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
872c5917d9aSJim Ingham {
87344d93782SGreg Clayton     if (m_input_file_sp)
87444d93782SGreg Clayton     {
87544d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
876c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
877c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
878c5917d9aSJim Ingham     }
87944d93782SGreg Clayton }
880c5917d9aSJim Ingham 
881c5917d9aSJim Ingham void
882c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
883c5917d9aSJim Ingham {
884c5917d9aSJim Ingham     m_terminal_state.Restore();
885c5917d9aSJim Ingham }
886c5917d9aSJim Ingham 
88730fdc8d8SChris Lattner ExecutionContext
8882976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
88930fdc8d8SChris Lattner {
89030fdc8d8SChris Lattner     ExecutionContext exe_ctx;
891c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
892c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
89330fdc8d8SChris Lattner 
89430fdc8d8SChris Lattner     if (target_sp)
89530fdc8d8SChris Lattner     {
896c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
897c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
898c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
89930fdc8d8SChris Lattner         {
900c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
901c14ee32dSGreg Clayton             if (thread_sp)
90230fdc8d8SChris Lattner             {
903c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
904c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
905c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
906c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
90730fdc8d8SChris Lattner             }
90830fdc8d8SChris Lattner         }
90930fdc8d8SChris Lattner     }
91030fdc8d8SChris Lattner     return exe_ctx;
91130fdc8d8SChris Lattner }
91230fdc8d8SChris Lattner 
91330fdc8d8SChris Lattner void
914efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
915efed6131SCaroline Tice {
91644d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
91744d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
918efed6131SCaroline Tice     if (reader_sp)
91944d93782SGreg Clayton         reader_sp->Interrupt();
920efed6131SCaroline Tice }
921efed6131SCaroline Tice 
922efed6131SCaroline Tice void
923efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
924efed6131SCaroline Tice {
92544d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
92644d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
927efed6131SCaroline Tice     if (reader_sp)
92844d93782SGreg Clayton         reader_sp->GotEOF();
929efed6131SCaroline Tice }
930efed6131SCaroline Tice 
931efed6131SCaroline Tice void
93244d93782SGreg Clayton Debugger::ClearIOHandlers ()
9333d6086f6SCaroline Tice {
934b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
93544d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
936d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
9373d6086f6SCaroline Tice     {
93844d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
9393d6086f6SCaroline Tice         if (reader_sp)
9404446487dSPavel Labath             PopIOHandler (reader_sp);
9413d6086f6SCaroline Tice     }
9423d6086f6SCaroline Tice }
9433d6086f6SCaroline Tice 
9443d6086f6SCaroline Tice void
9459aaab558SSiva Chandra Debugger::ExecuteIOHandlers()
946969ed3d1SCaroline Tice {
94744d93782SGreg Clayton     while (1)
948969ed3d1SCaroline Tice     {
94944d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
95030fdc8d8SChris Lattner         if (!reader_sp)
95130fdc8d8SChris Lattner             break;
95230fdc8d8SChris Lattner 
95344d93782SGreg Clayton         reader_sp->Run();
95444d93782SGreg Clayton 
95544d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
95644d93782SGreg Clayton         while (1)
95730fdc8d8SChris Lattner         {
95844d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
95944d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
9604446487dSPavel Labath                 PopIOHandler (top_reader_sp);
96130fdc8d8SChris Lattner             else
96230fdc8d8SChris Lattner                 break;
96330fdc8d8SChris Lattner         }
96430fdc8d8SChris Lattner     }
96544d93782SGreg Clayton     ClearIOHandlers();
96644d93782SGreg Clayton }
96730fdc8d8SChris Lattner 
96844d93782SGreg Clayton bool
96944d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
97044d93782SGreg Clayton {
97144d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
97244d93782SGreg Clayton }
97330fdc8d8SChris Lattner 
9746681041dSSean Callanan bool
9756681041dSSean Callanan Debugger::CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type)
9766681041dSSean Callanan {
9776681041dSSean Callanan     return m_input_reader_stack.CheckTopIOHandlerTypes (top_type, second_top_type);
9786681041dSSean Callanan }
9796681041dSSean Callanan 
9804446487dSPavel Labath void
9814446487dSPavel Labath Debugger::PrintAsync (const char *s, size_t len, bool is_stdout)
9824446487dSPavel Labath {
9834446487dSPavel Labath     lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
9844446487dSPavel Labath     m_input_reader_stack.PrintAsync(stream.get(), s, len);
9854446487dSPavel Labath }
98644d93782SGreg Clayton 
98744d93782SGreg Clayton ConstString
98844d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
98944d93782SGreg Clayton {
99044d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
99130fdc8d8SChris Lattner }
99230fdc8d8SChris Lattner 
993a487aa4cSKate Stone const char *
994a487aa4cSKate Stone Debugger::GetIOHandlerCommandPrefix()
995a487aa4cSKate Stone {
996a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
997a487aa4cSKate Stone }
998a487aa4cSKate Stone 
999a487aa4cSKate Stone const char *
1000a487aa4cSKate Stone Debugger::GetIOHandlerHelpPrologue()
1001a487aa4cSKate Stone {
1002a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
1003a487aa4cSKate Stone }
1004a487aa4cSKate Stone 
100530fdc8d8SChris Lattner void
100644d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
100744d93782SGreg Clayton {
100844d93782SGreg Clayton     PushIOHandler (reader_sp);
1009577508dfSGreg Clayton 
1010577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
1011577508dfSGreg Clayton     while (top_reader_sp)
1012577508dfSGreg Clayton     {
1013577508dfSGreg Clayton         top_reader_sp->Run();
1014577508dfSGreg Clayton 
1015577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
1016577508dfSGreg Clayton         {
1017577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
1018577508dfSGreg Clayton                 break;
1019577508dfSGreg Clayton         }
1020577508dfSGreg Clayton 
1021577508dfSGreg Clayton         while (1)
1022577508dfSGreg Clayton         {
1023577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
1024577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
10254446487dSPavel Labath                 PopIOHandler (top_reader_sp);
1026577508dfSGreg Clayton             else
1027577508dfSGreg Clayton                 break;
1028577508dfSGreg Clayton         }
1029577508dfSGreg Clayton     }
103044d93782SGreg Clayton }
103144d93782SGreg Clayton 
103244d93782SGreg Clayton void
103344d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
103444d93782SGreg Clayton {
103544d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
103644d93782SGreg Clayton     // This function is called when one ore more of the streams
103744d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
103844d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
103944d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
104044d93782SGreg Clayton 
104144d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
104244d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
104344d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
104444d93782SGreg Clayton     if (!in)
104544d93782SGreg Clayton     {
104644d93782SGreg Clayton         if (top_reader_sp)
104744d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
104844d93782SGreg Clayton         else
104944d93782SGreg Clayton             in = GetInputFile();
105044d93782SGreg Clayton 
105144d93782SGreg Clayton         // If there is nothing, use stdin
105244d93782SGreg Clayton         if (!in)
105344d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
105444d93782SGreg Clayton     }
105544d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
105644d93782SGreg Clayton     if (!out)
105744d93782SGreg Clayton     {
105844d93782SGreg Clayton         if (top_reader_sp)
105944d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
106044d93782SGreg Clayton         else
106144d93782SGreg Clayton             out = GetOutputFile();
106244d93782SGreg Clayton 
106344d93782SGreg Clayton         // If there is nothing, use stdout
106444d93782SGreg Clayton         if (!out)
106544d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
106644d93782SGreg Clayton     }
106744d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
106844d93782SGreg Clayton     if (!err)
106944d93782SGreg Clayton     {
107044d93782SGreg Clayton         if (top_reader_sp)
107144d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
107244d93782SGreg Clayton         else
107344d93782SGreg Clayton             err = GetErrorFile();
107444d93782SGreg Clayton 
107544d93782SGreg Clayton         // If there is nothing, use stderr
107644d93782SGreg Clayton         if (!err)
107744d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
107844d93782SGreg Clayton 
107944d93782SGreg Clayton     }
108044d93782SGreg Clayton }
108144d93782SGreg Clayton 
108244d93782SGreg Clayton void
108344d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
108430fdc8d8SChris Lattner {
108530fdc8d8SChris Lattner     if (!reader_sp)
108630fdc8d8SChris Lattner         return;
1087b44880caSCaroline Tice 
10884446487dSPavel Labath     Mutex::Locker locker (m_input_reader_stack.GetMutex());
10894446487dSPavel Labath 
10904446487dSPavel Labath     // Get the current top input reader...
109144d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1092b44880caSCaroline Tice 
1093b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
10944446487dSPavel Labath     if (reader_sp == top_reader_sp)
10954446487dSPavel Labath         return;
10964446487dSPavel Labath 
109744d93782SGreg Clayton     // Push our new input reader
1098d5a0a01bSCaroline Tice     m_input_reader_stack.Push (reader_sp);
10994446487dSPavel Labath     reader_sp->Activate();
110044d93782SGreg Clayton 
110144d93782SGreg Clayton     // Interrupt the top input reader to it will exit its Run() function
110244d93782SGreg Clayton     // and let this new input reader take over
110344d93782SGreg Clayton     if (top_reader_sp)
11044446487dSPavel Labath     {
110544d93782SGreg Clayton         top_reader_sp->Deactivate();
11064446487dSPavel Labath         top_reader_sp->Cancel();
110730fdc8d8SChris Lattner     }
1108b4874f1aSGreg Clayton }
110930fdc8d8SChris Lattner 
111030fdc8d8SChris Lattner bool
111144d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
111230fdc8d8SChris Lattner {
11134446487dSPavel Labath     if (! pop_reader_sp)
11144446487dSPavel Labath         return false;
111530fdc8d8SChris Lattner 
111644d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
111744d93782SGreg Clayton 
111830fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
11196a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
11204446487dSPavel Labath     if (m_input_reader_stack.IsEmpty())
11214446487dSPavel Labath         return false;
11224446487dSPavel Labath 
112344d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
112430fdc8d8SChris Lattner 
11254446487dSPavel Labath     if (pop_reader_sp != reader_sp)
11264446487dSPavel Labath         return false;
11274446487dSPavel Labath 
112844d93782SGreg Clayton     reader_sp->Deactivate();
1129b4874f1aSGreg Clayton     reader_sp->Cancel();
1130d5a0a01bSCaroline Tice     m_input_reader_stack.Pop ();
113130fdc8d8SChris Lattner 
1132d5a0a01bSCaroline Tice     reader_sp = m_input_reader_stack.Top();
113330fdc8d8SChris Lattner     if (reader_sp)
113444d93782SGreg Clayton         reader_sp->Activate();
113544d93782SGreg Clayton 
113644d93782SGreg Clayton     return true;
113730fdc8d8SChris Lattner }
11386611103cSGreg Clayton 
11395b52f0c7SJim Ingham StreamSP
11405b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
11415b52f0c7SJim Ingham {
11424446487dSPavel Labath     return StreamSP (new StreamAsynchronousIO (*this, true));
11435b52f0c7SJim Ingham }
11445b52f0c7SJim Ingham 
11455b52f0c7SJim Ingham StreamSP
11465b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
11475b52f0c7SJim Ingham {
11484446487dSPavel Labath     return StreamSP (new StreamAsynchronousIO (*this, false));
11495b52f0c7SJim Ingham }
11505b52f0c7SJim Ingham 
1151c7bece56SGreg Clayton size_t
1152061858ceSEnrico Granata Debugger::GetNumDebuggers()
1153061858ceSEnrico Granata {
1154e6e2bb38SZachary Turner     if (lldb_initialized)
1155c15f55e2SGreg Clayton     {
1156061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1157061858ceSEnrico Granata         return GetDebuggerList().size();
1158061858ceSEnrico Granata     }
1159c15f55e2SGreg Clayton     return 0;
1160c15f55e2SGreg Clayton }
1161061858ceSEnrico Granata 
1162061858ceSEnrico Granata lldb::DebuggerSP
1163c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1164061858ceSEnrico Granata {
1165061858ceSEnrico Granata     DebuggerSP debugger_sp;
1166061858ceSEnrico Granata 
1167e6e2bb38SZachary Turner     if (lldb_initialized)
1168c15f55e2SGreg Clayton     {
1169061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1170061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1171061858ceSEnrico Granata 
1172061858ceSEnrico Granata         if (index < debugger_list.size())
1173061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1174c15f55e2SGreg Clayton     }
1175061858ceSEnrico Granata 
1176061858ceSEnrico Granata     return debugger_sp;
1177061858ceSEnrico Granata }
1178061858ceSEnrico Granata 
1179ebc1bb27SCaroline Tice DebuggerSP
1180ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1181ebc1bb27SCaroline Tice {
11824d122c40SGreg Clayton     DebuggerSP debugger_sp;
1183ebc1bb27SCaroline Tice 
1184e6e2bb38SZachary Turner     if (lldb_initialized)
1185c15f55e2SGreg Clayton     {
1186ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1187ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1188ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1189ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1190ebc1bb27SCaroline Tice         {
1191ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1192ebc1bb27SCaroline Tice             {
1193ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1194ebc1bb27SCaroline Tice                 break;
1195ebc1bb27SCaroline Tice             }
1196ebc1bb27SCaroline Tice         }
1197c15f55e2SGreg Clayton     }
1198ebc1bb27SCaroline Tice     return debugger_sp;
1199ebc1bb27SCaroline Tice }
12003df9a8dfSCaroline Tice 
12012643b905SSaleem Abdulrasool #if 0
12021b654882SGreg Clayton static void
1203b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
12041b654882SGreg Clayton {
12051b654882SGreg Clayton     if (frame == NULL)
12061b654882SGreg Clayton         return;
12071b654882SGreg Clayton 
12081b654882SGreg Clayton     StreamString s;
12091b654882SGreg Clayton     const char *prompt_format =
12101b654882SGreg Clayton     "{addr = '${addr}'\n}"
1211aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1212aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
12131b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
12141b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
12151b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
12161b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
12171b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
12181b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
12191b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
12201b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
12211b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
12221b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
12231b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
12241b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
12251b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
12261b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
12271b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
12281b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
12291b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
12301b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
12311b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
12321b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
12331b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
12341b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
12351b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
12361b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
12371b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
12381b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
12391b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1240aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1241aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
12421b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1243aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1244ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
12451b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1246aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
12471b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
12481b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
12491b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
12501b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
12511b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
12521b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
12531b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
12541b654882SGreg Clayton ;
12551b654882SGreg Clayton 
12561b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
12571b654882SGreg Clayton     ExecutionContext exe_ctx;
12580603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1259c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
12601b654882SGreg Clayton     {
12611b654882SGreg Clayton         printf("%s\n", s.GetData());
12621b654882SGreg Clayton     }
12631b654882SGreg Clayton     else
12641b654882SGreg Clayton     {
12651b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
12661b654882SGreg Clayton     }
12671b654882SGreg Clayton }
12682643b905SSaleem Abdulrasool #endif
12691b654882SGreg Clayton 
1270c3ce7f27SMichael Sartain bool
1271554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
1272aff1b357SJason Molenda                                      const SymbolContext *sc,
1273aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
1274aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
1275aff1b357SJason Molenda                                      const Address *addr,
1276aff1b357SJason Molenda                                      Stream &s)
1277aff1b357SJason Molenda {
1278554f68d3SGreg Clayton     FormatEntity::Entry format_entry;
1279554f68d3SGreg Clayton 
1280554f68d3SGreg Clayton     if (format == NULL)
1281aff1b357SJason Molenda     {
1282554f68d3SGreg Clayton         if (exe_ctx != NULL && exe_ctx->HasTargetScope())
1283aff1b357SJason Molenda             format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1284554f68d3SGreg Clayton         if (format == NULL)
1285554f68d3SGreg Clayton         {
1286554f68d3SGreg Clayton             FormatEntity::Parse("${addr}: ", format_entry);
1287554f68d3SGreg Clayton             format = &format_entry;
1288554f68d3SGreg Clayton         }
1289aff1b357SJason Molenda     }
1290aff1b357SJason Molenda     bool function_changed = false;
1291aff1b357SJason Molenda     bool initial_function = false;
1292aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
1293aff1b357SJason Molenda     {
1294aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
1295aff1b357SJason Molenda         {
1296aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
1297aff1b357SJason Molenda             {
1298aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
1299aff1b357SJason Molenda                 {
1300aff1b357SJason Molenda                     function_changed = true;
1301aff1b357SJason Molenda                 }
1302aff1b357SJason Molenda             }
1303aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
1304aff1b357SJason Molenda             {
1305aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
1306aff1b357SJason Molenda                 {
1307aff1b357SJason Molenda                     function_changed = true;
1308aff1b357SJason Molenda                 }
1309aff1b357SJason Molenda             }
1310aff1b357SJason Molenda         }
1311aff1b357SJason Molenda     }
1312aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
1313aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
1314aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
1315aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
1316aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
1317aff1b357SJason Molenda     {
1318aff1b357SJason Molenda         initial_function = true;
1319aff1b357SJason Molenda     }
1320554f68d3SGreg Clayton     return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function);
1321aff1b357SJason Molenda }
1322aff1b357SJason Molenda 
1323aff1b357SJason Molenda 
1324228063cdSJim Ingham void
1325228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
1326228063cdSJim Ingham {
13274f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
13284f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
13294f02b22dSJim Ingham     // callback.
1330228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
1331228063cdSJim Ingham }
1332228063cdSJim Ingham 
1333228063cdSJim Ingham bool
1334228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
1335228063cdSJim Ingham {
1336228063cdSJim Ingham     StreamSP log_stream_sp;
13379a028519SSean Callanan     if (m_log_callback_stream_sp)
1338228063cdSJim Ingham     {
1339228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
1340228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
1341228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1342228063cdSJim Ingham     }
1343228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
1344228063cdSJim Ingham     {
134544d93782SGreg Clayton         log_stream_sp = GetOutputFile();
1346228063cdSJim Ingham     }
1347228063cdSJim Ingham     else
1348228063cdSJim Ingham     {
1349228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
1350c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
1351c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
1352c1b2ccfdSGreg Clayton         if (!log_stream_sp)
1353228063cdSJim Ingham         {
13548ac06996SPavel Labath             uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate
13558ac06996SPavel Labath                                 | File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
13568ac06996SPavel Labath             if (! (log_options & LLDB_LOG_OPTION_APPEND))
13578ac06996SPavel Labath                 options |= File::eOpenOptionTruncate;
13588ac06996SPavel Labath 
13598ac06996SPavel Labath             log_stream_sp.reset (new StreamFile (log_file, options));
1360228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
1361228063cdSJim Ingham         }
1362228063cdSJim Ingham     }
1363228063cdSJim Ingham     assert (log_stream_sp.get());
1364228063cdSJim Ingham 
1365228063cdSJim Ingham     if (log_options == 0)
1366228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
1367228063cdSJim Ingham 
13689c9ecce0STamas Berghammer     return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, error_stream);
1369228063cdSJim Ingham }
1370228063cdSJim Ingham 
13719585fbfcSGreg Clayton SourceManager &
13729585fbfcSGreg Clayton Debugger::GetSourceManager ()
13739585fbfcSGreg Clayton {
13749585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
13759585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
13769585fbfcSGreg Clayton     return *m_source_manager_ap;
13779585fbfcSGreg Clayton }
13789585fbfcSGreg Clayton 
13799585fbfcSGreg Clayton 
138044d93782SGreg Clayton 
138144d93782SGreg Clayton // This function handles events that were broadcast by the process.
138244d93782SGreg Clayton void
138344d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
138444d93782SGreg Clayton {
138544d93782SGreg Clayton     using namespace lldb;
138644d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
138744d93782SGreg Clayton 
138844d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
138944d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
139044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
139144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
139244d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
139344d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
139444d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
139544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
139644d93782SGreg Clayton //    {
139744d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
139844d93782SGreg Clayton //    }
139944d93782SGreg Clayton //
140044d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
140144d93782SGreg Clayton     {
140244d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
140344d93782SGreg Clayton         if (num_new_locations > 0)
140444d93782SGreg Clayton         {
140544d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
14064446487dSPavel Labath             StreamSP output_sp (GetAsyncOutputStream());
140744d93782SGreg Clayton             if (output_sp)
140844d93782SGreg Clayton             {
140944d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
141044d93782SGreg Clayton                                   num_new_locations,
141144d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
141244d93782SGreg Clayton                                   breakpoint->GetID());
14134446487dSPavel Labath                 output_sp->Flush();
141444d93782SGreg Clayton             }
141544d93782SGreg Clayton         }
141644d93782SGreg Clayton     }
141744d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
141844d93782SGreg Clayton //    {
141944d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
142044d93782SGreg Clayton //    }
142144d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
142244d93782SGreg Clayton //    {
142344d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
142444d93782SGreg Clayton //    }
142544d93782SGreg Clayton }
142644d93782SGreg Clayton 
142744d93782SGreg Clayton size_t
142844d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
142944d93782SGreg Clayton {
143044d93782SGreg Clayton     size_t total_bytes = 0;
143144d93782SGreg Clayton     if (stream == NULL)
143244d93782SGreg Clayton         stream = GetOutputFile().get();
143344d93782SGreg Clayton 
143444d93782SGreg Clayton     if (stream)
143544d93782SGreg Clayton     {
143644d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
143744d93782SGreg Clayton         if (process == NULL)
143844d93782SGreg Clayton         {
143944d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
144044d93782SGreg Clayton             if (target_sp)
144144d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
144244d93782SGreg Clayton         }
144344d93782SGreg Clayton         if (process)
144444d93782SGreg Clayton         {
144544d93782SGreg Clayton             Error error;
144644d93782SGreg Clayton             size_t len;
144744d93782SGreg Clayton             char stdio_buffer[1024];
144844d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
144944d93782SGreg Clayton             {
145044d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
145144d93782SGreg Clayton                 total_bytes += len;
145244d93782SGreg Clayton             }
145344d93782SGreg Clayton         }
145444d93782SGreg Clayton         stream->Flush();
145544d93782SGreg Clayton     }
145644d93782SGreg Clayton     return total_bytes;
145744d93782SGreg Clayton }
145844d93782SGreg Clayton 
145944d93782SGreg Clayton size_t
146044d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
146144d93782SGreg Clayton {
146244d93782SGreg Clayton     size_t total_bytes = 0;
146344d93782SGreg Clayton     if (stream == NULL)
146444d93782SGreg Clayton         stream = GetOutputFile().get();
146544d93782SGreg Clayton 
146644d93782SGreg Clayton     if (stream)
146744d93782SGreg Clayton     {
146844d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
146944d93782SGreg Clayton         if (process == NULL)
147044d93782SGreg Clayton         {
147144d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
147244d93782SGreg Clayton             if (target_sp)
147344d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
147444d93782SGreg Clayton         }
147544d93782SGreg Clayton         if (process)
147644d93782SGreg Clayton         {
147744d93782SGreg Clayton             Error error;
147844d93782SGreg Clayton             size_t len;
147944d93782SGreg Clayton             char stdio_buffer[1024];
148044d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
148144d93782SGreg Clayton             {
148244d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
148344d93782SGreg Clayton                 total_bytes += len;
148444d93782SGreg Clayton             }
148544d93782SGreg Clayton         }
148644d93782SGreg Clayton         stream->Flush();
148744d93782SGreg Clayton     }
148844d93782SGreg Clayton     return total_bytes;
148944d93782SGreg Clayton }
149044d93782SGreg Clayton 
1491dc6224e0SGreg Clayton 
149244d93782SGreg Clayton // This function handles events that were broadcast by the process.
149344d93782SGreg Clayton void
149444d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
149544d93782SGreg Clayton {
149644d93782SGreg Clayton     using namespace lldb;
149744d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
149844d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
149944d93782SGreg Clayton 
15004446487dSPavel Labath     StreamSP output_stream_sp = GetAsyncOutputStream();
15014446487dSPavel Labath     StreamSP error_stream_sp = GetAsyncErrorStream();
150244d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
150344d93782SGreg Clayton 
1504b4874f1aSGreg Clayton     if (!gui_enabled)
1505b4874f1aSGreg Clayton     {
1506b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
150744d93782SGreg Clayton         assert (process_sp);
150844d93782SGreg Clayton 
15094446487dSPavel Labath         bool state_is_stopped = false;
15104446487dSPavel Labath         const bool got_state_changed = (event_type & Process::eBroadcastBitStateChanged) != 0;
15114446487dSPavel Labath         const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
15124446487dSPavel Labath         const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
15134446487dSPavel Labath         if (got_state_changed)
151444d93782SGreg Clayton         {
15154446487dSPavel Labath             StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
15164446487dSPavel Labath             state_is_stopped = StateIsStoppedState(event_state, false);
151744d93782SGreg Clayton         }
1518b4874f1aSGreg Clayton 
15194446487dSPavel Labath         // Display running state changes first before any STDIO
15204446487dSPavel Labath         if (got_state_changed && !state_is_stopped)
152144d93782SGreg Clayton         {
15224446487dSPavel Labath             Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
152344d93782SGreg Clayton         }
1524b4874f1aSGreg Clayton 
15254446487dSPavel Labath         // Now display and STDOUT
15264446487dSPavel Labath         if (got_stdout || got_state_changed)
152744d93782SGreg Clayton         {
15284446487dSPavel Labath             GetProcessSTDOUT (process_sp.get(), output_stream_sp.get());
152944d93782SGreg Clayton         }
1530b4874f1aSGreg Clayton 
15314446487dSPavel Labath         // Now display and STDERR
15324446487dSPavel Labath         if (got_stderr || got_state_changed)
1533b4874f1aSGreg Clayton         {
15344446487dSPavel Labath             GetProcessSTDERR (process_sp.get(), error_stream_sp.get());
1535b4874f1aSGreg Clayton         }
1536b4874f1aSGreg Clayton 
15374446487dSPavel Labath         // Now display any stopped state changes after any STDIO
15384446487dSPavel Labath         if (got_state_changed && state_is_stopped)
1539b4874f1aSGreg Clayton         {
15404446487dSPavel Labath             Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
154144d93782SGreg Clayton         }
154244d93782SGreg Clayton 
15434446487dSPavel Labath         output_stream_sp->Flush();
15444446487dSPavel Labath         error_stream_sp->Flush();
154544d93782SGreg Clayton 
1546b4874f1aSGreg Clayton         if (pop_process_io_handler)
1547b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
1548b4874f1aSGreg Clayton     }
1549b4874f1aSGreg Clayton }
1550b4874f1aSGreg Clayton 
155144d93782SGreg Clayton void
155244d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
155344d93782SGreg Clayton {
155444d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
155544d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
155644d93782SGreg Clayton     using namespace lldb;
155744d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
155844d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
155944d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
156044d93782SGreg Clayton     {
156144d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
156244d93782SGreg Clayton         if (thread_sp)
156344d93782SGreg Clayton         {
15644446487dSPavel Labath             thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1);
156544d93782SGreg Clayton         }
156644d93782SGreg Clayton     }
156744d93782SGreg Clayton }
156844d93782SGreg Clayton 
156944d93782SGreg Clayton bool
157044d93782SGreg Clayton Debugger::IsForwardingEvents ()
157144d93782SGreg Clayton {
157244d93782SGreg Clayton     return (bool)m_forward_listener_sp;
157344d93782SGreg Clayton }
157444d93782SGreg Clayton 
157544d93782SGreg Clayton void
157644d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
157744d93782SGreg Clayton {
157844d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
157944d93782SGreg Clayton }
158044d93782SGreg Clayton 
158144d93782SGreg Clayton void
158244d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
158344d93782SGreg Clayton {
158444d93782SGreg Clayton     m_forward_listener_sp.reset();
158544d93782SGreg Clayton }
158644d93782SGreg Clayton 
158744d93782SGreg Clayton 
158844d93782SGreg Clayton void
158944d93782SGreg Clayton Debugger::DefaultEventHandler()
159044d93782SGreg Clayton {
159144d93782SGreg Clayton     Listener& listener(GetListener());
159244d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
159344d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
159444d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
159544d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
159644d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
159744d93782SGreg Clayton 
159844d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
159944d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
160044d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
160144d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
160244d93782SGreg Clayton 
160344d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
160444d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
160544d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
160644d93782SGreg Clayton 
160744d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
160844d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
160944d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
161044d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
161144d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
161244d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
161344d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
161444d93782SGreg Clayton 
1615afa91e33SGreg Clayton     // Let the thread that spawned us know that we have started up and
1616afa91e33SGreg Clayton     // that we are now listening to all required events so no events get missed
1617afa91e33SGreg Clayton     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
1618afa91e33SGreg Clayton 
161944d93782SGreg Clayton     bool done = false;
162044d93782SGreg Clayton     while (!done)
162144d93782SGreg Clayton     {
162244d93782SGreg Clayton         EventSP event_sp;
162344d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
162444d93782SGreg Clayton         {
162544d93782SGreg Clayton             if (event_sp)
162644d93782SGreg Clayton             {
162744d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
162844d93782SGreg Clayton                 if (broadcaster)
162944d93782SGreg Clayton                 {
163044d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
163144d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
163244d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
163344d93782SGreg Clayton                     {
163444d93782SGreg Clayton                         HandleProcessEvent (event_sp);
163544d93782SGreg Clayton                     }
163644d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
163744d93782SGreg Clayton                     {
163844d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
163944d93782SGreg Clayton                         {
164044d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
164144d93782SGreg Clayton                         }
164244d93782SGreg Clayton                     }
164344d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
164444d93782SGreg Clayton                     {
164544d93782SGreg Clayton                         HandleThreadEvent (event_sp);
164644d93782SGreg Clayton                     }
164744d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
164844d93782SGreg Clayton                     {
164944d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
165044d93782SGreg Clayton                         {
165144d93782SGreg Clayton                             done = true;
165244d93782SGreg Clayton                         }
165344d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
165444d93782SGreg Clayton                         {
165544d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
165644d93782SGreg Clayton                             if (data && data[0])
165744d93782SGreg Clayton                             {
16584446487dSPavel Labath                                 StreamSP error_sp (GetAsyncErrorStream());
165944d93782SGreg Clayton                                 if (error_sp)
166044d93782SGreg Clayton                                 {
166144d93782SGreg Clayton                                     error_sp->PutCString(data);
166244d93782SGreg Clayton                                     error_sp->Flush();
166344d93782SGreg Clayton                                 }
166444d93782SGreg Clayton                             }
166544d93782SGreg Clayton                         }
166644d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
166744d93782SGreg Clayton                         {
166844d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
166944d93782SGreg Clayton                             if (data && data[0])
167044d93782SGreg Clayton                             {
16714446487dSPavel Labath                                 StreamSP output_sp (GetAsyncOutputStream());
167244d93782SGreg Clayton                                 if (output_sp)
167344d93782SGreg Clayton                                 {
167444d93782SGreg Clayton                                     output_sp->PutCString(data);
167544d93782SGreg Clayton                                     output_sp->Flush();
167644d93782SGreg Clayton                                 }
167744d93782SGreg Clayton                             }
167844d93782SGreg Clayton                         }
167944d93782SGreg Clayton                     }
168044d93782SGreg Clayton                 }
168144d93782SGreg Clayton 
168244d93782SGreg Clayton                 if (m_forward_listener_sp)
168344d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
168444d93782SGreg Clayton             }
168544d93782SGreg Clayton         }
168644d93782SGreg Clayton     }
168744d93782SGreg Clayton }
168844d93782SGreg Clayton 
168944d93782SGreg Clayton lldb::thread_result_t
169044d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
169144d93782SGreg Clayton {
169244d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
169344d93782SGreg Clayton     return NULL;
169444d93782SGreg Clayton }
169544d93782SGreg Clayton 
169644d93782SGreg Clayton bool
169744d93782SGreg Clayton Debugger::StartEventHandlerThread()
169844d93782SGreg Clayton {
1699acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
1700807b6b32SGreg Clayton     {
1701afa91e33SGreg Clayton         // We must synchronize with the DefaultEventHandler() thread to ensure
1702afa91e33SGreg Clayton         // it is up and running and listening to events before we return from
1703afa91e33SGreg Clayton         // this function. We do this by listening to events for the
1704afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
1705afa91e33SGreg Clayton         Listener listener("lldb.debugger.event-handler");
1706afa91e33SGreg Clayton         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
1707afa91e33SGreg Clayton 
17087c2896a2SZachary Turner         // Use larger 8MB stack for this thread
1709afa91e33SGreg Clayton         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
1710afa91e33SGreg Clayton                                                               this,
1711afa91e33SGreg Clayton                                                               NULL,
17127c2896a2SZachary Turner                                                               g_debugger_event_thread_stack_bytes);
1713afa91e33SGreg Clayton 
1714afa91e33SGreg Clayton         // Make sure DefaultEventHandler() is running and listening to events before we return
1715afa91e33SGreg Clayton         // from this function. We are only listening for events of type
1716afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
1717afa91e33SGreg Clayton         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
1718afa91e33SGreg Clayton         lldb::EventSP event_sp;
1719afa91e33SGreg Clayton         listener.WaitForEvent(NULL, event_sp);
1720807b6b32SGreg Clayton     }
1721acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
172244d93782SGreg Clayton }
172344d93782SGreg Clayton 
172444d93782SGreg Clayton void
172544d93782SGreg Clayton Debugger::StopEventHandlerThread()
172644d93782SGreg Clayton {
1727acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
172844d93782SGreg Clayton     {
172944d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
173039de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
173144d93782SGreg Clayton     }
173244d93782SGreg Clayton }
173344d93782SGreg Clayton 
173444d93782SGreg Clayton 
173544d93782SGreg Clayton lldb::thread_result_t
173644d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
173744d93782SGreg Clayton {
173844d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
17399aaab558SSiva Chandra     debugger->ExecuteIOHandlers();
174044d93782SGreg Clayton     debugger->StopEventHandlerThread();
174144d93782SGreg Clayton     return NULL;
174244d93782SGreg Clayton }
174344d93782SGreg Clayton 
174444d93782SGreg Clayton bool
17456681041dSSean Callanan Debugger::HasIOHandlerThread()
17466681041dSSean Callanan {
17476681041dSSean Callanan     return m_io_handler_thread.IsJoinable();
17486681041dSSean Callanan }
17496681041dSSean Callanan 
17506681041dSSean Callanan bool
175144d93782SGreg Clayton Debugger::StartIOHandlerThread()
175244d93782SGreg Clayton {
1753acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
1754807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
1755807b6b32SGreg Clayton                                                             IOHandlerThread,
1756807b6b32SGreg Clayton                                                             this,
1757807b6b32SGreg Clayton                                                             NULL,
1758807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
1759acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
176044d93782SGreg Clayton }
176144d93782SGreg Clayton 
176244d93782SGreg Clayton void
176344d93782SGreg Clayton Debugger::StopIOHandlerThread()
176444d93782SGreg Clayton {
1765acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
176644d93782SGreg Clayton     {
176744d93782SGreg Clayton         if (m_input_file_sp)
176844d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
176939de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
177044d93782SGreg Clayton     }
177144d93782SGreg Clayton }
177244d93782SGreg Clayton 
17736681041dSSean Callanan void
17746681041dSSean Callanan Debugger::JoinIOHandlerThread()
17756681041dSSean Callanan {
17766681041dSSean Callanan     if (HasIOHandlerThread())
17776681041dSSean Callanan     {
17786681041dSSean Callanan         thread_result_t result;
17796681041dSSean Callanan         m_io_handler_thread.Join(&result);
17806681041dSSean Callanan         m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
17816681041dSSean Callanan     }
17826681041dSSean Callanan }
17836681041dSSean Callanan 
1784893c932aSJim Ingham Target *
1785893c932aSJim Ingham Debugger::GetDummyTarget()
1786893c932aSJim Ingham {
1787893c932aSJim Ingham     return m_target_list.GetDummyTarget (*this).get();
1788893c932aSJim Ingham }
1789893c932aSJim Ingham 
1790893c932aSJim Ingham Target *
179133df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
1792893c932aSJim Ingham {
179333df7cd3SJim Ingham     Target *target = nullptr;
179433df7cd3SJim Ingham     if (!prefer_dummy)
179533df7cd3SJim Ingham     {
179633df7cd3SJim Ingham         target = m_target_list.GetSelectedTarget().get();
179733df7cd3SJim Ingham         if (target)
179833df7cd3SJim Ingham             return target;
179933df7cd3SJim Ingham     }
1800893c932aSJim Ingham 
1801893c932aSJim Ingham     return GetDummyTarget();
1802893c932aSJim Ingham }
180344d93782SGreg Clayton 
18043e7e915dSSean Callanan Error
18053e7e915dSSean Callanan Debugger::RunREPL (LanguageType language, const char *repl_options)
18063e7e915dSSean Callanan {
18073e7e915dSSean Callanan     Error err;
18083e7e915dSSean Callanan     FileSpec repl_executable;
18093e7e915dSSean Callanan 
181097f84e87SSean Callanan     if (language == eLanguageTypeUnknown)
181197f84e87SSean Callanan     {
181297f84e87SSean Callanan         std::set<LanguageType> repl_languages;
181397f84e87SSean Callanan 
181497f84e87SSean Callanan         Language::GetLanguagesSupportingREPLs(repl_languages);
181597f84e87SSean Callanan 
181697f84e87SSean Callanan         if (repl_languages.size() == 1)
181797f84e87SSean Callanan         {
181897f84e87SSean Callanan             language = *repl_languages.begin();
181997f84e87SSean Callanan         }
182097f84e87SSean Callanan         else if (repl_languages.size() == 0)
182197f84e87SSean Callanan         {
182297f84e87SSean Callanan             err.SetErrorStringWithFormat("LLDB isn't configured with support support for any REPLs.");
182397f84e87SSean Callanan             return err;
182497f84e87SSean Callanan         }
182597f84e87SSean Callanan         else
182697f84e87SSean Callanan         {
182797f84e87SSean Callanan             err.SetErrorStringWithFormat("Multiple possible REPL languages.  Please specify a language.");
182897f84e87SSean Callanan             return err;
182997f84e87SSean Callanan         }
183097f84e87SSean Callanan     }
183197f84e87SSean Callanan 
18323e7e915dSSean Callanan     Target *const target = nullptr; // passing in an empty target means the REPL must create one
18333e7e915dSSean Callanan 
18343b682de6SSean Callanan     REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
18353e7e915dSSean Callanan 
18363e7e915dSSean Callanan     if (!err.Success())
18373e7e915dSSean Callanan     {
18383e7e915dSSean Callanan         return err;
18393e7e915dSSean Callanan     }
18403e7e915dSSean Callanan 
18413e7e915dSSean Callanan     if (!repl_sp)
18423e7e915dSSean Callanan     {
18433e7e915dSSean Callanan         err.SetErrorStringWithFormat("couldn't find a REPL for %s", Language::GetNameForLanguageType(language));
18443e7e915dSSean Callanan         return err;
18453e7e915dSSean Callanan     }
18463e7e915dSSean Callanan 
18473e7e915dSSean Callanan     repl_sp->SetCompilerOptions(repl_options);
18483e7e915dSSean Callanan     repl_sp->RunLoop();
18493e7e915dSSean Callanan 
18503e7e915dSSean Callanan     return err;
18513e7e915dSSean Callanan }
18523e7e915dSSean Callanan 
1853