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 
144becb37eSEnrico Granata #include "clang/AST/DeclCXX.h"
154becb37eSEnrico Granata #include "clang/AST/Type.h"
16705b1809SJason Molenda #include "llvm/ADT/StringRef.h"
174becb37eSEnrico Granata 
1830fdc8d8SChris Lattner #include "lldb/lldb-private.h"
19554f68d3SGreg Clayton #include "lldb/Core/FormatEntity.h"
201f746071SGreg Clayton #include "lldb/Core/Module.h"
21*0d5a2bd6SJim Ingham #include "lldb/Core/PluginInterface.h"
22e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
237349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2430fdc8d8SChris Lattner #include "lldb/Core/State.h"
255b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
26228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
2744d93782SGreg Clayton #include "lldb/Core/StreamFile.h"
281b654882SGreg Clayton #include "lldb/Core/StreamString.h"
29705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
3030fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
314becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
326d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
335548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
35894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h"
3693a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h"
3742ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h"
38a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
3939de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h"
406611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
41633a29cfSZachary Turner #include "lldb/Interpreter/OptionValueProperties.h"
4267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4367cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
441f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
451f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
461f746071SGreg Clayton #include "lldb/Symbol/Function.h"
471f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
486d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
4930fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
5030fdc8d8SChris Lattner #include "lldb/Target/Process.h"
511b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
525fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h"
531b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5484a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5530fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
565a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5730fdc8d8SChris Lattner 
5858a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h"
5958a559c0SZachary Turner 
6030fdc8d8SChris Lattner using namespace lldb;
6130fdc8d8SChris Lattner using namespace lldb_private;
6230fdc8d8SChris Lattner 
6330fdc8d8SChris Lattner 
64ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
657c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
66ebc1bb27SCaroline Tice 
671b654882SGreg Clayton #pragma mark Static Functions
681b654882SGreg Clayton 
691b654882SGreg Clayton static Mutex &
701b654882SGreg Clayton GetDebuggerListMutex ()
711b654882SGreg Clayton {
721b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
731b654882SGreg Clayton     return g_mutex;
741b654882SGreg Clayton }
751b654882SGreg Clayton 
761b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
771b654882SGreg Clayton 
781b654882SGreg Clayton static DebuggerList &
791b654882SGreg Clayton GetDebuggerList()
801b654882SGreg Clayton {
811b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
826a7f3338SBruce Mitchener     // global init constructors
831b654882SGreg Clayton     static DebuggerList g_list;
841b654882SGreg Clayton     return g_list;
851b654882SGreg Clayton }
86e372b98dSGreg Clayton 
87e372b98dSGreg Clayton OptionEnumValueElement
8867cc0636SGreg Clayton g_show_disassembly_enum_values[] =
89e372b98dSGreg Clayton {
9067cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
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." },
15467cc0636SGreg Clayton {   "stop-disassembly-display", OptionValue::eTypeEnum        , true, Debugger::eStopDisassemblyTypeNoSource, 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)." },
162ebdc1ac0SEnrico Granata {   "escape-non-printables",    OptionValue::eTypeBoolean     , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
16367cc0636SGreg Clayton {   NULL,                       OptionValue::eTypeInvalid     , true, 0    , NULL, NULL, NULL }
16467cc0636SGreg Clayton };
16567cc0636SGreg Clayton 
16667cc0636SGreg Clayton enum
16767cc0636SGreg Clayton {
16867cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
169aff1b357SJason Molenda     ePropertyDisassemblyFormat,
17067cc0636SGreg Clayton     ePropertyFrameFormat,
17167cc0636SGreg Clayton     ePropertyNotiftVoid,
17267cc0636SGreg Clayton     ePropertyPrompt,
17367cc0636SGreg Clayton     ePropertyScriptLanguage,
17467cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
17567cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
17667cc0636SGreg Clayton     ePropertyStopLineCountAfter,
17767cc0636SGreg Clayton     ePropertyStopLineCountBefore,
17867cc0636SGreg Clayton     ePropertyTerminalWidth,
17967cc0636SGreg Clayton     ePropertyThreadFormat,
180c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
181c3ce7f27SMichael Sartain     ePropertyUseColor,
182ebdc1ac0SEnrico Granata     ePropertyAutoOneLineSummaries,
183ebdc1ac0SEnrico Granata     ePropertyEscapeNonPrintables
18467cc0636SGreg Clayton };
18567cc0636SGreg Clayton 
1863a00691fSZachary Turner LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1874c05410fSGreg Clayton 
1884c05410fSGreg Clayton Error
1894c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1904c05410fSGreg Clayton                             VarSetOperationType op,
1914c05410fSGreg Clayton                             const char *property_path,
1924c05410fSGreg Clayton                             const char *value)
1934c05410fSGreg Clayton {
19484a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
195ebdc1ac0SEnrico Granata     bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
19684a53dfbSEnrico Granata     TargetSP target_sp;
197397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
19884a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
19984a53dfbSEnrico Granata     {
20084a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
20184a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
20284a53dfbSEnrico Granata     }
2034c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
2044c05410fSGreg Clayton     if (error.Success())
2054c05410fSGreg Clayton     {
20684a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
2074c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
2084c05410fSGreg Clayton         {
2094c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
210c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
211c3ce7f27SMichael Sartain             if (str.length())
212c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
21344d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
2144c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
2154c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
2164c05410fSGreg Clayton         }
217c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
218c3ce7f27SMichael Sartain         {
219c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
220c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
221c3ce7f27SMichael Sartain         }
222397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
22384a53dfbSEnrico Granata         {
224397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
22584a53dfbSEnrico Granata             {
22684a53dfbSEnrico Granata                 std::list<Error> errors;
2279730339bSEnrico Granata                 StreamString feedback_stream;
2289730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
22984a53dfbSEnrico Granata                 {
23044d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
23144d93782SGreg Clayton                     if (stream_sp)
23244d93782SGreg Clayton                     {
23384a53dfbSEnrico Granata                         for (auto error : errors)
23484a53dfbSEnrico Granata                         {
23544d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
23684a53dfbSEnrico Granata                         }
2379730339bSEnrico Granata                         if (feedback_stream.GetSize())
23844d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
23944d93782SGreg Clayton                     }
24084a53dfbSEnrico Granata                 }
24184a53dfbSEnrico Granata             }
24284a53dfbSEnrico Granata         }
243ebdc1ac0SEnrico Granata         else if (is_escape_non_printables)
244ebdc1ac0SEnrico Granata         {
245ebdc1ac0SEnrico Granata             DataVisualization::ForceUpdate();
246ebdc1ac0SEnrico Granata         }
2474c05410fSGreg Clayton     }
2484c05410fSGreg Clayton     return error;
2494c05410fSGreg Clayton }
2504c05410fSGreg Clayton 
25167cc0636SGreg Clayton bool
25267cc0636SGreg Clayton Debugger::GetAutoConfirm () const
25367cc0636SGreg Clayton {
25467cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
255754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
25667cc0636SGreg Clayton }
25767cc0636SGreg Clayton 
258554f68d3SGreg Clayton const FormatEntity::Entry *
259aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const
260aff1b357SJason Molenda {
261aff1b357SJason Molenda     const uint32_t idx = ePropertyDisassemblyFormat;
262554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
263aff1b357SJason Molenda }
264aff1b357SJason Molenda 
265554f68d3SGreg Clayton const FormatEntity::Entry *
26667cc0636SGreg Clayton Debugger::GetFrameFormat() const
26767cc0636SGreg Clayton {
26867cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
269554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
27067cc0636SGreg Clayton }
27167cc0636SGreg Clayton 
27267cc0636SGreg Clayton bool
27367cc0636SGreg Clayton Debugger::GetNotifyVoid () const
27467cc0636SGreg Clayton {
27567cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
276754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
27767cc0636SGreg Clayton }
27867cc0636SGreg Clayton 
27967cc0636SGreg Clayton const char *
28067cc0636SGreg Clayton Debugger::GetPrompt() const
28167cc0636SGreg Clayton {
28267cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
283754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
28467cc0636SGreg Clayton }
28567cc0636SGreg Clayton 
28667cc0636SGreg Clayton void
28767cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
28867cc0636SGreg Clayton {
28967cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
29067cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
29167cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
292c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
293c3ce7f27SMichael Sartain     if (str.length())
294c3ce7f27SMichael Sartain         new_prompt = str.c_str();
29544d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
29667cc0636SGreg Clayton }
29767cc0636SGreg Clayton 
298554f68d3SGreg Clayton const FormatEntity::Entry *
29967cc0636SGreg Clayton Debugger::GetThreadFormat() const
30067cc0636SGreg Clayton {
30167cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
302554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
30367cc0636SGreg Clayton }
30467cc0636SGreg Clayton 
30567cc0636SGreg Clayton lldb::ScriptLanguage
30667cc0636SGreg Clayton Debugger::GetScriptLanguage() const
30767cc0636SGreg Clayton {
30867cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
309754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
31067cc0636SGreg Clayton }
31167cc0636SGreg Clayton 
31267cc0636SGreg Clayton bool
31367cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
31467cc0636SGreg Clayton {
31567cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
31667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
31767cc0636SGreg Clayton }
31867cc0636SGreg Clayton 
31967cc0636SGreg Clayton uint32_t
32067cc0636SGreg Clayton Debugger::GetTerminalWidth () const
32167cc0636SGreg Clayton {
32267cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
323754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
32467cc0636SGreg Clayton }
32567cc0636SGreg Clayton 
32667cc0636SGreg Clayton bool
32767cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
32867cc0636SGreg Clayton {
32967cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
33067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
33167cc0636SGreg Clayton }
33267cc0636SGreg Clayton 
33367cc0636SGreg Clayton bool
33467cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
33567cc0636SGreg Clayton {
33667cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
337754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
33867cc0636SGreg Clayton }
33967cc0636SGreg Clayton 
34067cc0636SGreg Clayton bool
34167cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
34267cc0636SGreg Clayton {
34367cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
34467cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
34567cc0636SGreg Clayton }
34667cc0636SGreg Clayton 
347c3ce7f27SMichael Sartain bool
348c3ce7f27SMichael Sartain Debugger::GetUseColor () const
349c3ce7f27SMichael Sartain {
350c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
351c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
352c3ce7f27SMichael Sartain }
353c3ce7f27SMichael Sartain 
354c3ce7f27SMichael Sartain bool
355c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
356c3ce7f27SMichael Sartain {
357c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
358c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
359c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
360c3ce7f27SMichael Sartain     return ret;
361c3ce7f27SMichael Sartain }
362c3ce7f27SMichael Sartain 
36367cc0636SGreg Clayton uint32_t
36467cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
36567cc0636SGreg Clayton {
36667cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
367754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
36867cc0636SGreg Clayton }
36967cc0636SGreg Clayton 
37067cc0636SGreg Clayton Debugger::StopDisassemblyType
37167cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
37267cc0636SGreg Clayton {
37367cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
374754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
37567cc0636SGreg Clayton }
37667cc0636SGreg Clayton 
37767cc0636SGreg Clayton uint32_t
37867cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
37967cc0636SGreg Clayton {
38067cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
381754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
38267cc0636SGreg Clayton }
383e372b98dSGreg Clayton 
384553fad5cSEnrico Granata bool
38590a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
386553fad5cSEnrico Granata {
38790a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
388553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
389ebdc1ac0SEnrico Granata }
390553fad5cSEnrico Granata 
391ebdc1ac0SEnrico Granata bool
392ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const
393ebdc1ac0SEnrico Granata {
394ebdc1ac0SEnrico Granata     const uint32_t idx = ePropertyEscapeNonPrintables;
395ebdc1ac0SEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
396553fad5cSEnrico Granata }
397553fad5cSEnrico Granata 
3981b654882SGreg Clayton #pragma mark Debugger
3991b654882SGreg Clayton 
40067cc0636SGreg Clayton //const DebuggerPropertiesSP &
40167cc0636SGreg Clayton //Debugger::GetSettings() const
40267cc0636SGreg Clayton //{
40367cc0636SGreg Clayton //    return m_properties_sp;
40467cc0636SGreg Clayton //}
40567cc0636SGreg Clayton //
40699d0faf2SGreg Clayton 
407e6e2bb38SZachary Turner static bool lldb_initialized = false;
40830fdc8d8SChris Lattner void
4095fb8f797SGreg Clayton Debugger::Initialize(LoadPluginCallbackType load_plugin_callback)
41030fdc8d8SChris Lattner {
411e6e2bb38SZachary Turner     assert(!lldb_initialized && "Debugger::Initialize called more than once!");
412e6e2bb38SZachary Turner 
413f196c931SRobert Flack     lldb_initialized = true;
4145fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
41599d0faf2SGreg Clayton }
41630fdc8d8SChris Lattner 
417e6e2bb38SZachary Turner void
41830fdc8d8SChris Lattner Debugger::Terminate ()
41930fdc8d8SChris Lattner {
420e6e2bb38SZachary Turner     assert(lldb_initialized && "Debugger::Terminate called without a matching Debugger::Initialize!");
421e6e2bb38SZachary Turner 
42299d0faf2SGreg Clayton     // Clear our master list of debugger objects
42399d0faf2SGreg Clayton     Mutex::Locker locker (GetDebuggerListMutex ());
42499d0faf2SGreg Clayton     GetDebuggerList().clear();
42530fdc8d8SChris Lattner }
42630fdc8d8SChris Lattner 
42720bd37f7SCaroline Tice void
42820bd37f7SCaroline Tice Debugger::SettingsInitialize ()
42920bd37f7SCaroline Tice {
4306920b52bSGreg Clayton     Target::SettingsInitialize ();
43120bd37f7SCaroline Tice }
43220bd37f7SCaroline Tice 
43320bd37f7SCaroline Tice void
43420bd37f7SCaroline Tice Debugger::SettingsTerminate ()
43520bd37f7SCaroline Tice {
4366920b52bSGreg Clayton     Target::SettingsTerminate ();
43720bd37f7SCaroline Tice }
43820bd37f7SCaroline Tice 
43921dfcd9dSEnrico Granata bool
440e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
44121dfcd9dSEnrico Granata {
4425fb8f797SGreg Clayton     if (g_load_plugin_callback)
443e743c782SEnrico Granata     {
44458a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
44558a559c0SZachary Turner         if (dynlib.isValid())
44621dfcd9dSEnrico Granata         {
44758a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
44821dfcd9dSEnrico Granata             return true;
44921dfcd9dSEnrico Granata         }
4505fb8f797SGreg Clayton     }
4515fb8f797SGreg Clayton     else
4525fb8f797SGreg Clayton     {
4535fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4545fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4555fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4565fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4575fb8f797SGreg Clayton     }
45821dfcd9dSEnrico Granata     return false;
45921dfcd9dSEnrico Granata }
46021dfcd9dSEnrico Granata 
46121dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
46221dfcd9dSEnrico Granata LoadPluginCallback
46321dfcd9dSEnrico Granata (
46421dfcd9dSEnrico Granata  void *baton,
46521dfcd9dSEnrico Granata  FileSpec::FileType file_type,
46621dfcd9dSEnrico Granata  const FileSpec &file_spec
46721dfcd9dSEnrico Granata  )
46821dfcd9dSEnrico Granata {
46921dfcd9dSEnrico Granata     Error error;
47021dfcd9dSEnrico Granata 
47121dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4723cf443ddSMichael Sartain     static ConstString g_solibext("so");
47321dfcd9dSEnrico Granata 
47421dfcd9dSEnrico Granata     if (!baton)
47521dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
47621dfcd9dSEnrico Granata 
47721dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
47821dfcd9dSEnrico Granata 
47921dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
48021dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
48121dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
48221dfcd9dSEnrico Granata     // file type information.
48321dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
48421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
48521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
48621dfcd9dSEnrico Granata     {
48721dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
48821dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
48921dfcd9dSEnrico Granata 
4903cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4913cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4923cf443ddSMichael Sartain         {
49321dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4943cf443ddSMichael Sartain         }
49521dfcd9dSEnrico Granata 
496e743c782SEnrico Granata         Error plugin_load_error;
497e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
49821dfcd9dSEnrico Granata 
49921dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
50021dfcd9dSEnrico Granata     }
50121dfcd9dSEnrico Granata 
50221dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
50321dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
50421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
50521dfcd9dSEnrico Granata     {
50621dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
50721dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
5086a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
50921dfcd9dSEnrico Granata         // information.
51021dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
51121dfcd9dSEnrico Granata     }
51221dfcd9dSEnrico Granata 
51321dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
51421dfcd9dSEnrico Granata }
51521dfcd9dSEnrico Granata 
51621dfcd9dSEnrico Granata void
51721dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
51821dfcd9dSEnrico Granata {
51921dfcd9dSEnrico Granata     FileSpec dir_spec;
52021dfcd9dSEnrico Granata     const bool find_directories = true;
52121dfcd9dSEnrico Granata     const bool find_files = true;
52221dfcd9dSEnrico Granata     const bool find_other = true;
52321dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
52442ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
52521dfcd9dSEnrico Granata     {
52621dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
52721dfcd9dSEnrico Granata         {
52821dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
52921dfcd9dSEnrico Granata                                           find_directories,
53021dfcd9dSEnrico Granata                                           find_files,
53121dfcd9dSEnrico Granata                                           find_other,
53221dfcd9dSEnrico Granata                                           LoadPluginCallback,
53321dfcd9dSEnrico Granata                                           this);
53421dfcd9dSEnrico Granata         }
53521dfcd9dSEnrico Granata     }
53621dfcd9dSEnrico Granata 
53742ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
53821dfcd9dSEnrico Granata     {
53921dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
54021dfcd9dSEnrico Granata         {
54121dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
54221dfcd9dSEnrico Granata                                           find_directories,
54321dfcd9dSEnrico Granata                                           find_files,
54421dfcd9dSEnrico Granata                                           find_other,
54521dfcd9dSEnrico Granata                                           LoadPluginCallback,
54621dfcd9dSEnrico Granata                                           this);
54721dfcd9dSEnrico Granata         }
54821dfcd9dSEnrico Granata     }
549e8cd0c98SGreg Clayton 
550e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
55121dfcd9dSEnrico Granata }
55221dfcd9dSEnrico Granata 
5536611103cSGreg Clayton DebuggerSP
554228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5556611103cSGreg Clayton {
556228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
557e6e2bb38SZachary Turner     if (lldb_initialized)
5586611103cSGreg Clayton     {
5596611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5606611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5616611103cSGreg Clayton     }
56221dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5636611103cSGreg Clayton     return debugger_sp;
5646611103cSGreg Clayton }
5656611103cSGreg Clayton 
566e02657b1SCaroline Tice void
5674d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
568e02657b1SCaroline Tice {
569e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
570e02657b1SCaroline Tice         return;
571e02657b1SCaroline Tice 
5728314c525SJim Ingham     debugger_sp->Clear();
5738314c525SJim Ingham 
574e6e2bb38SZachary Turner     if (lldb_initialized)
575c15f55e2SGreg Clayton     {
576e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
577e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
578e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
579e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
580e02657b1SCaroline Tice         {
581e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
582e02657b1SCaroline Tice             {
583e02657b1SCaroline Tice                 debugger_list.erase (pos);
584e02657b1SCaroline Tice                 return;
585e02657b1SCaroline Tice             }
586e02657b1SCaroline Tice         }
587e02657b1SCaroline Tice     }
588c15f55e2SGreg Clayton }
589e02657b1SCaroline Tice 
5904d122c40SGreg Clayton DebuggerSP
5913df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5923df9a8dfSCaroline Tice {
5934d122c40SGreg Clayton     DebuggerSP debugger_sp;
594e6e2bb38SZachary Turner     if (lldb_initialized)
5956920b52bSGreg Clayton     {
5966920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5976920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5986920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5996920b52bSGreg Clayton 
6006920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6016920b52bSGreg Clayton         {
6026920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
6036920b52bSGreg Clayton             {
6046920b52bSGreg Clayton                 debugger_sp = *pos;
6056920b52bSGreg Clayton                 break;
6066920b52bSGreg Clayton             }
6076920b52bSGreg Clayton         }
6086920b52bSGreg Clayton     }
6093df9a8dfSCaroline Tice     return debugger_sp;
6103df9a8dfSCaroline Tice }
6116611103cSGreg Clayton 
6126611103cSGreg Clayton TargetSP
6136611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6146611103cSGreg Clayton {
6154d122c40SGreg Clayton     TargetSP target_sp;
616e6e2bb38SZachary Turner     if (lldb_initialized)
617c15f55e2SGreg Clayton     {
6186611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6196611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6206611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6216611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6226611103cSGreg Clayton         {
6236611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6246611103cSGreg Clayton             if (target_sp)
6256611103cSGreg Clayton                 break;
6266611103cSGreg Clayton         }
627c15f55e2SGreg Clayton     }
6286611103cSGreg Clayton     return target_sp;
6296611103cSGreg Clayton }
6306611103cSGreg Clayton 
631e4e45924SGreg Clayton TargetSP
632e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
633e4e45924SGreg Clayton {
634e4e45924SGreg Clayton     TargetSP target_sp;
635e6e2bb38SZachary Turner     if (lldb_initialized)
636c15f55e2SGreg Clayton     {
637e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
638e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
639e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
640e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
641e4e45924SGreg Clayton         {
642e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
643e4e45924SGreg Clayton             if (target_sp)
644e4e45924SGreg Clayton                 break;
645e4e45924SGreg Clayton         }
646c15f55e2SGreg Clayton     }
647e4e45924SGreg Clayton     return target_sp;
648e4e45924SGreg Clayton }
649e4e45924SGreg Clayton 
650e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
651e6481c7eSJason Molenda     UserID(g_unique_id++),
652e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
653e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
654e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
655e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
656e6481c7eSJason Molenda     m_terminal_state(),
657e6481c7eSJason Molenda     m_target_list(*this),
658e6481c7eSJason Molenda     m_platform_list(),
659e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
660e6481c7eSJason Molenda     m_source_manager_ap(),
661e6481c7eSJason Molenda     m_source_file_cache(),
662e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
663e6481c7eSJason Molenda     m_input_reader_stack(),
664e6481c7eSJason Molenda     m_instance_name(),
665afa91e33SGreg Clayton     m_loaded_plugins(),
666afa91e33SGreg Clayton     m_event_handler_thread (),
667afa91e33SGreg Clayton     m_io_handler_thread (),
668afa91e33SGreg Clayton     m_sync_broadcaster (NULL, "lldb.debugger.sync")
66930fdc8d8SChris Lattner {
67067cc0636SGreg Clayton     char instance_cstr[256];
67167cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
67267cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
673228063cdSJim Ingham     if (log_callback)
674228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6756611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
676ded470d3SGreg Clayton     // Always add our default platform to the platform list
677615eb7e6SGreg Clayton     PlatformSP default_platform_sp (Platform::GetHostPlatform());
678ded470d3SGreg Clayton     assert (default_platform_sp.get());
679ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
68067cc0636SGreg Clayton 
681754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
68267cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
68367cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
68467cc0636SGreg Clayton                                      true,
68567cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
68663acdfdeSOleksiy Vyalov     m_collection_sp->AppendProperty (ConstString("platform"),
68763acdfdeSOleksiy Vyalov                                      ConstString("Platform settings."),
68863acdfdeSOleksiy Vyalov                                      true,
68963acdfdeSOleksiy Vyalov                                      Platform::GetGlobalPlatformProperties()->GetValueProperties());
690754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
691754a9369SGreg Clayton     {
692754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
693754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
694754a9369SGreg Clayton                                          true,
695754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
696754a9369SGreg Clayton     }
69767cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
69867cc0636SGreg Clayton     term_width->SetMinimumValue(10);
69967cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
700c3ce7f27SMichael Sartain 
701c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
702c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
703c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
704c3ce7f27SMichael Sartain         SetUseColor (false);
70530fdc8d8SChris Lattner }
70630fdc8d8SChris Lattner 
70730fdc8d8SChris Lattner Debugger::~Debugger ()
70830fdc8d8SChris Lattner {
7098314c525SJim Ingham     Clear();
7108314c525SJim Ingham }
7118314c525SJim Ingham 
7128314c525SJim Ingham void
7138314c525SJim Ingham Debugger::Clear()
7148314c525SJim Ingham {
71544d93782SGreg Clayton     ClearIOHandlers();
71644d93782SGreg Clayton     StopIOHandlerThread();
71744d93782SGreg Clayton     StopEventHandlerThread();
7181ed54f50SGreg Clayton     m_listener.Clear();
7196611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
7206611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7216611103cSGreg Clayton     {
722ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
723ccbc08e6SGreg Clayton         if (target_sp)
724ccbc08e6SGreg Clayton         {
725ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7266611103cSGreg Clayton             if (process_sp)
7271fd07059SJim Ingham                 process_sp->Finalize();
728ccbc08e6SGreg Clayton             target_sp->Destroy();
7296611103cSGreg Clayton         }
73030fdc8d8SChris Lattner     }
7314bddaeb5SJim Ingham     BroadcasterManager::Clear ();
73230fdc8d8SChris Lattner 
7330d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7340d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
735c5917d9aSJim Ingham     m_terminal_state.Clear();
73644d93782SGreg Clayton     if (m_input_file_sp)
73744d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7380c4129f2SGreg Clayton 
7390c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7408314c525SJim Ingham }
74130fdc8d8SChris Lattner 
74230fdc8d8SChris Lattner bool
743fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
744fc3f027dSGreg Clayton {
74544d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
74644d93782SGreg Clayton     return false;
747fc3f027dSGreg Clayton }
748fc3f027dSGreg Clayton 
749fc3f027dSGreg Clayton void
750fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
751fc3f027dSGreg Clayton {
75244d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
753fc3f027dSGreg Clayton }
754fc3f027dSGreg Clayton 
755fc3f027dSGreg Clayton bool
75630fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
75730fdc8d8SChris Lattner {
7586611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
75930fdc8d8SChris Lattner }
76030fdc8d8SChris Lattner 
76130fdc8d8SChris Lattner void
76230fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
76330fdc8d8SChris Lattner {
7646611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
76530fdc8d8SChris Lattner }
76630fdc8d8SChris Lattner 
76730fdc8d8SChris Lattner 
76830fdc8d8SChris Lattner void
76930fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
77030fdc8d8SChris Lattner {
77144d93782SGreg Clayton     if (m_input_file_sp)
77244d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
77344d93782SGreg Clayton     else
77444d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
77544d93782SGreg Clayton 
77644d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
77751b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
77851b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
77930fdc8d8SChris Lattner 
780c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
781c5917d9aSJim Ingham     SaveInputTerminalState ();
78230fdc8d8SChris Lattner }
78330fdc8d8SChris Lattner 
78430fdc8d8SChris Lattner void
78530fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
78630fdc8d8SChris Lattner {
78744d93782SGreg Clayton     if (m_output_file_sp)
78844d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
78944d93782SGreg Clayton     else
79044d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
79144d93782SGreg Clayton 
79244d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
79351b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
79451b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7952f88aadfSCaroline Tice 
796b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
797b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
798b588726eSEnrico Granata     const bool can_create = false;
799b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
800b588726eSEnrico Granata     if (script_interpreter)
801b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
80230fdc8d8SChris Lattner }
80330fdc8d8SChris Lattner 
80430fdc8d8SChris Lattner void
80530fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
80630fdc8d8SChris Lattner {
80744d93782SGreg Clayton     if (m_error_file_sp)
80844d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
80944d93782SGreg Clayton     else
81044d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
81144d93782SGreg Clayton 
81244d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
81351b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
81451b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
81530fdc8d8SChris Lattner }
81630fdc8d8SChris Lattner 
817c5917d9aSJim Ingham void
818c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
819c5917d9aSJim Ingham {
82044d93782SGreg Clayton     if (m_input_file_sp)
82144d93782SGreg Clayton     {
82244d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
823c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
824c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
825c5917d9aSJim Ingham     }
82644d93782SGreg Clayton }
827c5917d9aSJim Ingham 
828c5917d9aSJim Ingham void
829c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
830c5917d9aSJim Ingham {
831c5917d9aSJim Ingham     m_terminal_state.Restore();
832c5917d9aSJim Ingham }
833c5917d9aSJim Ingham 
83430fdc8d8SChris Lattner ExecutionContext
8352976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
83630fdc8d8SChris Lattner {
83730fdc8d8SChris Lattner     ExecutionContext exe_ctx;
838c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
839c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
84030fdc8d8SChris Lattner 
84130fdc8d8SChris Lattner     if (target_sp)
84230fdc8d8SChris Lattner     {
843c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
844c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
845c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
84630fdc8d8SChris Lattner         {
847c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
848c14ee32dSGreg Clayton             if (thread_sp)
84930fdc8d8SChris Lattner             {
850c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
851c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
852c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
853c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
85430fdc8d8SChris Lattner             }
85530fdc8d8SChris Lattner         }
85630fdc8d8SChris Lattner     }
85730fdc8d8SChris Lattner     return exe_ctx;
85830fdc8d8SChris Lattner }
85930fdc8d8SChris Lattner 
86030fdc8d8SChris Lattner void
861efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
862efed6131SCaroline Tice {
86344d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
86444d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
865efed6131SCaroline Tice     if (reader_sp)
86644d93782SGreg Clayton         reader_sp->Interrupt();
867efed6131SCaroline Tice }
868efed6131SCaroline Tice 
869efed6131SCaroline Tice void
870efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
871efed6131SCaroline Tice {
87244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
87344d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
874efed6131SCaroline Tice     if (reader_sp)
87544d93782SGreg Clayton         reader_sp->GotEOF();
876efed6131SCaroline Tice }
877efed6131SCaroline Tice 
878efed6131SCaroline Tice void
87944d93782SGreg Clayton Debugger::ClearIOHandlers ()
8803d6086f6SCaroline Tice {
881b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
88244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
883d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8843d6086f6SCaroline Tice     {
88544d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8863d6086f6SCaroline Tice         if (reader_sp)
8874446487dSPavel Labath             PopIOHandler (reader_sp);
8883d6086f6SCaroline Tice     }
8893d6086f6SCaroline Tice }
8903d6086f6SCaroline Tice 
8913d6086f6SCaroline Tice void
8929aaab558SSiva Chandra Debugger::ExecuteIOHandlers()
893969ed3d1SCaroline Tice {
89444d93782SGreg Clayton     while (1)
895969ed3d1SCaroline Tice     {
89644d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
89730fdc8d8SChris Lattner         if (!reader_sp)
89830fdc8d8SChris Lattner             break;
89930fdc8d8SChris Lattner 
90044d93782SGreg Clayton         reader_sp->Run();
90144d93782SGreg Clayton 
90244d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
90344d93782SGreg Clayton         while (1)
90430fdc8d8SChris Lattner         {
90544d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
90644d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
9074446487dSPavel Labath                 PopIOHandler (top_reader_sp);
90830fdc8d8SChris Lattner             else
90930fdc8d8SChris Lattner                 break;
91030fdc8d8SChris Lattner         }
91130fdc8d8SChris Lattner     }
91244d93782SGreg Clayton     ClearIOHandlers();
91344d93782SGreg Clayton }
91430fdc8d8SChris Lattner 
91544d93782SGreg Clayton bool
91644d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
91744d93782SGreg Clayton {
91844d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
91944d93782SGreg Clayton }
92030fdc8d8SChris Lattner 
9214446487dSPavel Labath void
9224446487dSPavel Labath Debugger::PrintAsync (const char *s, size_t len, bool is_stdout)
9234446487dSPavel Labath {
9244446487dSPavel Labath     lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
9254446487dSPavel Labath     m_input_reader_stack.PrintAsync(stream.get(), s, len);
9264446487dSPavel Labath }
92744d93782SGreg Clayton 
92844d93782SGreg Clayton ConstString
92944d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
93044d93782SGreg Clayton {
93144d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
93230fdc8d8SChris Lattner }
93330fdc8d8SChris Lattner 
934a487aa4cSKate Stone const char *
935a487aa4cSKate Stone Debugger::GetIOHandlerCommandPrefix()
936a487aa4cSKate Stone {
937a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
938a487aa4cSKate Stone }
939a487aa4cSKate Stone 
940a487aa4cSKate Stone const char *
941a487aa4cSKate Stone Debugger::GetIOHandlerHelpPrologue()
942a487aa4cSKate Stone {
943a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
944a487aa4cSKate Stone }
945a487aa4cSKate Stone 
94630fdc8d8SChris Lattner void
94744d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
94844d93782SGreg Clayton {
94944d93782SGreg Clayton     PushIOHandler (reader_sp);
950577508dfSGreg Clayton 
951577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
952577508dfSGreg Clayton     while (top_reader_sp)
953577508dfSGreg Clayton     {
954577508dfSGreg Clayton         top_reader_sp->Run();
955577508dfSGreg Clayton 
956577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
957577508dfSGreg Clayton         {
958577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
959577508dfSGreg Clayton                 break;
960577508dfSGreg Clayton         }
961577508dfSGreg Clayton 
962577508dfSGreg Clayton         while (1)
963577508dfSGreg Clayton         {
964577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
965577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
9664446487dSPavel Labath                 PopIOHandler (top_reader_sp);
967577508dfSGreg Clayton             else
968577508dfSGreg Clayton                 break;
969577508dfSGreg Clayton         }
970577508dfSGreg Clayton     }
97144d93782SGreg Clayton }
97244d93782SGreg Clayton 
97344d93782SGreg Clayton void
97444d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
97544d93782SGreg Clayton {
97644d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
97744d93782SGreg Clayton     // This function is called when one ore more of the streams
97844d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
97944d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
98044d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
98144d93782SGreg Clayton 
98244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
98344d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
98444d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
98544d93782SGreg Clayton     if (!in)
98644d93782SGreg Clayton     {
98744d93782SGreg Clayton         if (top_reader_sp)
98844d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
98944d93782SGreg Clayton         else
99044d93782SGreg Clayton             in = GetInputFile();
99144d93782SGreg Clayton 
99244d93782SGreg Clayton         // If there is nothing, use stdin
99344d93782SGreg Clayton         if (!in)
99444d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
99544d93782SGreg Clayton     }
99644d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
99744d93782SGreg Clayton     if (!out)
99844d93782SGreg Clayton     {
99944d93782SGreg Clayton         if (top_reader_sp)
100044d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
100144d93782SGreg Clayton         else
100244d93782SGreg Clayton             out = GetOutputFile();
100344d93782SGreg Clayton 
100444d93782SGreg Clayton         // If there is nothing, use stdout
100544d93782SGreg Clayton         if (!out)
100644d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
100744d93782SGreg Clayton     }
100844d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
100944d93782SGreg Clayton     if (!err)
101044d93782SGreg Clayton     {
101144d93782SGreg Clayton         if (top_reader_sp)
101244d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
101344d93782SGreg Clayton         else
101444d93782SGreg Clayton             err = GetErrorFile();
101544d93782SGreg Clayton 
101644d93782SGreg Clayton         // If there is nothing, use stderr
101744d93782SGreg Clayton         if (!err)
101844d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
101944d93782SGreg Clayton 
102044d93782SGreg Clayton     }
102144d93782SGreg Clayton }
102244d93782SGreg Clayton 
102344d93782SGreg Clayton void
102444d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
102530fdc8d8SChris Lattner {
102630fdc8d8SChris Lattner     if (!reader_sp)
102730fdc8d8SChris Lattner         return;
1028b44880caSCaroline Tice 
10294446487dSPavel Labath     Mutex::Locker locker (m_input_reader_stack.GetMutex());
10304446487dSPavel Labath 
10314446487dSPavel Labath     // Get the current top input reader...
103244d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1033b44880caSCaroline Tice 
1034b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
10354446487dSPavel Labath     if (reader_sp == top_reader_sp)
10364446487dSPavel Labath         return;
10374446487dSPavel Labath 
103844d93782SGreg Clayton     // Push our new input reader
1039d5a0a01bSCaroline Tice     m_input_reader_stack.Push (reader_sp);
10404446487dSPavel Labath     reader_sp->Activate();
104144d93782SGreg Clayton 
104244d93782SGreg Clayton     // Interrupt the top input reader to it will exit its Run() function
104344d93782SGreg Clayton     // and let this new input reader take over
104444d93782SGreg Clayton     if (top_reader_sp)
10454446487dSPavel Labath     {
104644d93782SGreg Clayton         top_reader_sp->Deactivate();
10474446487dSPavel Labath         top_reader_sp->Cancel();
104830fdc8d8SChris Lattner     }
1049b4874f1aSGreg Clayton }
105030fdc8d8SChris Lattner 
105130fdc8d8SChris Lattner bool
105244d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
105330fdc8d8SChris Lattner {
10544446487dSPavel Labath     if (! pop_reader_sp)
10554446487dSPavel Labath         return false;
105630fdc8d8SChris Lattner 
105744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
105844d93782SGreg Clayton 
105930fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10606a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
10614446487dSPavel Labath     if (m_input_reader_stack.IsEmpty())
10624446487dSPavel Labath         return false;
10634446487dSPavel Labath 
106444d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
106530fdc8d8SChris Lattner 
10664446487dSPavel Labath     if (pop_reader_sp != reader_sp)
10674446487dSPavel Labath         return false;
10684446487dSPavel Labath 
106944d93782SGreg Clayton     reader_sp->Deactivate();
1070b4874f1aSGreg Clayton     reader_sp->Cancel();
1071d5a0a01bSCaroline Tice     m_input_reader_stack.Pop ();
107230fdc8d8SChris Lattner 
1073d5a0a01bSCaroline Tice     reader_sp = m_input_reader_stack.Top();
107430fdc8d8SChris Lattner     if (reader_sp)
107544d93782SGreg Clayton         reader_sp->Activate();
107644d93782SGreg Clayton 
107744d93782SGreg Clayton     return true;
107830fdc8d8SChris Lattner }
10796611103cSGreg Clayton 
10805b52f0c7SJim Ingham StreamSP
10815b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10825b52f0c7SJim Ingham {
10834446487dSPavel Labath     return StreamSP (new StreamAsynchronousIO (*this, true));
10845b52f0c7SJim Ingham }
10855b52f0c7SJim Ingham 
10865b52f0c7SJim Ingham StreamSP
10875b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10885b52f0c7SJim Ingham {
10894446487dSPavel Labath     return StreamSP (new StreamAsynchronousIO (*this, false));
10905b52f0c7SJim Ingham }
10915b52f0c7SJim Ingham 
1092c7bece56SGreg Clayton size_t
1093061858ceSEnrico Granata Debugger::GetNumDebuggers()
1094061858ceSEnrico Granata {
1095e6e2bb38SZachary Turner     if (lldb_initialized)
1096c15f55e2SGreg Clayton     {
1097061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1098061858ceSEnrico Granata         return GetDebuggerList().size();
1099061858ceSEnrico Granata     }
1100c15f55e2SGreg Clayton     return 0;
1101c15f55e2SGreg Clayton }
1102061858ceSEnrico Granata 
1103061858ceSEnrico Granata lldb::DebuggerSP
1104c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1105061858ceSEnrico Granata {
1106061858ceSEnrico Granata     DebuggerSP debugger_sp;
1107061858ceSEnrico Granata 
1108e6e2bb38SZachary Turner     if (lldb_initialized)
1109c15f55e2SGreg Clayton     {
1110061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1111061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1112061858ceSEnrico Granata 
1113061858ceSEnrico Granata         if (index < debugger_list.size())
1114061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1115c15f55e2SGreg Clayton     }
1116061858ceSEnrico Granata 
1117061858ceSEnrico Granata     return debugger_sp;
1118061858ceSEnrico Granata }
1119061858ceSEnrico Granata 
1120ebc1bb27SCaroline Tice DebuggerSP
1121ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1122ebc1bb27SCaroline Tice {
11234d122c40SGreg Clayton     DebuggerSP debugger_sp;
1124ebc1bb27SCaroline Tice 
1125e6e2bb38SZachary Turner     if (lldb_initialized)
1126c15f55e2SGreg Clayton     {
1127ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1128ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1129ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1130ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1131ebc1bb27SCaroline Tice         {
1132ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1133ebc1bb27SCaroline Tice             {
1134ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1135ebc1bb27SCaroline Tice                 break;
1136ebc1bb27SCaroline Tice             }
1137ebc1bb27SCaroline Tice         }
1138c15f55e2SGreg Clayton     }
1139ebc1bb27SCaroline Tice     return debugger_sp;
1140ebc1bb27SCaroline Tice }
11413df9a8dfSCaroline Tice 
11422643b905SSaleem Abdulrasool #if 0
11431b654882SGreg Clayton static void
1144b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11451b654882SGreg Clayton {
11461b654882SGreg Clayton     if (frame == NULL)
11471b654882SGreg Clayton         return;
11481b654882SGreg Clayton 
11491b654882SGreg Clayton     StreamString s;
11501b654882SGreg Clayton     const char *prompt_format =
11511b654882SGreg Clayton     "{addr = '${addr}'\n}"
1152aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1153aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
11541b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11551b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11561b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11571b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11581b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11591b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11601b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11611b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11621b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11631b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11641b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11651b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11661b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11671b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11681b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11691b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11701b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11711b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11721b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11731b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11741b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11751b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11761b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11771b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11781b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11791b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11801b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1181aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1182aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
11831b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1184aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1185ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11861b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1187aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
11881b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11891b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11901b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11911b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11921b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11931b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11941b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11951b654882SGreg Clayton ;
11961b654882SGreg Clayton 
11971b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11981b654882SGreg Clayton     ExecutionContext exe_ctx;
11990603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1200c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
12011b654882SGreg Clayton     {
12021b654882SGreg Clayton         printf("%s\n", s.GetData());
12031b654882SGreg Clayton     }
12041b654882SGreg Clayton     else
12051b654882SGreg Clayton     {
12061b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
12071b654882SGreg Clayton     }
12081b654882SGreg Clayton }
12092643b905SSaleem Abdulrasool #endif
12101b654882SGreg Clayton 
1211c3ce7f27SMichael Sartain bool
1212554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
1213aff1b357SJason Molenda                                      const SymbolContext *sc,
1214aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
1215aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
1216aff1b357SJason Molenda                                      const Address *addr,
1217aff1b357SJason Molenda                                      Stream &s)
1218aff1b357SJason Molenda {
1219554f68d3SGreg Clayton     FormatEntity::Entry format_entry;
1220554f68d3SGreg Clayton 
1221554f68d3SGreg Clayton     if (format == NULL)
1222aff1b357SJason Molenda     {
1223554f68d3SGreg Clayton         if (exe_ctx != NULL && exe_ctx->HasTargetScope())
1224aff1b357SJason Molenda             format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1225554f68d3SGreg Clayton         if (format == NULL)
1226554f68d3SGreg Clayton         {
1227554f68d3SGreg Clayton             FormatEntity::Parse("${addr}: ", format_entry);
1228554f68d3SGreg Clayton             format = &format_entry;
1229554f68d3SGreg Clayton         }
1230aff1b357SJason Molenda     }
1231aff1b357SJason Molenda     bool function_changed = false;
1232aff1b357SJason Molenda     bool initial_function = false;
1233aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
1234aff1b357SJason Molenda     {
1235aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
1236aff1b357SJason Molenda         {
1237aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
1238aff1b357SJason Molenda             {
1239aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
1240aff1b357SJason Molenda                 {
1241aff1b357SJason Molenda                     function_changed = true;
1242aff1b357SJason Molenda                 }
1243aff1b357SJason Molenda             }
1244aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
1245aff1b357SJason Molenda             {
1246aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
1247aff1b357SJason Molenda                 {
1248aff1b357SJason Molenda                     function_changed = true;
1249aff1b357SJason Molenda                 }
1250aff1b357SJason Molenda             }
1251aff1b357SJason Molenda         }
1252aff1b357SJason Molenda     }
1253aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
1254aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
1255aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
1256aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
1257aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
1258aff1b357SJason Molenda     {
1259aff1b357SJason Molenda         initial_function = true;
1260aff1b357SJason Molenda     }
1261554f68d3SGreg Clayton     return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function);
1262aff1b357SJason Molenda }
1263aff1b357SJason Molenda 
1264aff1b357SJason Molenda 
1265228063cdSJim Ingham void
1266228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
1267228063cdSJim Ingham {
12684f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
12694f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
12704f02b22dSJim Ingham     // callback.
1271228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
1272228063cdSJim Ingham }
1273228063cdSJim Ingham 
1274228063cdSJim Ingham bool
1275228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
1276228063cdSJim Ingham {
1277228063cdSJim Ingham     StreamSP log_stream_sp;
12789a028519SSean Callanan     if (m_log_callback_stream_sp)
1279228063cdSJim Ingham     {
1280228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
1281228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
1282228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1283228063cdSJim Ingham     }
1284228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
1285228063cdSJim Ingham     {
128644d93782SGreg Clayton         log_stream_sp = GetOutputFile();
1287228063cdSJim Ingham     }
1288228063cdSJim Ingham     else
1289228063cdSJim Ingham     {
1290228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
1291c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
1292c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
1293c1b2ccfdSGreg Clayton         if (!log_stream_sp)
1294228063cdSJim Ingham         {
12958ac06996SPavel Labath             uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate
12968ac06996SPavel Labath                                 | File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
12978ac06996SPavel Labath             if (! (log_options & LLDB_LOG_OPTION_APPEND))
12988ac06996SPavel Labath                 options |= File::eOpenOptionTruncate;
12998ac06996SPavel Labath 
13008ac06996SPavel Labath             log_stream_sp.reset (new StreamFile (log_file, options));
1301228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
1302228063cdSJim Ingham         }
1303228063cdSJim Ingham     }
1304228063cdSJim Ingham     assert (log_stream_sp.get());
1305228063cdSJim Ingham 
1306228063cdSJim Ingham     if (log_options == 0)
1307228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
1308228063cdSJim Ingham 
13099c9ecce0STamas Berghammer     return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, error_stream);
1310228063cdSJim Ingham }
1311228063cdSJim Ingham 
13129585fbfcSGreg Clayton SourceManager &
13139585fbfcSGreg Clayton Debugger::GetSourceManager ()
13149585fbfcSGreg Clayton {
13159585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
13169585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
13179585fbfcSGreg Clayton     return *m_source_manager_ap;
13189585fbfcSGreg Clayton }
13199585fbfcSGreg Clayton 
13209585fbfcSGreg Clayton 
132144d93782SGreg Clayton 
132244d93782SGreg Clayton // This function handles events that were broadcast by the process.
132344d93782SGreg Clayton void
132444d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
132544d93782SGreg Clayton {
132644d93782SGreg Clayton     using namespace lldb;
132744d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
132844d93782SGreg Clayton 
132944d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
133044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
133144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
133244d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
133344d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
133444d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
133544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
133644d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
133744d93782SGreg Clayton //    {
133844d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
133944d93782SGreg Clayton //    }
134044d93782SGreg Clayton //
134144d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
134244d93782SGreg Clayton     {
134344d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
134444d93782SGreg Clayton         if (num_new_locations > 0)
134544d93782SGreg Clayton         {
134644d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
13474446487dSPavel Labath             StreamSP output_sp (GetAsyncOutputStream());
134844d93782SGreg Clayton             if (output_sp)
134944d93782SGreg Clayton             {
135044d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
135144d93782SGreg Clayton                                   num_new_locations,
135244d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
135344d93782SGreg Clayton                                   breakpoint->GetID());
13544446487dSPavel Labath                 output_sp->Flush();
135544d93782SGreg Clayton             }
135644d93782SGreg Clayton         }
135744d93782SGreg Clayton     }
135844d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
135944d93782SGreg Clayton //    {
136044d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
136144d93782SGreg Clayton //    }
136244d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
136344d93782SGreg Clayton //    {
136444d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
136544d93782SGreg Clayton //    }
136644d93782SGreg Clayton }
136744d93782SGreg Clayton 
136844d93782SGreg Clayton size_t
136944d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
137044d93782SGreg Clayton {
137144d93782SGreg Clayton     size_t total_bytes = 0;
137244d93782SGreg Clayton     if (stream == NULL)
137344d93782SGreg Clayton         stream = GetOutputFile().get();
137444d93782SGreg Clayton 
137544d93782SGreg Clayton     if (stream)
137644d93782SGreg Clayton     {
137744d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
137844d93782SGreg Clayton         if (process == NULL)
137944d93782SGreg Clayton         {
138044d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
138144d93782SGreg Clayton             if (target_sp)
138244d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
138344d93782SGreg Clayton         }
138444d93782SGreg Clayton         if (process)
138544d93782SGreg Clayton         {
138644d93782SGreg Clayton             Error error;
138744d93782SGreg Clayton             size_t len;
138844d93782SGreg Clayton             char stdio_buffer[1024];
138944d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
139044d93782SGreg Clayton             {
139144d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
139244d93782SGreg Clayton                 total_bytes += len;
139344d93782SGreg Clayton             }
139444d93782SGreg Clayton         }
139544d93782SGreg Clayton         stream->Flush();
139644d93782SGreg Clayton     }
139744d93782SGreg Clayton     return total_bytes;
139844d93782SGreg Clayton }
139944d93782SGreg Clayton 
140044d93782SGreg Clayton size_t
140144d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
140244d93782SGreg Clayton {
140344d93782SGreg Clayton     size_t total_bytes = 0;
140444d93782SGreg Clayton     if (stream == NULL)
140544d93782SGreg Clayton         stream = GetOutputFile().get();
140644d93782SGreg Clayton 
140744d93782SGreg Clayton     if (stream)
140844d93782SGreg Clayton     {
140944d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
141044d93782SGreg Clayton         if (process == NULL)
141144d93782SGreg Clayton         {
141244d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
141344d93782SGreg Clayton             if (target_sp)
141444d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
141544d93782SGreg Clayton         }
141644d93782SGreg Clayton         if (process)
141744d93782SGreg Clayton         {
141844d93782SGreg Clayton             Error error;
141944d93782SGreg Clayton             size_t len;
142044d93782SGreg Clayton             char stdio_buffer[1024];
142144d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
142244d93782SGreg Clayton             {
142344d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
142444d93782SGreg Clayton                 total_bytes += len;
142544d93782SGreg Clayton             }
142644d93782SGreg Clayton         }
142744d93782SGreg Clayton         stream->Flush();
142844d93782SGreg Clayton     }
142944d93782SGreg Clayton     return total_bytes;
143044d93782SGreg Clayton }
143144d93782SGreg Clayton 
1432dc6224e0SGreg Clayton 
143344d93782SGreg Clayton // This function handles events that were broadcast by the process.
143444d93782SGreg Clayton void
143544d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
143644d93782SGreg Clayton {
143744d93782SGreg Clayton     using namespace lldb;
143844d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
143944d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
144044d93782SGreg Clayton 
14414446487dSPavel Labath     StreamSP output_stream_sp = GetAsyncOutputStream();
14424446487dSPavel Labath     StreamSP error_stream_sp = GetAsyncErrorStream();
144344d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
144444d93782SGreg Clayton 
1445b4874f1aSGreg Clayton     if (!gui_enabled)
1446b4874f1aSGreg Clayton     {
1447b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
144844d93782SGreg Clayton         assert (process_sp);
144944d93782SGreg Clayton 
14504446487dSPavel Labath         bool state_is_stopped = false;
14514446487dSPavel Labath         const bool got_state_changed = (event_type & Process::eBroadcastBitStateChanged) != 0;
14524446487dSPavel Labath         const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
14534446487dSPavel Labath         const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
14544446487dSPavel Labath         if (got_state_changed)
145544d93782SGreg Clayton         {
14564446487dSPavel Labath             StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
14574446487dSPavel Labath             state_is_stopped = StateIsStoppedState(event_state, false);
145844d93782SGreg Clayton         }
1459b4874f1aSGreg Clayton 
14604446487dSPavel Labath         // Display running state changes first before any STDIO
14614446487dSPavel Labath         if (got_state_changed && !state_is_stopped)
146244d93782SGreg Clayton         {
14634446487dSPavel Labath             Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
146444d93782SGreg Clayton         }
1465b4874f1aSGreg Clayton 
14664446487dSPavel Labath         // Now display and STDOUT
14674446487dSPavel Labath         if (got_stdout || got_state_changed)
146844d93782SGreg Clayton         {
14694446487dSPavel Labath             GetProcessSTDOUT (process_sp.get(), output_stream_sp.get());
147044d93782SGreg Clayton         }
1471b4874f1aSGreg Clayton 
14724446487dSPavel Labath         // Now display and STDERR
14734446487dSPavel Labath         if (got_stderr || got_state_changed)
1474b4874f1aSGreg Clayton         {
14754446487dSPavel Labath             GetProcessSTDERR (process_sp.get(), error_stream_sp.get());
1476b4874f1aSGreg Clayton         }
1477b4874f1aSGreg Clayton 
14784446487dSPavel Labath         // Now display any stopped state changes after any STDIO
14794446487dSPavel Labath         if (got_state_changed && state_is_stopped)
1480b4874f1aSGreg Clayton         {
14814446487dSPavel Labath             Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
148244d93782SGreg Clayton         }
148344d93782SGreg Clayton 
14844446487dSPavel Labath         output_stream_sp->Flush();
14854446487dSPavel Labath         error_stream_sp->Flush();
148644d93782SGreg Clayton 
1487b4874f1aSGreg Clayton         if (pop_process_io_handler)
1488b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
1489b4874f1aSGreg Clayton     }
1490b4874f1aSGreg Clayton }
1491b4874f1aSGreg Clayton 
149244d93782SGreg Clayton void
149344d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
149444d93782SGreg Clayton {
149544d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
149644d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
149744d93782SGreg Clayton     using namespace lldb;
149844d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
149944d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
150044d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
150144d93782SGreg Clayton     {
150244d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
150344d93782SGreg Clayton         if (thread_sp)
150444d93782SGreg Clayton         {
15054446487dSPavel Labath             thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1);
150644d93782SGreg Clayton         }
150744d93782SGreg Clayton     }
150844d93782SGreg Clayton }
150944d93782SGreg Clayton 
151044d93782SGreg Clayton bool
151144d93782SGreg Clayton Debugger::IsForwardingEvents ()
151244d93782SGreg Clayton {
151344d93782SGreg Clayton     return (bool)m_forward_listener_sp;
151444d93782SGreg Clayton }
151544d93782SGreg Clayton 
151644d93782SGreg Clayton void
151744d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
151844d93782SGreg Clayton {
151944d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
152044d93782SGreg Clayton }
152144d93782SGreg Clayton 
152244d93782SGreg Clayton void
152344d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
152444d93782SGreg Clayton {
152544d93782SGreg Clayton     m_forward_listener_sp.reset();
152644d93782SGreg Clayton }
152744d93782SGreg Clayton 
152844d93782SGreg Clayton 
152944d93782SGreg Clayton void
153044d93782SGreg Clayton Debugger::DefaultEventHandler()
153144d93782SGreg Clayton {
153244d93782SGreg Clayton     Listener& listener(GetListener());
153344d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
153444d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
153544d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
153644d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
153744d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
153844d93782SGreg Clayton 
153944d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
154044d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
154144d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
154244d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
154344d93782SGreg Clayton 
154444d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
154544d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
154644d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
154744d93782SGreg Clayton 
154844d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
154944d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
155044d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
155144d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
155244d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
155344d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
155444d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
155544d93782SGreg Clayton 
1556afa91e33SGreg Clayton     // Let the thread that spawned us know that we have started up and
1557afa91e33SGreg Clayton     // that we are now listening to all required events so no events get missed
1558afa91e33SGreg Clayton     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
1559afa91e33SGreg Clayton 
156044d93782SGreg Clayton     bool done = false;
156144d93782SGreg Clayton     while (!done)
156244d93782SGreg Clayton     {
156344d93782SGreg Clayton         EventSP event_sp;
156444d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
156544d93782SGreg Clayton         {
156644d93782SGreg Clayton             if (event_sp)
156744d93782SGreg Clayton             {
156844d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
156944d93782SGreg Clayton                 if (broadcaster)
157044d93782SGreg Clayton                 {
157144d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
157244d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
157344d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
157444d93782SGreg Clayton                     {
157544d93782SGreg Clayton                         HandleProcessEvent (event_sp);
157644d93782SGreg Clayton                     }
157744d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
157844d93782SGreg Clayton                     {
157944d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
158044d93782SGreg Clayton                         {
158144d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
158244d93782SGreg Clayton                         }
158344d93782SGreg Clayton                     }
158444d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
158544d93782SGreg Clayton                     {
158644d93782SGreg Clayton                         HandleThreadEvent (event_sp);
158744d93782SGreg Clayton                     }
158844d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
158944d93782SGreg Clayton                     {
159044d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
159144d93782SGreg Clayton                         {
159244d93782SGreg Clayton                             done = true;
159344d93782SGreg Clayton                         }
159444d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
159544d93782SGreg Clayton                         {
159644d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
159744d93782SGreg Clayton                             if (data && data[0])
159844d93782SGreg Clayton                             {
15994446487dSPavel Labath                                 StreamSP error_sp (GetAsyncErrorStream());
160044d93782SGreg Clayton                                 if (error_sp)
160144d93782SGreg Clayton                                 {
160244d93782SGreg Clayton                                     error_sp->PutCString(data);
160344d93782SGreg Clayton                                     error_sp->Flush();
160444d93782SGreg Clayton                                 }
160544d93782SGreg Clayton                             }
160644d93782SGreg Clayton                         }
160744d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
160844d93782SGreg Clayton                         {
160944d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
161044d93782SGreg Clayton                             if (data && data[0])
161144d93782SGreg Clayton                             {
16124446487dSPavel Labath                                 StreamSP output_sp (GetAsyncOutputStream());
161344d93782SGreg Clayton                                 if (output_sp)
161444d93782SGreg Clayton                                 {
161544d93782SGreg Clayton                                     output_sp->PutCString(data);
161644d93782SGreg Clayton                                     output_sp->Flush();
161744d93782SGreg Clayton                                 }
161844d93782SGreg Clayton                             }
161944d93782SGreg Clayton                         }
162044d93782SGreg Clayton                     }
162144d93782SGreg Clayton                 }
162244d93782SGreg Clayton 
162344d93782SGreg Clayton                 if (m_forward_listener_sp)
162444d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
162544d93782SGreg Clayton             }
162644d93782SGreg Clayton         }
162744d93782SGreg Clayton     }
162844d93782SGreg Clayton }
162944d93782SGreg Clayton 
163044d93782SGreg Clayton lldb::thread_result_t
163144d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
163244d93782SGreg Clayton {
163344d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
163444d93782SGreg Clayton     return NULL;
163544d93782SGreg Clayton }
163644d93782SGreg Clayton 
163744d93782SGreg Clayton bool
163844d93782SGreg Clayton Debugger::StartEventHandlerThread()
163944d93782SGreg Clayton {
1640acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
1641807b6b32SGreg Clayton     {
1642afa91e33SGreg Clayton         // We must synchronize with the DefaultEventHandler() thread to ensure
1643afa91e33SGreg Clayton         // it is up and running and listening to events before we return from
1644afa91e33SGreg Clayton         // this function. We do this by listening to events for the
1645afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
1646afa91e33SGreg Clayton         Listener listener("lldb.debugger.event-handler");
1647afa91e33SGreg Clayton         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
1648afa91e33SGreg Clayton 
16497c2896a2SZachary Turner         // Use larger 8MB stack for this thread
1650afa91e33SGreg Clayton         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
1651afa91e33SGreg Clayton                                                               this,
1652afa91e33SGreg Clayton                                                               NULL,
16537c2896a2SZachary Turner                                                               g_debugger_event_thread_stack_bytes);
1654afa91e33SGreg Clayton 
1655afa91e33SGreg Clayton         // Make sure DefaultEventHandler() is running and listening to events before we return
1656afa91e33SGreg Clayton         // from this function. We are only listening for events of type
1657afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
1658afa91e33SGreg Clayton         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
1659afa91e33SGreg Clayton         lldb::EventSP event_sp;
1660afa91e33SGreg Clayton         listener.WaitForEvent(NULL, event_sp);
1661807b6b32SGreg Clayton     }
1662acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
166344d93782SGreg Clayton }
166444d93782SGreg Clayton 
166544d93782SGreg Clayton void
166644d93782SGreg Clayton Debugger::StopEventHandlerThread()
166744d93782SGreg Clayton {
1668acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
166944d93782SGreg Clayton     {
167044d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
167139de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
167244d93782SGreg Clayton     }
167344d93782SGreg Clayton }
167444d93782SGreg Clayton 
167544d93782SGreg Clayton 
167644d93782SGreg Clayton lldb::thread_result_t
167744d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
167844d93782SGreg Clayton {
167944d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
16809aaab558SSiva Chandra     debugger->ExecuteIOHandlers();
168144d93782SGreg Clayton     debugger->StopEventHandlerThread();
168244d93782SGreg Clayton     return NULL;
168344d93782SGreg Clayton }
168444d93782SGreg Clayton 
168544d93782SGreg Clayton bool
168644d93782SGreg Clayton Debugger::StartIOHandlerThread()
168744d93782SGreg Clayton {
1688acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
1689807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
1690807b6b32SGreg Clayton                                                             IOHandlerThread,
1691807b6b32SGreg Clayton                                                             this,
1692807b6b32SGreg Clayton                                                             NULL,
1693807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
1694acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
169544d93782SGreg Clayton }
169644d93782SGreg Clayton 
169744d93782SGreg Clayton void
169844d93782SGreg Clayton Debugger::StopIOHandlerThread()
169944d93782SGreg Clayton {
1700acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
170144d93782SGreg Clayton     {
170244d93782SGreg Clayton         if (m_input_file_sp)
170344d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
170439de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
170544d93782SGreg Clayton     }
170644d93782SGreg Clayton }
170744d93782SGreg Clayton 
1708893c932aSJim Ingham Target *
1709893c932aSJim Ingham Debugger::GetDummyTarget()
1710893c932aSJim Ingham {
1711893c932aSJim Ingham     return m_target_list.GetDummyTarget (*this).get();
1712893c932aSJim Ingham }
1713893c932aSJim Ingham 
1714893c932aSJim Ingham Target *
171533df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
1716893c932aSJim Ingham {
171733df7cd3SJim Ingham     Target *target = nullptr;
171833df7cd3SJim Ingham     if (!prefer_dummy)
171933df7cd3SJim Ingham     {
172033df7cd3SJim Ingham         target = m_target_list.GetSelectedTarget().get();
172133df7cd3SJim Ingham         if (target)
172233df7cd3SJim Ingham             return target;
172333df7cd3SJim Ingham     }
1724893c932aSJim Ingham 
1725893c932aSJim Ingham     return GetDummyTarget();
1726893c932aSJim Ingham }
172744d93782SGreg Clayton 
1728