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 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
124a33d318SGreg Clayton #include "lldb/Core/Debugger.h"
134a33d318SGreg Clayton 
144a33d318SGreg Clayton #include <map>
154a33d318SGreg Clayton 
164becb37eSEnrico Granata #include "clang/AST/DeclCXX.h"
174becb37eSEnrico Granata #include "clang/AST/Type.h"
18705b1809SJason Molenda #include "llvm/ADT/StringRef.h"
194becb37eSEnrico Granata 
2030fdc8d8SChris Lattner #include "lldb/lldb-private.h"
21554f68d3SGreg Clayton #include "lldb/Core/FormatEntity.h"
221f746071SGreg Clayton #include "lldb/Core/Module.h"
23e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
247349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2530fdc8d8SChris Lattner #include "lldb/Core/State.h"
265b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
27228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
2844d93782SGreg Clayton #include "lldb/Core/StreamFile.h"
291b654882SGreg Clayton #include "lldb/Core/StreamString.h"
30705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
3130fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
324becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
336d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
355548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
36894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h"
3793a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h"
3842ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h"
39a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
4039de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h"
416611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
42633a29cfSZachary Turner #include "lldb/Interpreter/OptionValueProperties.h"
4367cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4467cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
451f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
461f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
471f746071SGreg Clayton #include "lldb/Symbol/Function.h"
481f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
496d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
50aff1b357SJason Molenda #include "lldb/Target/CPPLanguageRuntime.h"
51aff1b357SJason Molenda #include "lldb/Target/ObjCLanguageRuntime.h"
5230fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
5330fdc8d8SChris Lattner #include "lldb/Target/Process.h"
541b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
555fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h"
561b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5784a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5830fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
595a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
6030fdc8d8SChris Lattner 
6158a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h"
6258a559c0SZachary Turner 
6330fdc8d8SChris Lattner using namespace lldb;
6430fdc8d8SChris Lattner using namespace lldb_private;
6530fdc8d8SChris Lattner 
6630fdc8d8SChris Lattner 
671b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
68ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
697c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
70ebc1bb27SCaroline Tice 
711b654882SGreg Clayton #pragma mark Static Functions
721b654882SGreg Clayton 
731b654882SGreg Clayton static Mutex &
741b654882SGreg Clayton GetDebuggerListMutex ()
751b654882SGreg Clayton {
761b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
771b654882SGreg Clayton     return g_mutex;
781b654882SGreg Clayton }
791b654882SGreg Clayton 
801b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
811b654882SGreg Clayton 
821b654882SGreg Clayton static DebuggerList &
831b654882SGreg Clayton GetDebuggerList()
841b654882SGreg Clayton {
851b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
866a7f3338SBruce Mitchener     // global init constructors
871b654882SGreg Clayton     static DebuggerList g_list;
881b654882SGreg Clayton     return g_list;
891b654882SGreg Clayton }
90e372b98dSGreg Clayton 
91e372b98dSGreg Clayton OptionEnumValueElement
9267cc0636SGreg Clayton g_show_disassembly_enum_values[] =
93e372b98dSGreg Clayton {
9467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
9567cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
9667cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
97e372b98dSGreg Clayton     { 0, NULL, NULL }
98e372b98dSGreg Clayton };
99e372b98dSGreg Clayton 
10067cc0636SGreg Clayton OptionEnumValueElement
10167cc0636SGreg Clayton g_language_enumerators[] =
10267cc0636SGreg Clayton {
10367cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
10467cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
10567cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
106a12993c9SGreg Clayton     { 0, NULL, NULL }
10767cc0636SGreg Clayton };
108e372b98dSGreg Clayton 
10967cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
11067cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
11167cc0636SGreg Clayton 
1120769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
11367cc0636SGreg Clayton     "{, ${frame.pc}}"\
11467cc0636SGreg Clayton     MODULE_WITH_FUNC\
11567cc0636SGreg Clayton     FILE_AND_LINE\
1160769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
1170769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
118705b1809SJason Molenda     "{, activity = '${thread.info.activity.name}'}" \
119705b1809SJason Molenda     "{, ${thread.info.trace_messages} messages}" \
12067cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
12167cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
12230fadafeSJim Ingham     "{\\nCompleted expression: ${thread.completed-expression}}"\
12367cc0636SGreg Clayton     "\\n"
12467cc0636SGreg Clayton 
12567cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
12667cc0636SGreg Clayton     MODULE_WITH_FUNC\
12767cc0636SGreg Clayton     FILE_AND_LINE\
12867cc0636SGreg Clayton     "\\n"
12967cc0636SGreg Clayton 
130c980fa92SJason Molenda // Three parts to this disassembly format specification:
131c980fa92SJason Molenda //   1. If this is a new function/symbol (no previous symbol/function), print
132c980fa92SJason Molenda //      dylib`funcname:\n
133c980fa92SJason Molenda //   2. If this is a symbol context change (different from previous symbol/function), print
134c980fa92SJason Molenda //      dylib`funcname:\n
135c980fa92SJason Molenda //   3. print
136c980fa92SJason Molenda //      address <+offset>:
137c980fa92SJason 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}>}: "
138c980fa92SJason Molenda 
139c980fa92SJason Molenda // gdb's disassembly format can be emulated with
140c980fa92SJason Molenda // ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
141c980fa92SJason Molenda 
142c980fa92SJason Molenda // lldb's original format for disassembly would look like this format string -
143c980fa92SJason 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}}:
144c980fa92SJason Molenda 
14567cc0636SGreg Clayton 
146754a9369SGreg Clayton static PropertyDefinition
147754a9369SGreg Clayton g_properties[] =
14867cc0636SGreg Clayton {
14967cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean     , true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
150554f68d3SGreg Clayton {   "disassembly-format",       OptionValue::eTypeFormatEntity, true, 0    , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
151554f68d3SGreg 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." },
15267cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean     , true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1534c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString      , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
15467cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum        , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
15567cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64      , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
15667cc0636SGreg 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." },
15767cc0636SGreg 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." },
15867cc0636SGreg 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." },
15967cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64      , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
160554f68d3SGreg Clayton {   "thread-format",            OptionValue::eTypeFormatEntity, true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
16167cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean     , true, false, NULL, NULL, "Whether to use an external editor or not." },
162c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean     , true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
16390a8db30SEnrico 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)." },
164ebdc1ac0SEnrico Granata {   "escape-non-printables",    OptionValue::eTypeBoolean     , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
16567cc0636SGreg Clayton {   NULL,                       OptionValue::eTypeInvalid     , true, 0    , NULL, NULL, NULL }
16667cc0636SGreg Clayton };
16767cc0636SGreg Clayton 
16867cc0636SGreg Clayton enum
16967cc0636SGreg Clayton {
17067cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
171aff1b357SJason Molenda     ePropertyDisassemblyFormat,
17267cc0636SGreg Clayton     ePropertyFrameFormat,
17367cc0636SGreg Clayton     ePropertyNotiftVoid,
17467cc0636SGreg Clayton     ePropertyPrompt,
17567cc0636SGreg Clayton     ePropertyScriptLanguage,
17667cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
17767cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
17867cc0636SGreg Clayton     ePropertyStopLineCountAfter,
17967cc0636SGreg Clayton     ePropertyStopLineCountBefore,
18067cc0636SGreg Clayton     ePropertyTerminalWidth,
18167cc0636SGreg Clayton     ePropertyThreadFormat,
182c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
183c3ce7f27SMichael Sartain     ePropertyUseColor,
184ebdc1ac0SEnrico Granata     ePropertyAutoOneLineSummaries,
185ebdc1ac0SEnrico Granata     ePropertyEscapeNonPrintables
18667cc0636SGreg Clayton };
18767cc0636SGreg Clayton 
1885fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1894c05410fSGreg Clayton 
1904c05410fSGreg Clayton Error
1914c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1924c05410fSGreg Clayton                             VarSetOperationType op,
1934c05410fSGreg Clayton                             const char *property_path,
1944c05410fSGreg Clayton                             const char *value)
1954c05410fSGreg Clayton {
19684a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
197ebdc1ac0SEnrico Granata     bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
19884a53dfbSEnrico Granata     TargetSP target_sp;
199397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
20084a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
20184a53dfbSEnrico Granata     {
20284a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
20384a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
20484a53dfbSEnrico Granata     }
2054c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
2064c05410fSGreg Clayton     if (error.Success())
2074c05410fSGreg Clayton     {
20884a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
2094c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
2104c05410fSGreg Clayton         {
2114c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
212c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
213c3ce7f27SMichael Sartain             if (str.length())
214c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
21544d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
2164c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
2174c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
2184c05410fSGreg Clayton         }
219c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
220c3ce7f27SMichael Sartain         {
221c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
222c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
223c3ce7f27SMichael Sartain         }
224397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
22584a53dfbSEnrico Granata         {
226397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
22784a53dfbSEnrico Granata             {
22884a53dfbSEnrico Granata                 std::list<Error> errors;
2299730339bSEnrico Granata                 StreamString feedback_stream;
2309730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
23184a53dfbSEnrico Granata                 {
23244d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
23344d93782SGreg Clayton                     if (stream_sp)
23444d93782SGreg Clayton                     {
23584a53dfbSEnrico Granata                         for (auto error : errors)
23684a53dfbSEnrico Granata                         {
23744d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
23884a53dfbSEnrico Granata                         }
2399730339bSEnrico Granata                         if (feedback_stream.GetSize())
24044d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
24144d93782SGreg Clayton                     }
24284a53dfbSEnrico Granata                 }
24384a53dfbSEnrico Granata             }
24484a53dfbSEnrico Granata         }
245ebdc1ac0SEnrico Granata         else if (is_escape_non_printables)
246ebdc1ac0SEnrico Granata         {
247ebdc1ac0SEnrico Granata             DataVisualization::ForceUpdate();
248ebdc1ac0SEnrico Granata         }
2494c05410fSGreg Clayton     }
2504c05410fSGreg Clayton     return error;
2514c05410fSGreg Clayton }
2524c05410fSGreg Clayton 
25367cc0636SGreg Clayton bool
25467cc0636SGreg Clayton Debugger::GetAutoConfirm () const
25567cc0636SGreg Clayton {
25667cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
257754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
25867cc0636SGreg Clayton }
25967cc0636SGreg Clayton 
260554f68d3SGreg Clayton const FormatEntity::Entry *
261aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const
262aff1b357SJason Molenda {
263aff1b357SJason Molenda     const uint32_t idx = ePropertyDisassemblyFormat;
264554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
265aff1b357SJason Molenda }
266aff1b357SJason Molenda 
267554f68d3SGreg Clayton const FormatEntity::Entry *
26867cc0636SGreg Clayton Debugger::GetFrameFormat() const
26967cc0636SGreg Clayton {
27067cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
271554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
27267cc0636SGreg Clayton }
27367cc0636SGreg Clayton 
27467cc0636SGreg Clayton bool
27567cc0636SGreg Clayton Debugger::GetNotifyVoid () const
27667cc0636SGreg Clayton {
27767cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
278754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
27967cc0636SGreg Clayton }
28067cc0636SGreg Clayton 
28167cc0636SGreg Clayton const char *
28267cc0636SGreg Clayton Debugger::GetPrompt() const
28367cc0636SGreg Clayton {
28467cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
285754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
28667cc0636SGreg Clayton }
28767cc0636SGreg Clayton 
28867cc0636SGreg Clayton void
28967cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
29067cc0636SGreg Clayton {
29167cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
29267cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
29367cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
294c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
295c3ce7f27SMichael Sartain     if (str.length())
296c3ce7f27SMichael Sartain         new_prompt = str.c_str();
29744d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
29867cc0636SGreg Clayton }
29967cc0636SGreg Clayton 
300554f68d3SGreg Clayton const FormatEntity::Entry *
30167cc0636SGreg Clayton Debugger::GetThreadFormat() const
30267cc0636SGreg Clayton {
30367cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
304554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
30567cc0636SGreg Clayton }
30667cc0636SGreg Clayton 
30767cc0636SGreg Clayton lldb::ScriptLanguage
30867cc0636SGreg Clayton Debugger::GetScriptLanguage() const
30967cc0636SGreg Clayton {
31067cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
311754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
31267cc0636SGreg Clayton }
31367cc0636SGreg Clayton 
31467cc0636SGreg Clayton bool
31567cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
31667cc0636SGreg Clayton {
31767cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
31867cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
31967cc0636SGreg Clayton }
32067cc0636SGreg Clayton 
32167cc0636SGreg Clayton uint32_t
32267cc0636SGreg Clayton Debugger::GetTerminalWidth () const
32367cc0636SGreg Clayton {
32467cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
325754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
32667cc0636SGreg Clayton }
32767cc0636SGreg Clayton 
32867cc0636SGreg Clayton bool
32967cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
33067cc0636SGreg Clayton {
33167cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
33267cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
33367cc0636SGreg Clayton }
33467cc0636SGreg Clayton 
33567cc0636SGreg Clayton bool
33667cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
33767cc0636SGreg Clayton {
33867cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
339754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
34067cc0636SGreg Clayton }
34167cc0636SGreg Clayton 
34267cc0636SGreg Clayton bool
34367cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
34467cc0636SGreg Clayton {
34567cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
34667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
34767cc0636SGreg Clayton }
34867cc0636SGreg Clayton 
349c3ce7f27SMichael Sartain bool
350c3ce7f27SMichael Sartain Debugger::GetUseColor () const
351c3ce7f27SMichael Sartain {
352c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
353c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
354c3ce7f27SMichael Sartain }
355c3ce7f27SMichael Sartain 
356c3ce7f27SMichael Sartain bool
357c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
358c3ce7f27SMichael Sartain {
359c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
360c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
361c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
362c3ce7f27SMichael Sartain     return ret;
363c3ce7f27SMichael Sartain }
364c3ce7f27SMichael Sartain 
36567cc0636SGreg Clayton uint32_t
36667cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
36767cc0636SGreg Clayton {
36867cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
369754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
37067cc0636SGreg Clayton }
37167cc0636SGreg Clayton 
37267cc0636SGreg Clayton Debugger::StopDisassemblyType
37367cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
37467cc0636SGreg Clayton {
37567cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
376754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
37767cc0636SGreg Clayton }
37867cc0636SGreg Clayton 
37967cc0636SGreg Clayton uint32_t
38067cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
38167cc0636SGreg Clayton {
38267cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
383754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
38467cc0636SGreg Clayton }
385e372b98dSGreg Clayton 
386553fad5cSEnrico Granata bool
38790a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
388553fad5cSEnrico Granata {
38990a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
390553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
391ebdc1ac0SEnrico Granata }
392553fad5cSEnrico Granata 
393ebdc1ac0SEnrico Granata bool
394ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const
395ebdc1ac0SEnrico Granata {
396ebdc1ac0SEnrico Granata     const uint32_t idx = ePropertyEscapeNonPrintables;
397ebdc1ac0SEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
398553fad5cSEnrico Granata }
399553fad5cSEnrico Granata 
4001b654882SGreg Clayton #pragma mark Debugger
4011b654882SGreg Clayton 
40267cc0636SGreg Clayton //const DebuggerPropertiesSP &
40367cc0636SGreg Clayton //Debugger::GetSettings() const
40467cc0636SGreg Clayton //{
40567cc0636SGreg Clayton //    return m_properties_sp;
40667cc0636SGreg Clayton //}
40767cc0636SGreg Clayton //
40899d0faf2SGreg Clayton 
4092f88aadfSCaroline Tice int
4102f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
4112f88aadfSCaroline Tice {
4122f88aadfSCaroline Tice     return g_shared_debugger_refcount;
4132f88aadfSCaroline Tice }
4142f88aadfSCaroline Tice 
41530fdc8d8SChris Lattner void
4165fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
41730fdc8d8SChris Lattner {
4185fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
419c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
420dbe54508SGreg Clayton         lldb_private::Initialize();
42199d0faf2SGreg Clayton }
42230fdc8d8SChris Lattner 
42330fdc8d8SChris Lattner void
42430fdc8d8SChris Lattner Debugger::Terminate ()
42530fdc8d8SChris Lattner {
4266611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
4276611103cSGreg Clayton     {
42830fdc8d8SChris Lattner         g_shared_debugger_refcount--;
42930fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
43030fdc8d8SChris Lattner         {
431dbe54508SGreg Clayton             lldb_private::WillTerminate();
432dbe54508SGreg Clayton             lldb_private::Terminate();
4336760a517SCaroline Tice 
43499d0faf2SGreg Clayton             // Clear our master list of debugger objects
43599d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
43699d0faf2SGreg Clayton             GetDebuggerList().clear();
43730fdc8d8SChris Lattner         }
4386760a517SCaroline Tice     }
4396760a517SCaroline Tice }
44030fdc8d8SChris Lattner 
44120bd37f7SCaroline Tice void
44220bd37f7SCaroline Tice Debugger::SettingsInitialize ()
44320bd37f7SCaroline Tice {
4446920b52bSGreg Clayton     Target::SettingsInitialize ();
44520bd37f7SCaroline Tice }
44620bd37f7SCaroline Tice 
44720bd37f7SCaroline Tice void
44820bd37f7SCaroline Tice Debugger::SettingsTerminate ()
44920bd37f7SCaroline Tice {
4506920b52bSGreg Clayton     Target::SettingsTerminate ();
45120bd37f7SCaroline Tice }
45220bd37f7SCaroline Tice 
45321dfcd9dSEnrico Granata bool
454e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
45521dfcd9dSEnrico Granata {
4565fb8f797SGreg Clayton     if (g_load_plugin_callback)
457e743c782SEnrico Granata     {
45858a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
45958a559c0SZachary Turner         if (dynlib.isValid())
46021dfcd9dSEnrico Granata         {
46158a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
46221dfcd9dSEnrico Granata             return true;
46321dfcd9dSEnrico Granata         }
4645fb8f797SGreg Clayton     }
4655fb8f797SGreg Clayton     else
4665fb8f797SGreg Clayton     {
4675fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4685fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4695fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4705fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4715fb8f797SGreg Clayton     }
47221dfcd9dSEnrico Granata     return false;
47321dfcd9dSEnrico Granata }
47421dfcd9dSEnrico Granata 
47521dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
47621dfcd9dSEnrico Granata LoadPluginCallback
47721dfcd9dSEnrico Granata (
47821dfcd9dSEnrico Granata  void *baton,
47921dfcd9dSEnrico Granata  FileSpec::FileType file_type,
48021dfcd9dSEnrico Granata  const FileSpec &file_spec
48121dfcd9dSEnrico Granata  )
48221dfcd9dSEnrico Granata {
48321dfcd9dSEnrico Granata     Error error;
48421dfcd9dSEnrico Granata 
48521dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4863cf443ddSMichael Sartain     static ConstString g_solibext("so");
48721dfcd9dSEnrico Granata 
48821dfcd9dSEnrico Granata     if (!baton)
48921dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
49021dfcd9dSEnrico Granata 
49121dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
49221dfcd9dSEnrico Granata 
49321dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
49421dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
49521dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
49621dfcd9dSEnrico Granata     // file type information.
49721dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
49821dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
49921dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
50021dfcd9dSEnrico Granata     {
50121dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
50221dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
50321dfcd9dSEnrico Granata 
5043cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
5053cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
5063cf443ddSMichael Sartain         {
50721dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
5083cf443ddSMichael Sartain         }
50921dfcd9dSEnrico Granata 
510e743c782SEnrico Granata         Error plugin_load_error;
511e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
51221dfcd9dSEnrico Granata 
51321dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
51421dfcd9dSEnrico Granata     }
51521dfcd9dSEnrico Granata 
51621dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
51721dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
51821dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
51921dfcd9dSEnrico Granata     {
52021dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
52121dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
5226a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
52321dfcd9dSEnrico Granata         // information.
52421dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
52521dfcd9dSEnrico Granata     }
52621dfcd9dSEnrico Granata 
52721dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
52821dfcd9dSEnrico Granata }
52921dfcd9dSEnrico Granata 
53021dfcd9dSEnrico Granata void
53121dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
53221dfcd9dSEnrico Granata {
53321dfcd9dSEnrico Granata     FileSpec dir_spec;
53421dfcd9dSEnrico Granata     const bool find_directories = true;
53521dfcd9dSEnrico Granata     const bool find_files = true;
53621dfcd9dSEnrico Granata     const bool find_other = true;
53721dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
53842ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
53921dfcd9dSEnrico Granata     {
54021dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
54121dfcd9dSEnrico Granata         {
54221dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
54321dfcd9dSEnrico Granata                                           find_directories,
54421dfcd9dSEnrico Granata                                           find_files,
54521dfcd9dSEnrico Granata                                           find_other,
54621dfcd9dSEnrico Granata                                           LoadPluginCallback,
54721dfcd9dSEnrico Granata                                           this);
54821dfcd9dSEnrico Granata         }
54921dfcd9dSEnrico Granata     }
55021dfcd9dSEnrico Granata 
55142ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
55221dfcd9dSEnrico Granata     {
55321dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
55421dfcd9dSEnrico Granata         {
55521dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
55621dfcd9dSEnrico Granata                                           find_directories,
55721dfcd9dSEnrico Granata                                           find_files,
55821dfcd9dSEnrico Granata                                           find_other,
55921dfcd9dSEnrico Granata                                           LoadPluginCallback,
56021dfcd9dSEnrico Granata                                           this);
56121dfcd9dSEnrico Granata         }
56221dfcd9dSEnrico Granata     }
563e8cd0c98SGreg Clayton 
564e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
56521dfcd9dSEnrico Granata }
56621dfcd9dSEnrico Granata 
5676611103cSGreg Clayton DebuggerSP
568228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5696611103cSGreg Clayton {
570228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
571c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5726611103cSGreg Clayton     {
5736611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5746611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5756611103cSGreg Clayton     }
57621dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5776611103cSGreg Clayton     return debugger_sp;
5786611103cSGreg Clayton }
5796611103cSGreg Clayton 
580e02657b1SCaroline Tice void
5814d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
582e02657b1SCaroline Tice {
583e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
584e02657b1SCaroline Tice         return;
585e02657b1SCaroline Tice 
5868314c525SJim Ingham     debugger_sp->Clear();
5878314c525SJim Ingham 
588c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
589c15f55e2SGreg Clayton     {
590e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
591e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
592e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
593e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
594e02657b1SCaroline Tice         {
595e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
596e02657b1SCaroline Tice             {
597e02657b1SCaroline Tice                 debugger_list.erase (pos);
598e02657b1SCaroline Tice                 return;
599e02657b1SCaroline Tice             }
600e02657b1SCaroline Tice         }
601e02657b1SCaroline Tice     }
602c15f55e2SGreg Clayton }
603e02657b1SCaroline Tice 
6044d122c40SGreg Clayton DebuggerSP
6053df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
6063df9a8dfSCaroline Tice {
6074d122c40SGreg Clayton     DebuggerSP debugger_sp;
6086920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
6096920b52bSGreg Clayton     {
6106920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6116920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6126920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6136920b52bSGreg Clayton 
6146920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6156920b52bSGreg Clayton         {
6166920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
6176920b52bSGreg Clayton             {
6186920b52bSGreg Clayton                 debugger_sp = *pos;
6196920b52bSGreg Clayton                 break;
6206920b52bSGreg Clayton             }
6216920b52bSGreg Clayton         }
6226920b52bSGreg Clayton     }
6233df9a8dfSCaroline Tice     return debugger_sp;
6243df9a8dfSCaroline Tice }
6256611103cSGreg Clayton 
6266611103cSGreg Clayton TargetSP
6276611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6286611103cSGreg Clayton {
6294d122c40SGreg Clayton     TargetSP target_sp;
630c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
631c15f55e2SGreg Clayton     {
6326611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6336611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6346611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6356611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6366611103cSGreg Clayton         {
6376611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6386611103cSGreg Clayton             if (target_sp)
6396611103cSGreg Clayton                 break;
6406611103cSGreg Clayton         }
641c15f55e2SGreg Clayton     }
6426611103cSGreg Clayton     return target_sp;
6436611103cSGreg Clayton }
6446611103cSGreg Clayton 
645e4e45924SGreg Clayton TargetSP
646e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
647e4e45924SGreg Clayton {
648e4e45924SGreg Clayton     TargetSP target_sp;
649c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
650c15f55e2SGreg Clayton     {
651e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
652e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
653e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
654e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
655e4e45924SGreg Clayton         {
656e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
657e4e45924SGreg Clayton             if (target_sp)
658e4e45924SGreg Clayton                 break;
659e4e45924SGreg Clayton         }
660c15f55e2SGreg Clayton     }
661e4e45924SGreg Clayton     return target_sp;
662e4e45924SGreg Clayton }
663e4e45924SGreg Clayton 
664e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
665e6481c7eSJason Molenda     UserID(g_unique_id++),
666e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
667e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
668e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
669e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
670e6481c7eSJason Molenda     m_terminal_state(),
671e6481c7eSJason Molenda     m_target_list(*this),
672e6481c7eSJason Molenda     m_platform_list(),
673e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
674e6481c7eSJason Molenda     m_source_manager_ap(),
675e6481c7eSJason Molenda     m_source_file_cache(),
676e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
677e6481c7eSJason Molenda     m_input_reader_stack(),
678e6481c7eSJason Molenda     m_instance_name(),
679afa91e33SGreg Clayton     m_loaded_plugins(),
680afa91e33SGreg Clayton     m_event_handler_thread (),
681afa91e33SGreg Clayton     m_io_handler_thread (),
682afa91e33SGreg Clayton     m_sync_broadcaster (NULL, "lldb.debugger.sync")
68330fdc8d8SChris Lattner {
68467cc0636SGreg Clayton     char instance_cstr[256];
68567cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
68667cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
687228063cdSJim Ingham     if (log_callback)
688228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6896611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
690ded470d3SGreg Clayton     // Always add our default platform to the platform list
691615eb7e6SGreg Clayton     PlatformSP default_platform_sp (Platform::GetHostPlatform());
692ded470d3SGreg Clayton     assert (default_platform_sp.get());
693ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
69467cc0636SGreg Clayton 
695754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
69667cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
69767cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
69867cc0636SGreg Clayton                                      true,
69967cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
700*63acdfdeSOleksiy Vyalov     m_collection_sp->AppendProperty (ConstString("platform"),
701*63acdfdeSOleksiy Vyalov                                      ConstString("Platform settings."),
702*63acdfdeSOleksiy Vyalov                                      true,
703*63acdfdeSOleksiy Vyalov                                      Platform::GetGlobalPlatformProperties()->GetValueProperties());
704754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
705754a9369SGreg Clayton     {
706754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
707754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
708754a9369SGreg Clayton                                          true,
709754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
710754a9369SGreg Clayton     }
71167cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
71267cc0636SGreg Clayton     term_width->SetMinimumValue(10);
71367cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
714c3ce7f27SMichael Sartain 
715c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
716c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
717c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
718c3ce7f27SMichael Sartain         SetUseColor (false);
71930fdc8d8SChris Lattner }
72030fdc8d8SChris Lattner 
72130fdc8d8SChris Lattner Debugger::~Debugger ()
72230fdc8d8SChris Lattner {
7238314c525SJim Ingham     Clear();
7248314c525SJim Ingham }
7258314c525SJim Ingham 
7268314c525SJim Ingham void
7278314c525SJim Ingham Debugger::Clear()
7288314c525SJim Ingham {
72944d93782SGreg Clayton     ClearIOHandlers();
73044d93782SGreg Clayton     StopIOHandlerThread();
73144d93782SGreg Clayton     StopEventHandlerThread();
7321ed54f50SGreg Clayton     m_listener.Clear();
7336611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
7346611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7356611103cSGreg Clayton     {
736ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
737ccbc08e6SGreg Clayton         if (target_sp)
738ccbc08e6SGreg Clayton         {
739ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7406611103cSGreg Clayton             if (process_sp)
7411fd07059SJim Ingham                 process_sp->Finalize();
742ccbc08e6SGreg Clayton             target_sp->Destroy();
7436611103cSGreg Clayton         }
74430fdc8d8SChris Lattner     }
7454bddaeb5SJim Ingham     BroadcasterManager::Clear ();
74630fdc8d8SChris Lattner 
7470d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7480d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
749c5917d9aSJim Ingham     m_terminal_state.Clear();
75044d93782SGreg Clayton     if (m_input_file_sp)
75144d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7520c4129f2SGreg Clayton 
7530c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7548314c525SJim Ingham }
75530fdc8d8SChris Lattner 
75630fdc8d8SChris Lattner bool
757fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
758fc3f027dSGreg Clayton {
75944d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
76044d93782SGreg Clayton     return false;
761fc3f027dSGreg Clayton }
762fc3f027dSGreg Clayton 
763fc3f027dSGreg Clayton void
764fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
765fc3f027dSGreg Clayton {
76644d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
767fc3f027dSGreg Clayton }
768fc3f027dSGreg Clayton 
769fc3f027dSGreg Clayton bool
77030fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
77130fdc8d8SChris Lattner {
7726611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
77330fdc8d8SChris Lattner }
77430fdc8d8SChris Lattner 
77530fdc8d8SChris Lattner void
77630fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
77730fdc8d8SChris Lattner {
7786611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
77930fdc8d8SChris Lattner }
78030fdc8d8SChris Lattner 
78130fdc8d8SChris Lattner 
78230fdc8d8SChris Lattner void
78330fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
78430fdc8d8SChris Lattner {
78544d93782SGreg Clayton     if (m_input_file_sp)
78644d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
78744d93782SGreg Clayton     else
78844d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
78944d93782SGreg Clayton 
79044d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
79151b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
79251b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
79330fdc8d8SChris Lattner 
794c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
795c5917d9aSJim Ingham     SaveInputTerminalState ();
79630fdc8d8SChris Lattner }
79730fdc8d8SChris Lattner 
79830fdc8d8SChris Lattner void
79930fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
80030fdc8d8SChris Lattner {
80144d93782SGreg Clayton     if (m_output_file_sp)
80244d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
80344d93782SGreg Clayton     else
80444d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
80544d93782SGreg Clayton 
80644d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
80751b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
80851b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
8092f88aadfSCaroline Tice 
810b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
811b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
812b588726eSEnrico Granata     const bool can_create = false;
813b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
814b588726eSEnrico Granata     if (script_interpreter)
815b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
81630fdc8d8SChris Lattner }
81730fdc8d8SChris Lattner 
81830fdc8d8SChris Lattner void
81930fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
82030fdc8d8SChris Lattner {
82144d93782SGreg Clayton     if (m_error_file_sp)
82244d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
82344d93782SGreg Clayton     else
82444d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
82544d93782SGreg Clayton 
82644d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
82751b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
82851b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
82930fdc8d8SChris Lattner }
83030fdc8d8SChris Lattner 
831c5917d9aSJim Ingham void
832c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
833c5917d9aSJim Ingham {
83444d93782SGreg Clayton     if (m_input_file_sp)
83544d93782SGreg Clayton     {
83644d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
837c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
838c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
839c5917d9aSJim Ingham     }
84044d93782SGreg Clayton }
841c5917d9aSJim Ingham 
842c5917d9aSJim Ingham void
843c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
844c5917d9aSJim Ingham {
845c5917d9aSJim Ingham     m_terminal_state.Restore();
846c5917d9aSJim Ingham }
847c5917d9aSJim Ingham 
84830fdc8d8SChris Lattner ExecutionContext
8492976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
85030fdc8d8SChris Lattner {
85130fdc8d8SChris Lattner     ExecutionContext exe_ctx;
852c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
853c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
85430fdc8d8SChris Lattner 
85530fdc8d8SChris Lattner     if (target_sp)
85630fdc8d8SChris Lattner     {
857c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
858c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
859c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
86030fdc8d8SChris Lattner         {
861c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
862c14ee32dSGreg Clayton             if (thread_sp)
86330fdc8d8SChris Lattner             {
864c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
865c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
866c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
867c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
86830fdc8d8SChris Lattner             }
86930fdc8d8SChris Lattner         }
87030fdc8d8SChris Lattner     }
87130fdc8d8SChris Lattner     return exe_ctx;
87230fdc8d8SChris Lattner }
87330fdc8d8SChris Lattner 
87430fdc8d8SChris Lattner void
875efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
876efed6131SCaroline Tice {
87744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
87844d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
879efed6131SCaroline Tice     if (reader_sp)
88044d93782SGreg Clayton         reader_sp->Interrupt();
881efed6131SCaroline Tice }
882efed6131SCaroline Tice 
883efed6131SCaroline Tice void
884efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
885efed6131SCaroline Tice {
88644d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
88744d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
888efed6131SCaroline Tice     if (reader_sp)
88944d93782SGreg Clayton         reader_sp->GotEOF();
890efed6131SCaroline Tice }
891efed6131SCaroline Tice 
892efed6131SCaroline Tice void
89344d93782SGreg Clayton Debugger::ClearIOHandlers ()
8943d6086f6SCaroline Tice {
895b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
89644d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
897d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8983d6086f6SCaroline Tice     {
89944d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
9003d6086f6SCaroline Tice         if (reader_sp)
9013d6086f6SCaroline Tice         {
90244d93782SGreg Clayton             m_input_reader_stack.Pop();
9033d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
904e68f5d6bSGreg Clayton             reader_sp->Cancel();
9053d6086f6SCaroline Tice         }
9063d6086f6SCaroline Tice     }
9073d6086f6SCaroline Tice }
9083d6086f6SCaroline Tice 
9093d6086f6SCaroline Tice void
9109aaab558SSiva Chandra Debugger::ExecuteIOHandlers()
911969ed3d1SCaroline Tice {
91244d93782SGreg Clayton 
91344d93782SGreg Clayton     while (1)
914969ed3d1SCaroline Tice     {
91544d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
91630fdc8d8SChris Lattner         if (!reader_sp)
91730fdc8d8SChris Lattner             break;
91830fdc8d8SChris Lattner 
91944d93782SGreg Clayton         reader_sp->Activate();
92044d93782SGreg Clayton         reader_sp->Run();
92144d93782SGreg Clayton         reader_sp->Deactivate();
92244d93782SGreg Clayton 
92344d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
92444d93782SGreg Clayton         while (1)
92530fdc8d8SChris Lattner         {
92644d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
92744d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
92844d93782SGreg Clayton                 m_input_reader_stack.Pop();
92930fdc8d8SChris Lattner             else
93030fdc8d8SChris Lattner                 break;
93130fdc8d8SChris Lattner         }
93230fdc8d8SChris Lattner     }
93344d93782SGreg Clayton     ClearIOHandlers();
93444d93782SGreg Clayton }
93530fdc8d8SChris Lattner 
93644d93782SGreg Clayton bool
93744d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
93844d93782SGreg Clayton {
93944d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
94044d93782SGreg Clayton }
94130fdc8d8SChris Lattner 
94244d93782SGreg Clayton 
94344d93782SGreg Clayton ConstString
94444d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
94544d93782SGreg Clayton {
94644d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
94730fdc8d8SChris Lattner }
94830fdc8d8SChris Lattner 
949a487aa4cSKate Stone const char *
950a487aa4cSKate Stone Debugger::GetIOHandlerCommandPrefix()
951a487aa4cSKate Stone {
952a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
953a487aa4cSKate Stone }
954a487aa4cSKate Stone 
955a487aa4cSKate Stone const char *
956a487aa4cSKate Stone Debugger::GetIOHandlerHelpPrologue()
957a487aa4cSKate Stone {
958a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
959a487aa4cSKate Stone }
960a487aa4cSKate Stone 
96130fdc8d8SChris Lattner void
96244d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
96344d93782SGreg Clayton {
96444d93782SGreg Clayton     PushIOHandler (reader_sp);
965577508dfSGreg Clayton 
966577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
967577508dfSGreg Clayton     while (top_reader_sp)
968577508dfSGreg Clayton     {
969577508dfSGreg Clayton         top_reader_sp->Activate();
970577508dfSGreg Clayton         top_reader_sp->Run();
971577508dfSGreg Clayton         top_reader_sp->Deactivate();
972577508dfSGreg Clayton 
973577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
974577508dfSGreg Clayton         {
975577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
976577508dfSGreg Clayton                 break;
977577508dfSGreg Clayton         }
978577508dfSGreg Clayton 
979577508dfSGreg Clayton         while (1)
980577508dfSGreg Clayton         {
981577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
982577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
983577508dfSGreg Clayton                 m_input_reader_stack.Pop();
984577508dfSGreg Clayton             else
985577508dfSGreg Clayton                 break;
986577508dfSGreg Clayton         }
987577508dfSGreg Clayton     }
98844d93782SGreg Clayton }
98944d93782SGreg Clayton 
99044d93782SGreg Clayton void
99144d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
99244d93782SGreg Clayton {
99344d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
99444d93782SGreg Clayton     // This function is called when one ore more of the streams
99544d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
99644d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
99744d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
99844d93782SGreg Clayton 
99944d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
100044d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
100144d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
100244d93782SGreg Clayton     if (!in)
100344d93782SGreg Clayton     {
100444d93782SGreg Clayton         if (top_reader_sp)
100544d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
100644d93782SGreg Clayton         else
100744d93782SGreg Clayton             in = GetInputFile();
100844d93782SGreg Clayton 
100944d93782SGreg Clayton         // If there is nothing, use stdin
101044d93782SGreg Clayton         if (!in)
101144d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
101244d93782SGreg Clayton     }
101344d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
101444d93782SGreg Clayton     if (!out)
101544d93782SGreg Clayton     {
101644d93782SGreg Clayton         if (top_reader_sp)
101744d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
101844d93782SGreg Clayton         else
101944d93782SGreg Clayton             out = GetOutputFile();
102044d93782SGreg Clayton 
102144d93782SGreg Clayton         // If there is nothing, use stdout
102244d93782SGreg Clayton         if (!out)
102344d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
102444d93782SGreg Clayton     }
102544d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
102644d93782SGreg Clayton     if (!err)
102744d93782SGreg Clayton     {
102844d93782SGreg Clayton         if (top_reader_sp)
102944d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
103044d93782SGreg Clayton         else
103144d93782SGreg Clayton             err = GetErrorFile();
103244d93782SGreg Clayton 
103344d93782SGreg Clayton         // If there is nothing, use stderr
103444d93782SGreg Clayton         if (!err)
103544d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
103644d93782SGreg Clayton 
103744d93782SGreg Clayton     }
103844d93782SGreg Clayton }
103944d93782SGreg Clayton 
104044d93782SGreg Clayton void
104144d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
104230fdc8d8SChris Lattner {
104330fdc8d8SChris Lattner     if (!reader_sp)
104430fdc8d8SChris Lattner         return;
1045b44880caSCaroline Tice 
104644d93782SGreg Clayton     // Got the current top input reader...
104744d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1048b44880caSCaroline Tice 
1049b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
1050b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
1051b4874f1aSGreg Clayton     {
105244d93782SGreg Clayton         // Push our new input reader
1053d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
105444d93782SGreg Clayton 
105544d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
105644d93782SGreg Clayton         // and let this new input reader take over
105744d93782SGreg Clayton         if (top_reader_sp)
105844d93782SGreg Clayton             top_reader_sp->Deactivate();
105930fdc8d8SChris Lattner     }
1060b4874f1aSGreg Clayton }
106130fdc8d8SChris Lattner 
106230fdc8d8SChris Lattner bool
106344d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
106430fdc8d8SChris Lattner {
106530fdc8d8SChris Lattner     bool result = false;
106630fdc8d8SChris Lattner 
106744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
106844d93782SGreg Clayton 
106930fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10706a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
1071d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
107230fdc8d8SChris Lattner     {
107344d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
107430fdc8d8SChris Lattner 
107530fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
107630fdc8d8SChris Lattner         {
107744d93782SGreg Clayton             reader_sp->Deactivate();
1078b4874f1aSGreg Clayton             reader_sp->Cancel();
1079d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
108030fdc8d8SChris Lattner 
1081d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
108230fdc8d8SChris Lattner             if (reader_sp)
108344d93782SGreg Clayton                 reader_sp->Activate();
108444d93782SGreg Clayton 
108544d93782SGreg Clayton             result = true;
108630fdc8d8SChris Lattner         }
108730fdc8d8SChris Lattner     }
108830fdc8d8SChris Lattner     return result;
108930fdc8d8SChris Lattner }
109030fdc8d8SChris Lattner 
109130fdc8d8SChris Lattner bool
109244d93782SGreg Clayton Debugger::HideTopIOHandler()
109330fdc8d8SChris Lattner {
109444d93782SGreg Clayton     Mutex::Locker locker;
109530fdc8d8SChris Lattner 
109644d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
109730fdc8d8SChris Lattner     {
109844d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
109944d93782SGreg Clayton         if (reader_sp)
110044d93782SGreg Clayton             reader_sp->Hide();
110144d93782SGreg Clayton         return true;
110230fdc8d8SChris Lattner     }
110344d93782SGreg Clayton     return false;
110430fdc8d8SChris Lattner }
110530fdc8d8SChris Lattner 
110630fdc8d8SChris Lattner void
110744d93782SGreg Clayton Debugger::RefreshTopIOHandler()
110830fdc8d8SChris Lattner {
110944d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
111044d93782SGreg Clayton     if (reader_sp)
111144d93782SGreg Clayton         reader_sp->Refresh();
111230fdc8d8SChris Lattner }
111344d93782SGreg Clayton 
11146611103cSGreg Clayton 
11155b52f0c7SJim Ingham StreamSP
11165b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
11175b52f0c7SJim Ingham {
11185b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
11195b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
11205b52f0c7SJim Ingham }
11215b52f0c7SJim Ingham 
11225b52f0c7SJim Ingham StreamSP
11235b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
11245b52f0c7SJim Ingham {
11255b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
11265b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
11275b52f0c7SJim Ingham }
11285b52f0c7SJim Ingham 
1129c7bece56SGreg Clayton size_t
1130061858ceSEnrico Granata Debugger::GetNumDebuggers()
1131061858ceSEnrico Granata {
1132c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1133c15f55e2SGreg Clayton     {
1134061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1135061858ceSEnrico Granata         return GetDebuggerList().size();
1136061858ceSEnrico Granata     }
1137c15f55e2SGreg Clayton     return 0;
1138c15f55e2SGreg Clayton }
1139061858ceSEnrico Granata 
1140061858ceSEnrico Granata lldb::DebuggerSP
1141c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1142061858ceSEnrico Granata {
1143061858ceSEnrico Granata     DebuggerSP debugger_sp;
1144061858ceSEnrico Granata 
1145c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1146c15f55e2SGreg Clayton     {
1147061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1148061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1149061858ceSEnrico Granata 
1150061858ceSEnrico Granata         if (index < debugger_list.size())
1151061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1152c15f55e2SGreg Clayton     }
1153061858ceSEnrico Granata 
1154061858ceSEnrico Granata     return debugger_sp;
1155061858ceSEnrico Granata }
1156061858ceSEnrico Granata 
1157ebc1bb27SCaroline Tice DebuggerSP
1158ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1159ebc1bb27SCaroline Tice {
11604d122c40SGreg Clayton     DebuggerSP debugger_sp;
1161ebc1bb27SCaroline Tice 
1162c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1163c15f55e2SGreg Clayton     {
1164ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1165ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1166ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1167ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1168ebc1bb27SCaroline Tice         {
1169ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1170ebc1bb27SCaroline Tice             {
1171ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1172ebc1bb27SCaroline Tice                 break;
1173ebc1bb27SCaroline Tice             }
1174ebc1bb27SCaroline Tice         }
1175c15f55e2SGreg Clayton     }
1176ebc1bb27SCaroline Tice     return debugger_sp;
1177ebc1bb27SCaroline Tice }
11783df9a8dfSCaroline Tice 
11792643b905SSaleem Abdulrasool #if 0
11801b654882SGreg Clayton static void
1181b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11821b654882SGreg Clayton {
11831b654882SGreg Clayton     if (frame == NULL)
11841b654882SGreg Clayton         return;
11851b654882SGreg Clayton 
11861b654882SGreg Clayton     StreamString s;
11871b654882SGreg Clayton     const char *prompt_format =
11881b654882SGreg Clayton     "{addr = '${addr}'\n}"
1189aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1190aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
11911b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11921b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11931b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11941b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11951b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11961b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11971b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11981b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11991b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
12001b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
12011b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
12021b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
12031b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
12041b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
12051b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
12061b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
12071b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
12081b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
12091b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
12101b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
12111b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
12121b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
12131b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
12141b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
12151b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
12161b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
12171b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1218aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1219aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
12201b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1221aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1222ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
12231b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1224aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
12251b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
12261b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
12271b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
12281b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
12291b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
12301b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
12311b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
12321b654882SGreg Clayton ;
12331b654882SGreg Clayton 
12341b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
12351b654882SGreg Clayton     ExecutionContext exe_ctx;
12360603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1237c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
12381b654882SGreg Clayton     {
12391b654882SGreg Clayton         printf("%s\n", s.GetData());
12401b654882SGreg Clayton     }
12411b654882SGreg Clayton     else
12421b654882SGreg Clayton     {
12431b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
12441b654882SGreg Clayton     }
12451b654882SGreg Clayton }
12462643b905SSaleem Abdulrasool #endif
12471b654882SGreg Clayton 
1248c3ce7f27SMichael Sartain bool
1249554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
1250aff1b357SJason Molenda                                      const SymbolContext *sc,
1251aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
1252aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
1253aff1b357SJason Molenda                                      const Address *addr,
1254aff1b357SJason Molenda                                      Stream &s)
1255aff1b357SJason Molenda {
1256554f68d3SGreg Clayton     FormatEntity::Entry format_entry;
1257554f68d3SGreg Clayton 
1258554f68d3SGreg Clayton     if (format == NULL)
1259aff1b357SJason Molenda     {
1260554f68d3SGreg Clayton         if (exe_ctx != NULL && exe_ctx->HasTargetScope())
1261aff1b357SJason Molenda             format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1262554f68d3SGreg Clayton         if (format == NULL)
1263554f68d3SGreg Clayton         {
1264554f68d3SGreg Clayton             FormatEntity::Parse("${addr}: ", format_entry);
1265554f68d3SGreg Clayton             format = &format_entry;
1266554f68d3SGreg Clayton         }
1267aff1b357SJason Molenda     }
1268aff1b357SJason Molenda     bool function_changed = false;
1269aff1b357SJason Molenda     bool initial_function = false;
1270aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
1271aff1b357SJason Molenda     {
1272aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
1273aff1b357SJason Molenda         {
1274aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
1275aff1b357SJason Molenda             {
1276aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
1277aff1b357SJason Molenda                 {
1278aff1b357SJason Molenda                     function_changed = true;
1279aff1b357SJason Molenda                 }
1280aff1b357SJason Molenda             }
1281aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
1282aff1b357SJason Molenda             {
1283aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
1284aff1b357SJason Molenda                 {
1285aff1b357SJason Molenda                     function_changed = true;
1286aff1b357SJason Molenda                 }
1287aff1b357SJason Molenda             }
1288aff1b357SJason Molenda         }
1289aff1b357SJason Molenda     }
1290aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
1291aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
1292aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
1293aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
1294aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
1295aff1b357SJason Molenda     {
1296aff1b357SJason Molenda         initial_function = true;
1297aff1b357SJason Molenda     }
1298554f68d3SGreg Clayton     return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function);
1299aff1b357SJason Molenda }
1300aff1b357SJason Molenda 
1301aff1b357SJason Molenda 
1302228063cdSJim Ingham void
1303228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
1304228063cdSJim Ingham {
13054f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
13064f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
13074f02b22dSJim Ingham     // callback.
1308228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
1309228063cdSJim Ingham }
1310228063cdSJim Ingham 
1311228063cdSJim Ingham bool
1312228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
1313228063cdSJim Ingham {
1314228063cdSJim Ingham     Log::Callbacks log_callbacks;
1315228063cdSJim Ingham 
1316228063cdSJim Ingham     StreamSP log_stream_sp;
13179a028519SSean Callanan     if (m_log_callback_stream_sp)
1318228063cdSJim Ingham     {
1319228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
1320228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
1321228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1322228063cdSJim Ingham     }
1323228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
1324228063cdSJim Ingham     {
132544d93782SGreg Clayton         log_stream_sp = GetOutputFile();
1326228063cdSJim Ingham     }
1327228063cdSJim Ingham     else
1328228063cdSJim Ingham     {
1329228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
1330c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
1331c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
1332c1b2ccfdSGreg Clayton         if (!log_stream_sp)
1333228063cdSJim Ingham         {
1334228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
1335228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
1336228063cdSJim Ingham         }
1337228063cdSJim Ingham     }
1338228063cdSJim Ingham     assert (log_stream_sp.get());
1339228063cdSJim Ingham 
1340228063cdSJim Ingham     if (log_options == 0)
1341228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
1342228063cdSJim Ingham 
134357abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
1344228063cdSJim Ingham     {
1345228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
1346228063cdSJim Ingham         return true;
1347228063cdSJim Ingham     }
1348228063cdSJim Ingham     else
1349228063cdSJim Ingham     {
1350228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
1351228063cdSJim Ingham         if (log_channel_sp)
1352228063cdSJim Ingham         {
1353228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
1354228063cdSJim Ingham             {
1355228063cdSJim Ingham                 return true;
1356228063cdSJim Ingham             }
1357228063cdSJim Ingham             else
1358228063cdSJim Ingham             {
1359228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
1360228063cdSJim Ingham                 return false;
1361228063cdSJim Ingham             }
1362228063cdSJim Ingham         }
1363228063cdSJim Ingham         else
1364228063cdSJim Ingham         {
1365228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
1366228063cdSJim Ingham             return false;
1367228063cdSJim Ingham         }
1368228063cdSJim Ingham     }
1369228063cdSJim Ingham     return false;
1370228063cdSJim Ingham }
1371228063cdSJim Ingham 
13729585fbfcSGreg Clayton SourceManager &
13739585fbfcSGreg Clayton Debugger::GetSourceManager ()
13749585fbfcSGreg Clayton {
13759585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
13769585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
13779585fbfcSGreg Clayton     return *m_source_manager_ap;
13789585fbfcSGreg Clayton }
13799585fbfcSGreg Clayton 
13809585fbfcSGreg Clayton 
138144d93782SGreg Clayton 
138244d93782SGreg Clayton // This function handles events that were broadcast by the process.
138344d93782SGreg Clayton void
138444d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
138544d93782SGreg Clayton {
138644d93782SGreg Clayton     using namespace lldb;
138744d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
138844d93782SGreg Clayton 
138944d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
139044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
139144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
139244d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
139344d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
139444d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
139544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
139644d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
139744d93782SGreg Clayton //    {
139844d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
139944d93782SGreg Clayton //    }
140044d93782SGreg Clayton //
140144d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
140244d93782SGreg Clayton     {
140344d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
140444d93782SGreg Clayton         if (num_new_locations > 0)
140544d93782SGreg Clayton         {
140644d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
140744d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
140844d93782SGreg Clayton             if (output_sp)
140944d93782SGreg Clayton             {
141044d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
141144d93782SGreg Clayton                                   num_new_locations,
141244d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
141344d93782SGreg Clayton                                   breakpoint->GetID());
141444d93782SGreg Clayton                 RefreshTopIOHandler();
141544d93782SGreg Clayton             }
141644d93782SGreg Clayton         }
141744d93782SGreg Clayton     }
141844d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
141944d93782SGreg Clayton //    {
142044d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
142144d93782SGreg Clayton //    }
142244d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
142344d93782SGreg Clayton //    {
142444d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
142544d93782SGreg Clayton //    }
142644d93782SGreg Clayton }
142744d93782SGreg Clayton 
142844d93782SGreg Clayton size_t
142944d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
143044d93782SGreg Clayton {
143144d93782SGreg Clayton     size_t total_bytes = 0;
143244d93782SGreg Clayton     if (stream == NULL)
143344d93782SGreg Clayton         stream = GetOutputFile().get();
143444d93782SGreg Clayton 
143544d93782SGreg Clayton     if (stream)
143644d93782SGreg Clayton     {
143744d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
143844d93782SGreg Clayton         if (process == NULL)
143944d93782SGreg Clayton         {
144044d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
144144d93782SGreg Clayton             if (target_sp)
144244d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
144344d93782SGreg Clayton         }
144444d93782SGreg Clayton         if (process)
144544d93782SGreg Clayton         {
144644d93782SGreg Clayton             Error error;
144744d93782SGreg Clayton             size_t len;
144844d93782SGreg Clayton             char stdio_buffer[1024];
144944d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
145044d93782SGreg Clayton             {
145144d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
145244d93782SGreg Clayton                 total_bytes += len;
145344d93782SGreg Clayton             }
145444d93782SGreg Clayton         }
145544d93782SGreg Clayton         stream->Flush();
145644d93782SGreg Clayton     }
145744d93782SGreg Clayton     return total_bytes;
145844d93782SGreg Clayton }
145944d93782SGreg Clayton 
146044d93782SGreg Clayton size_t
146144d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
146244d93782SGreg Clayton {
146344d93782SGreg Clayton     size_t total_bytes = 0;
146444d93782SGreg Clayton     if (stream == NULL)
146544d93782SGreg Clayton         stream = GetOutputFile().get();
146644d93782SGreg Clayton 
146744d93782SGreg Clayton     if (stream)
146844d93782SGreg Clayton     {
146944d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
147044d93782SGreg Clayton         if (process == NULL)
147144d93782SGreg Clayton         {
147244d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
147344d93782SGreg Clayton             if (target_sp)
147444d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
147544d93782SGreg Clayton         }
147644d93782SGreg Clayton         if (process)
147744d93782SGreg Clayton         {
147844d93782SGreg Clayton             Error error;
147944d93782SGreg Clayton             size_t len;
148044d93782SGreg Clayton             char stdio_buffer[1024];
148144d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
148244d93782SGreg Clayton             {
148344d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
148444d93782SGreg Clayton                 total_bytes += len;
148544d93782SGreg Clayton             }
148644d93782SGreg Clayton         }
148744d93782SGreg Clayton         stream->Flush();
148844d93782SGreg Clayton     }
148944d93782SGreg Clayton     return total_bytes;
149044d93782SGreg Clayton }
149144d93782SGreg Clayton 
1492dc6224e0SGreg Clayton 
149344d93782SGreg Clayton // This function handles events that were broadcast by the process.
149444d93782SGreg Clayton void
149544d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
149644d93782SGreg Clayton {
149744d93782SGreg Clayton     using namespace lldb;
149844d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
149944d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
150044d93782SGreg Clayton 
1501b4874f1aSGreg Clayton     StreamString output_stream;
1502b4874f1aSGreg Clayton     StreamString error_stream;
150344d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
150444d93782SGreg Clayton 
1505b4874f1aSGreg Clayton     if (!gui_enabled)
1506b4874f1aSGreg Clayton     {
1507b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
150844d93782SGreg Clayton         assert (process_sp);
150944d93782SGreg Clayton 
1510b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
151144d93782SGreg Clayton         {
1512b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
151344d93782SGreg Clayton         }
1514b4874f1aSGreg Clayton 
1515b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
151644d93782SGreg Clayton         {
1517b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
151844d93782SGreg Clayton         }
1519b4874f1aSGreg Clayton 
1520b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
152144d93782SGreg Clayton         {
1522dc6224e0SGreg Clayton             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
152344d93782SGreg Clayton         }
1524b4874f1aSGreg Clayton 
1525b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
1526b4874f1aSGreg Clayton         {
1527b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
15286fea17e8SGreg Clayton             bool top_io_handler_hid = false;
15296fea17e8SGreg Clayton 
15306fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
15316fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
1532b4874f1aSGreg Clayton 
1533b4874f1aSGreg Clayton             if (output_stream.GetSize())
1534b4874f1aSGreg Clayton             {
1535b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
1536b4874f1aSGreg Clayton                 if (output_stream_sp)
1537b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
1538b4874f1aSGreg Clayton             }
1539b4874f1aSGreg Clayton 
1540b4874f1aSGreg Clayton             if (error_stream.GetSize())
1541b4874f1aSGreg Clayton             {
1542b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
1543b4874f1aSGreg Clayton                 if (error_stream_sp)
1544b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
154544d93782SGreg Clayton             }
154644d93782SGreg Clayton 
154744d93782SGreg Clayton             if (top_io_handler_hid)
154844d93782SGreg Clayton                 RefreshTopIOHandler();
154944d93782SGreg Clayton         }
155044d93782SGreg Clayton 
1551b4874f1aSGreg Clayton         if (pop_process_io_handler)
1552b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
1553b4874f1aSGreg Clayton     }
1554b4874f1aSGreg Clayton }
1555b4874f1aSGreg Clayton 
155644d93782SGreg Clayton void
155744d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
155844d93782SGreg Clayton {
155944d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
156044d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
156144d93782SGreg Clayton     using namespace lldb;
156244d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
156344d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
156444d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
156544d93782SGreg Clayton     {
156644d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
156744d93782SGreg Clayton         if (thread_sp)
156844d93782SGreg Clayton         {
156944d93782SGreg Clayton             HideTopIOHandler();
157044d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
157144d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
157244d93782SGreg Clayton             RefreshTopIOHandler();
157344d93782SGreg Clayton         }
157444d93782SGreg Clayton     }
157544d93782SGreg Clayton }
157644d93782SGreg Clayton 
157744d93782SGreg Clayton bool
157844d93782SGreg Clayton Debugger::IsForwardingEvents ()
157944d93782SGreg Clayton {
158044d93782SGreg Clayton     return (bool)m_forward_listener_sp;
158144d93782SGreg Clayton }
158244d93782SGreg Clayton 
158344d93782SGreg Clayton void
158444d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
158544d93782SGreg Clayton {
158644d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
158744d93782SGreg Clayton }
158844d93782SGreg Clayton 
158944d93782SGreg Clayton void
159044d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
159144d93782SGreg Clayton {
159244d93782SGreg Clayton     m_forward_listener_sp.reset();
159344d93782SGreg Clayton }
159444d93782SGreg Clayton 
159544d93782SGreg Clayton 
159644d93782SGreg Clayton void
159744d93782SGreg Clayton Debugger::DefaultEventHandler()
159844d93782SGreg Clayton {
159944d93782SGreg Clayton     Listener& listener(GetListener());
160044d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
160144d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
160244d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
160344d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
160444d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
160544d93782SGreg Clayton 
160644d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
160744d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
160844d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
160944d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
161044d93782SGreg Clayton 
161144d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
161244d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
161344d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
161444d93782SGreg Clayton 
161544d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
161644d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
161744d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
161844d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
161944d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
162044d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
162144d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
162244d93782SGreg Clayton 
1623afa91e33SGreg Clayton     // Let the thread that spawned us know that we have started up and
1624afa91e33SGreg Clayton     // that we are now listening to all required events so no events get missed
1625afa91e33SGreg Clayton     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
1626afa91e33SGreg Clayton 
162744d93782SGreg Clayton     bool done = false;
162844d93782SGreg Clayton     while (!done)
162944d93782SGreg Clayton     {
163044d93782SGreg Clayton         EventSP event_sp;
163144d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
163244d93782SGreg Clayton         {
163344d93782SGreg Clayton             if (event_sp)
163444d93782SGreg Clayton             {
163544d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
163644d93782SGreg Clayton                 if (broadcaster)
163744d93782SGreg Clayton                 {
163844d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
163944d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
164044d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
164144d93782SGreg Clayton                     {
164244d93782SGreg Clayton                         HandleProcessEvent (event_sp);
164344d93782SGreg Clayton                     }
164444d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
164544d93782SGreg Clayton                     {
164644d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
164744d93782SGreg Clayton                         {
164844d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
164944d93782SGreg Clayton                         }
165044d93782SGreg Clayton                     }
165144d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
165244d93782SGreg Clayton                     {
165344d93782SGreg Clayton                         HandleThreadEvent (event_sp);
165444d93782SGreg Clayton                     }
165544d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
165644d93782SGreg Clayton                     {
165744d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
165844d93782SGreg Clayton                         {
165944d93782SGreg Clayton                             done = true;
166044d93782SGreg Clayton                         }
166144d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
166244d93782SGreg Clayton                         {
166344d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
166444d93782SGreg Clayton                             if (data && data[0])
166544d93782SGreg Clayton                             {
166644d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
166744d93782SGreg Clayton                                 if (error_sp)
166844d93782SGreg Clayton                                 {
166944d93782SGreg Clayton                                     HideTopIOHandler();
167044d93782SGreg Clayton                                     error_sp->PutCString(data);
167144d93782SGreg Clayton                                     error_sp->Flush();
167244d93782SGreg Clayton                                     RefreshTopIOHandler();
167344d93782SGreg Clayton                                 }
167444d93782SGreg Clayton                             }
167544d93782SGreg Clayton                         }
167644d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
167744d93782SGreg Clayton                         {
167844d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
167944d93782SGreg Clayton                             if (data && data[0])
168044d93782SGreg Clayton                             {
168144d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
168244d93782SGreg Clayton                                 if (output_sp)
168344d93782SGreg Clayton                                 {
168444d93782SGreg Clayton                                     HideTopIOHandler();
168544d93782SGreg Clayton                                     output_sp->PutCString(data);
168644d93782SGreg Clayton                                     output_sp->Flush();
168744d93782SGreg Clayton                                     RefreshTopIOHandler();
168844d93782SGreg Clayton                                 }
168944d93782SGreg Clayton                             }
169044d93782SGreg Clayton                         }
169144d93782SGreg Clayton                     }
169244d93782SGreg Clayton                 }
169344d93782SGreg Clayton 
169444d93782SGreg Clayton                 if (m_forward_listener_sp)
169544d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
169644d93782SGreg Clayton             }
169744d93782SGreg Clayton         }
169844d93782SGreg Clayton     }
169944d93782SGreg Clayton }
170044d93782SGreg Clayton 
170144d93782SGreg Clayton lldb::thread_result_t
170244d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
170344d93782SGreg Clayton {
170444d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
170544d93782SGreg Clayton     return NULL;
170644d93782SGreg Clayton }
170744d93782SGreg Clayton 
170844d93782SGreg Clayton bool
170944d93782SGreg Clayton Debugger::StartEventHandlerThread()
171044d93782SGreg Clayton {
1711acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
1712807b6b32SGreg Clayton     {
1713afa91e33SGreg Clayton         // We must synchronize with the DefaultEventHandler() thread to ensure
1714afa91e33SGreg Clayton         // it is up and running and listening to events before we return from
1715afa91e33SGreg Clayton         // this function. We do this by listening to events for the
1716afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
1717afa91e33SGreg Clayton         Listener listener("lldb.debugger.event-handler");
1718afa91e33SGreg Clayton         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
1719afa91e33SGreg Clayton 
17207c2896a2SZachary Turner         // Use larger 8MB stack for this thread
1721afa91e33SGreg Clayton         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
1722afa91e33SGreg Clayton                                                               this,
1723afa91e33SGreg Clayton                                                               NULL,
17247c2896a2SZachary Turner                                                               g_debugger_event_thread_stack_bytes);
1725afa91e33SGreg Clayton 
1726afa91e33SGreg Clayton         // Make sure DefaultEventHandler() is running and listening to events before we return
1727afa91e33SGreg Clayton         // from this function. We are only listening for events of type
1728afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
1729afa91e33SGreg Clayton         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
1730afa91e33SGreg Clayton         lldb::EventSP event_sp;
1731afa91e33SGreg Clayton         listener.WaitForEvent(NULL, event_sp);
1732807b6b32SGreg Clayton     }
1733acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
173444d93782SGreg Clayton }
173544d93782SGreg Clayton 
173644d93782SGreg Clayton void
173744d93782SGreg Clayton Debugger::StopEventHandlerThread()
173844d93782SGreg Clayton {
1739acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
174044d93782SGreg Clayton     {
174144d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
174239de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
174344d93782SGreg Clayton     }
174444d93782SGreg Clayton }
174544d93782SGreg Clayton 
174644d93782SGreg Clayton 
174744d93782SGreg Clayton lldb::thread_result_t
174844d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
174944d93782SGreg Clayton {
175044d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
17519aaab558SSiva Chandra     debugger->ExecuteIOHandlers();
175244d93782SGreg Clayton     debugger->StopEventHandlerThread();
175344d93782SGreg Clayton     return NULL;
175444d93782SGreg Clayton }
175544d93782SGreg Clayton 
175644d93782SGreg Clayton bool
175744d93782SGreg Clayton Debugger::StartIOHandlerThread()
175844d93782SGreg Clayton {
1759acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
1760807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
1761807b6b32SGreg Clayton                                                             IOHandlerThread,
1762807b6b32SGreg Clayton                                                             this,
1763807b6b32SGreg Clayton                                                             NULL,
1764807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
1765acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
176644d93782SGreg Clayton }
176744d93782SGreg Clayton 
176844d93782SGreg Clayton void
176944d93782SGreg Clayton Debugger::StopIOHandlerThread()
177044d93782SGreg Clayton {
1771acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
177244d93782SGreg Clayton     {
177344d93782SGreg Clayton         if (m_input_file_sp)
177444d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
177539de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
177644d93782SGreg Clayton     }
177744d93782SGreg Clayton }
177844d93782SGreg Clayton 
1779893c932aSJim Ingham Target *
1780893c932aSJim Ingham Debugger::GetDummyTarget()
1781893c932aSJim Ingham {
1782893c932aSJim Ingham     return m_target_list.GetDummyTarget (*this).get();
1783893c932aSJim Ingham }
1784893c932aSJim Ingham 
1785893c932aSJim Ingham Target *
178633df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
1787893c932aSJim Ingham {
178833df7cd3SJim Ingham     Target *target = nullptr;
178933df7cd3SJim Ingham     if (!prefer_dummy)
179033df7cd3SJim Ingham     {
179133df7cd3SJim Ingham         target = m_target_list.GetSelectedTarget().get();
179233df7cd3SJim Ingham         if (target)
179333df7cd3SJim Ingham             return target;
179433df7cd3SJim Ingham     }
1795893c932aSJim Ingham 
1796893c932aSJim Ingham     return GetDummyTarget();
1797893c932aSJim Ingham }
179844d93782SGreg Clayton 
1799