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 
67ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
687c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
69ebc1bb27SCaroline Tice 
701b654882SGreg Clayton #pragma mark Static Functions
711b654882SGreg Clayton 
721b654882SGreg Clayton static Mutex &
731b654882SGreg Clayton GetDebuggerListMutex ()
741b654882SGreg Clayton {
751b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
761b654882SGreg Clayton     return g_mutex;
771b654882SGreg Clayton }
781b654882SGreg Clayton 
791b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
801b654882SGreg Clayton 
811b654882SGreg Clayton static DebuggerList &
821b654882SGreg Clayton GetDebuggerList()
831b654882SGreg Clayton {
841b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
856a7f3338SBruce Mitchener     // global init constructors
861b654882SGreg Clayton     static DebuggerList g_list;
871b654882SGreg Clayton     return g_list;
881b654882SGreg Clayton }
89e372b98dSGreg Clayton 
90e372b98dSGreg Clayton OptionEnumValueElement
9167cc0636SGreg Clayton g_show_disassembly_enum_values[] =
92e372b98dSGreg Clayton {
9367cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
9467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
9567cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
96e372b98dSGreg Clayton     { 0, NULL, NULL }
97e372b98dSGreg Clayton };
98e372b98dSGreg Clayton 
9967cc0636SGreg Clayton OptionEnumValueElement
10067cc0636SGreg Clayton g_language_enumerators[] =
10167cc0636SGreg Clayton {
10267cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
10367cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
10467cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
105a12993c9SGreg Clayton     { 0, NULL, NULL }
10667cc0636SGreg Clayton };
107e372b98dSGreg Clayton 
10867cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10967cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
11067cc0636SGreg Clayton 
1110769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
11267cc0636SGreg Clayton     "{, ${frame.pc}}"\
11367cc0636SGreg Clayton     MODULE_WITH_FUNC\
11467cc0636SGreg Clayton     FILE_AND_LINE\
1150769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
1160769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
117705b1809SJason Molenda     "{, activity = '${thread.info.activity.name}'}" \
118705b1809SJason Molenda     "{, ${thread.info.trace_messages} messages}" \
11967cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
12067cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
12130fadafeSJim Ingham     "{\\nCompleted expression: ${thread.completed-expression}}"\
12267cc0636SGreg Clayton     "\\n"
12367cc0636SGreg Clayton 
12467cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
12567cc0636SGreg Clayton     MODULE_WITH_FUNC\
12667cc0636SGreg Clayton     FILE_AND_LINE\
12767cc0636SGreg Clayton     "\\n"
12867cc0636SGreg Clayton 
129c980fa92SJason Molenda // Three parts to this disassembly format specification:
130c980fa92SJason Molenda //   1. If this is a new function/symbol (no previous symbol/function), print
131c980fa92SJason Molenda //      dylib`funcname:\n
132c980fa92SJason Molenda //   2. If this is a symbol context change (different from previous symbol/function), print
133c980fa92SJason Molenda //      dylib`funcname:\n
134c980fa92SJason Molenda //   3. print
135c980fa92SJason Molenda //      address <+offset>:
136c980fa92SJason 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}>}: "
137c980fa92SJason Molenda 
138c980fa92SJason Molenda // gdb's disassembly format can be emulated with
139c980fa92SJason Molenda // ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
140c980fa92SJason Molenda 
141c980fa92SJason Molenda // lldb's original format for disassembly would look like this format string -
142c980fa92SJason 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}}:
143c980fa92SJason Molenda 
14467cc0636SGreg Clayton 
145754a9369SGreg Clayton static PropertyDefinition
146754a9369SGreg Clayton g_properties[] =
14767cc0636SGreg Clayton {
14867cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean     , true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
149554f68d3SGreg Clayton {   "disassembly-format",       OptionValue::eTypeFormatEntity, true, 0    , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
150554f68d3SGreg 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." },
15167cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean     , true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1524c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString      , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
15367cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum        , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
15467cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64      , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
15567cc0636SGreg 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." },
15667cc0636SGreg 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." },
15767cc0636SGreg 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." },
15867cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64      , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
159554f68d3SGreg Clayton {   "thread-format",            OptionValue::eTypeFormatEntity, true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
16067cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean     , true, false, NULL, NULL, "Whether to use an external editor or not." },
161c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean     , true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
16290a8db30SEnrico 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)." },
163ebdc1ac0SEnrico Granata {   "escape-non-printables",    OptionValue::eTypeBoolean     , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
16467cc0636SGreg Clayton {   NULL,                       OptionValue::eTypeInvalid     , true, 0    , NULL, NULL, NULL }
16567cc0636SGreg Clayton };
16667cc0636SGreg Clayton 
16767cc0636SGreg Clayton enum
16867cc0636SGreg Clayton {
16967cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
170aff1b357SJason Molenda     ePropertyDisassemblyFormat,
17167cc0636SGreg Clayton     ePropertyFrameFormat,
17267cc0636SGreg Clayton     ePropertyNotiftVoid,
17367cc0636SGreg Clayton     ePropertyPrompt,
17467cc0636SGreg Clayton     ePropertyScriptLanguage,
17567cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
17667cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
17767cc0636SGreg Clayton     ePropertyStopLineCountAfter,
17867cc0636SGreg Clayton     ePropertyStopLineCountBefore,
17967cc0636SGreg Clayton     ePropertyTerminalWidth,
18067cc0636SGreg Clayton     ePropertyThreadFormat,
181c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
182c3ce7f27SMichael Sartain     ePropertyUseColor,
183ebdc1ac0SEnrico Granata     ePropertyAutoOneLineSummaries,
184ebdc1ac0SEnrico Granata     ePropertyEscapeNonPrintables
18567cc0636SGreg Clayton };
18667cc0636SGreg Clayton 
1873a00691fSZachary Turner LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1884c05410fSGreg Clayton 
1894c05410fSGreg Clayton Error
1904c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1914c05410fSGreg Clayton                             VarSetOperationType op,
1924c05410fSGreg Clayton                             const char *property_path,
1934c05410fSGreg Clayton                             const char *value)
1944c05410fSGreg Clayton {
19584a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
196ebdc1ac0SEnrico Granata     bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
19784a53dfbSEnrico Granata     TargetSP target_sp;
198397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
19984a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
20084a53dfbSEnrico Granata     {
20184a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
20284a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
20384a53dfbSEnrico Granata     }
2044c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
2054c05410fSGreg Clayton     if (error.Success())
2064c05410fSGreg Clayton     {
20784a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
2084c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
2094c05410fSGreg Clayton         {
2104c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
211c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
212c3ce7f27SMichael Sartain             if (str.length())
213c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
21444d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
2154c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
2164c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
2174c05410fSGreg Clayton         }
218c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
219c3ce7f27SMichael Sartain         {
220c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
221c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
222c3ce7f27SMichael Sartain         }
223397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
22484a53dfbSEnrico Granata         {
225397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
22684a53dfbSEnrico Granata             {
22784a53dfbSEnrico Granata                 std::list<Error> errors;
2289730339bSEnrico Granata                 StreamString feedback_stream;
2299730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
23084a53dfbSEnrico Granata                 {
23144d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
23244d93782SGreg Clayton                     if (stream_sp)
23344d93782SGreg Clayton                     {
23484a53dfbSEnrico Granata                         for (auto error : errors)
23584a53dfbSEnrico Granata                         {
23644d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
23784a53dfbSEnrico Granata                         }
2389730339bSEnrico Granata                         if (feedback_stream.GetSize())
23944d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
24044d93782SGreg Clayton                     }
24184a53dfbSEnrico Granata                 }
24284a53dfbSEnrico Granata             }
24384a53dfbSEnrico Granata         }
244ebdc1ac0SEnrico Granata         else if (is_escape_non_printables)
245ebdc1ac0SEnrico Granata         {
246ebdc1ac0SEnrico Granata             DataVisualization::ForceUpdate();
247ebdc1ac0SEnrico Granata         }
2484c05410fSGreg Clayton     }
2494c05410fSGreg Clayton     return error;
2504c05410fSGreg Clayton }
2514c05410fSGreg Clayton 
25267cc0636SGreg Clayton bool
25367cc0636SGreg Clayton Debugger::GetAutoConfirm () const
25467cc0636SGreg Clayton {
25567cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
256754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
25767cc0636SGreg Clayton }
25867cc0636SGreg Clayton 
259554f68d3SGreg Clayton const FormatEntity::Entry *
260aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const
261aff1b357SJason Molenda {
262aff1b357SJason Molenda     const uint32_t idx = ePropertyDisassemblyFormat;
263554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
264aff1b357SJason Molenda }
265aff1b357SJason Molenda 
266554f68d3SGreg Clayton const FormatEntity::Entry *
26767cc0636SGreg Clayton Debugger::GetFrameFormat() const
26867cc0636SGreg Clayton {
26967cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
270554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
27167cc0636SGreg Clayton }
27267cc0636SGreg Clayton 
27367cc0636SGreg Clayton bool
27467cc0636SGreg Clayton Debugger::GetNotifyVoid () const
27567cc0636SGreg Clayton {
27667cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
277754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
27867cc0636SGreg Clayton }
27967cc0636SGreg Clayton 
28067cc0636SGreg Clayton const char *
28167cc0636SGreg Clayton Debugger::GetPrompt() const
28267cc0636SGreg Clayton {
28367cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
284754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
28567cc0636SGreg Clayton }
28667cc0636SGreg Clayton 
28767cc0636SGreg Clayton void
28867cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
28967cc0636SGreg Clayton {
29067cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
29167cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
29267cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
293c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
294c3ce7f27SMichael Sartain     if (str.length())
295c3ce7f27SMichael Sartain         new_prompt = str.c_str();
29644d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
29767cc0636SGreg Clayton }
29867cc0636SGreg Clayton 
299554f68d3SGreg Clayton const FormatEntity::Entry *
30067cc0636SGreg Clayton Debugger::GetThreadFormat() const
30167cc0636SGreg Clayton {
30267cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
303554f68d3SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
30467cc0636SGreg Clayton }
30567cc0636SGreg Clayton 
30667cc0636SGreg Clayton lldb::ScriptLanguage
30767cc0636SGreg Clayton Debugger::GetScriptLanguage() const
30867cc0636SGreg Clayton {
30967cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
310754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
31167cc0636SGreg Clayton }
31267cc0636SGreg Clayton 
31367cc0636SGreg Clayton bool
31467cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
31567cc0636SGreg Clayton {
31667cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
31767cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
31867cc0636SGreg Clayton }
31967cc0636SGreg Clayton 
32067cc0636SGreg Clayton uint32_t
32167cc0636SGreg Clayton Debugger::GetTerminalWidth () const
32267cc0636SGreg Clayton {
32367cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
324754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
32567cc0636SGreg Clayton }
32667cc0636SGreg Clayton 
32767cc0636SGreg Clayton bool
32867cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
32967cc0636SGreg Clayton {
33067cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
33167cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
33267cc0636SGreg Clayton }
33367cc0636SGreg Clayton 
33467cc0636SGreg Clayton bool
33567cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
33667cc0636SGreg Clayton {
33767cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
338754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
33967cc0636SGreg Clayton }
34067cc0636SGreg Clayton 
34167cc0636SGreg Clayton bool
34267cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
34367cc0636SGreg Clayton {
34467cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
34567cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
34667cc0636SGreg Clayton }
34767cc0636SGreg Clayton 
348c3ce7f27SMichael Sartain bool
349c3ce7f27SMichael Sartain Debugger::GetUseColor () const
350c3ce7f27SMichael Sartain {
351c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
352c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
353c3ce7f27SMichael Sartain }
354c3ce7f27SMichael Sartain 
355c3ce7f27SMichael Sartain bool
356c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
357c3ce7f27SMichael Sartain {
358c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
359c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
360c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
361c3ce7f27SMichael Sartain     return ret;
362c3ce7f27SMichael Sartain }
363c3ce7f27SMichael Sartain 
36467cc0636SGreg Clayton uint32_t
36567cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
36667cc0636SGreg Clayton {
36767cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
368754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
36967cc0636SGreg Clayton }
37067cc0636SGreg Clayton 
37167cc0636SGreg Clayton Debugger::StopDisassemblyType
37267cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
37367cc0636SGreg Clayton {
37467cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
375754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
37667cc0636SGreg Clayton }
37767cc0636SGreg Clayton 
37867cc0636SGreg Clayton uint32_t
37967cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
38067cc0636SGreg Clayton {
38167cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
382754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
38367cc0636SGreg Clayton }
384e372b98dSGreg Clayton 
385553fad5cSEnrico Granata bool
38690a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
387553fad5cSEnrico Granata {
38890a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
389553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
390ebdc1ac0SEnrico Granata }
391553fad5cSEnrico Granata 
392ebdc1ac0SEnrico Granata bool
393ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const
394ebdc1ac0SEnrico Granata {
395ebdc1ac0SEnrico Granata     const uint32_t idx = ePropertyEscapeNonPrintables;
396ebdc1ac0SEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
397553fad5cSEnrico Granata }
398553fad5cSEnrico Granata 
3991b654882SGreg Clayton #pragma mark Debugger
4001b654882SGreg Clayton 
40167cc0636SGreg Clayton //const DebuggerPropertiesSP &
40267cc0636SGreg Clayton //Debugger::GetSettings() const
40367cc0636SGreg Clayton //{
40467cc0636SGreg Clayton //    return m_properties_sp;
40567cc0636SGreg Clayton //}
40667cc0636SGreg Clayton //
40799d0faf2SGreg Clayton 
408*e6e2bb38SZachary Turner static bool lldb_initialized = false;
40930fdc8d8SChris Lattner void
4105fb8f797SGreg Clayton Debugger::Initialize(LoadPluginCallbackType load_plugin_callback)
41130fdc8d8SChris Lattner {
412*e6e2bb38SZachary Turner     assert(!lldb_initialized && "Debugger::Initialize called more than once!");
413*e6e2bb38SZachary Turner 
414f196c931SRobert Flack     lldb_initialized = true;
4155fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
41699d0faf2SGreg Clayton }
41730fdc8d8SChris Lattner 
418*e6e2bb38SZachary Turner void
41930fdc8d8SChris Lattner Debugger::Terminate ()
42030fdc8d8SChris Lattner {
421*e6e2bb38SZachary Turner     assert(lldb_initialized && "Debugger::Terminate called without a matching Debugger::Initialize!");
422*e6e2bb38SZachary Turner 
42399d0faf2SGreg Clayton     // Clear our master list of debugger objects
42499d0faf2SGreg Clayton     Mutex::Locker locker (GetDebuggerListMutex ());
42599d0faf2SGreg Clayton     GetDebuggerList().clear();
42630fdc8d8SChris Lattner }
42730fdc8d8SChris Lattner 
42820bd37f7SCaroline Tice void
42920bd37f7SCaroline Tice Debugger::SettingsInitialize ()
43020bd37f7SCaroline Tice {
4316920b52bSGreg Clayton     Target::SettingsInitialize ();
43220bd37f7SCaroline Tice }
43320bd37f7SCaroline Tice 
43420bd37f7SCaroline Tice void
43520bd37f7SCaroline Tice Debugger::SettingsTerminate ()
43620bd37f7SCaroline Tice {
4376920b52bSGreg Clayton     Target::SettingsTerminate ();
43820bd37f7SCaroline Tice }
43920bd37f7SCaroline Tice 
44021dfcd9dSEnrico Granata bool
441e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
44221dfcd9dSEnrico Granata {
4435fb8f797SGreg Clayton     if (g_load_plugin_callback)
444e743c782SEnrico Granata     {
44558a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
44658a559c0SZachary Turner         if (dynlib.isValid())
44721dfcd9dSEnrico Granata         {
44858a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
44921dfcd9dSEnrico Granata             return true;
45021dfcd9dSEnrico Granata         }
4515fb8f797SGreg Clayton     }
4525fb8f797SGreg Clayton     else
4535fb8f797SGreg Clayton     {
4545fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4555fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4565fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4575fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4585fb8f797SGreg Clayton     }
45921dfcd9dSEnrico Granata     return false;
46021dfcd9dSEnrico Granata }
46121dfcd9dSEnrico Granata 
46221dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
46321dfcd9dSEnrico Granata LoadPluginCallback
46421dfcd9dSEnrico Granata (
46521dfcd9dSEnrico Granata  void *baton,
46621dfcd9dSEnrico Granata  FileSpec::FileType file_type,
46721dfcd9dSEnrico Granata  const FileSpec &file_spec
46821dfcd9dSEnrico Granata  )
46921dfcd9dSEnrico Granata {
47021dfcd9dSEnrico Granata     Error error;
47121dfcd9dSEnrico Granata 
47221dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4733cf443ddSMichael Sartain     static ConstString g_solibext("so");
47421dfcd9dSEnrico Granata 
47521dfcd9dSEnrico Granata     if (!baton)
47621dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
47721dfcd9dSEnrico Granata 
47821dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
47921dfcd9dSEnrico Granata 
48021dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
48121dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
48221dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
48321dfcd9dSEnrico Granata     // file type information.
48421dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
48521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
48621dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
48721dfcd9dSEnrico Granata     {
48821dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
48921dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
49021dfcd9dSEnrico Granata 
4913cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4923cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4933cf443ddSMichael Sartain         {
49421dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4953cf443ddSMichael Sartain         }
49621dfcd9dSEnrico Granata 
497e743c782SEnrico Granata         Error plugin_load_error;
498e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
49921dfcd9dSEnrico Granata 
50021dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
50121dfcd9dSEnrico Granata     }
50221dfcd9dSEnrico Granata 
50321dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
50421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
50521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
50621dfcd9dSEnrico Granata     {
50721dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
50821dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
5096a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
51021dfcd9dSEnrico Granata         // information.
51121dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
51221dfcd9dSEnrico Granata     }
51321dfcd9dSEnrico Granata 
51421dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
51521dfcd9dSEnrico Granata }
51621dfcd9dSEnrico Granata 
51721dfcd9dSEnrico Granata void
51821dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
51921dfcd9dSEnrico Granata {
52021dfcd9dSEnrico Granata     FileSpec dir_spec;
52121dfcd9dSEnrico Granata     const bool find_directories = true;
52221dfcd9dSEnrico Granata     const bool find_files = true;
52321dfcd9dSEnrico Granata     const bool find_other = true;
52421dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
52542ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
52621dfcd9dSEnrico Granata     {
52721dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
52821dfcd9dSEnrico Granata         {
52921dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
53021dfcd9dSEnrico Granata                                           find_directories,
53121dfcd9dSEnrico Granata                                           find_files,
53221dfcd9dSEnrico Granata                                           find_other,
53321dfcd9dSEnrico Granata                                           LoadPluginCallback,
53421dfcd9dSEnrico Granata                                           this);
53521dfcd9dSEnrico Granata         }
53621dfcd9dSEnrico Granata     }
53721dfcd9dSEnrico Granata 
53842ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, 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     }
550e8cd0c98SGreg Clayton 
551e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
55221dfcd9dSEnrico Granata }
55321dfcd9dSEnrico Granata 
5546611103cSGreg Clayton DebuggerSP
555228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5566611103cSGreg Clayton {
557228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
558*e6e2bb38SZachary Turner     if (lldb_initialized)
5596611103cSGreg Clayton     {
5606611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5616611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5626611103cSGreg Clayton     }
56321dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5646611103cSGreg Clayton     return debugger_sp;
5656611103cSGreg Clayton }
5666611103cSGreg Clayton 
567e02657b1SCaroline Tice void
5684d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
569e02657b1SCaroline Tice {
570e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
571e02657b1SCaroline Tice         return;
572e02657b1SCaroline Tice 
5738314c525SJim Ingham     debugger_sp->Clear();
5748314c525SJim Ingham 
575*e6e2bb38SZachary Turner     if (lldb_initialized)
576c15f55e2SGreg Clayton     {
577e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
578e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
579e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
580e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
581e02657b1SCaroline Tice         {
582e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
583e02657b1SCaroline Tice             {
584e02657b1SCaroline Tice                 debugger_list.erase (pos);
585e02657b1SCaroline Tice                 return;
586e02657b1SCaroline Tice             }
587e02657b1SCaroline Tice         }
588e02657b1SCaroline Tice     }
589c15f55e2SGreg Clayton }
590e02657b1SCaroline Tice 
5914d122c40SGreg Clayton DebuggerSP
5923df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5933df9a8dfSCaroline Tice {
5944d122c40SGreg Clayton     DebuggerSP debugger_sp;
595*e6e2bb38SZachary Turner     if (lldb_initialized)
5966920b52bSGreg Clayton     {
5976920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5986920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5996920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6006920b52bSGreg Clayton 
6016920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6026920b52bSGreg Clayton         {
6036920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
6046920b52bSGreg Clayton             {
6056920b52bSGreg Clayton                 debugger_sp = *pos;
6066920b52bSGreg Clayton                 break;
6076920b52bSGreg Clayton             }
6086920b52bSGreg Clayton         }
6096920b52bSGreg Clayton     }
6103df9a8dfSCaroline Tice     return debugger_sp;
6113df9a8dfSCaroline Tice }
6126611103cSGreg Clayton 
6136611103cSGreg Clayton TargetSP
6146611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6156611103cSGreg Clayton {
6164d122c40SGreg Clayton     TargetSP target_sp;
617*e6e2bb38SZachary Turner     if (lldb_initialized)
618c15f55e2SGreg Clayton     {
6196611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6206611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6216611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6226611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6236611103cSGreg Clayton         {
6246611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6256611103cSGreg Clayton             if (target_sp)
6266611103cSGreg Clayton                 break;
6276611103cSGreg Clayton         }
628c15f55e2SGreg Clayton     }
6296611103cSGreg Clayton     return target_sp;
6306611103cSGreg Clayton }
6316611103cSGreg Clayton 
632e4e45924SGreg Clayton TargetSP
633e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
634e4e45924SGreg Clayton {
635e4e45924SGreg Clayton     TargetSP target_sp;
636*e6e2bb38SZachary Turner     if (lldb_initialized)
637c15f55e2SGreg Clayton     {
638e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
639e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
640e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
641e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
642e4e45924SGreg Clayton         {
643e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
644e4e45924SGreg Clayton             if (target_sp)
645e4e45924SGreg Clayton                 break;
646e4e45924SGreg Clayton         }
647c15f55e2SGreg Clayton     }
648e4e45924SGreg Clayton     return target_sp;
649e4e45924SGreg Clayton }
650e4e45924SGreg Clayton 
651e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
652e6481c7eSJason Molenda     UserID(g_unique_id++),
653e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
654e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
655e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
656e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
657e6481c7eSJason Molenda     m_terminal_state(),
658e6481c7eSJason Molenda     m_target_list(*this),
659e6481c7eSJason Molenda     m_platform_list(),
660e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
661e6481c7eSJason Molenda     m_source_manager_ap(),
662e6481c7eSJason Molenda     m_source_file_cache(),
663e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
664e6481c7eSJason Molenda     m_input_reader_stack(),
665e6481c7eSJason Molenda     m_instance_name(),
666afa91e33SGreg Clayton     m_loaded_plugins(),
667afa91e33SGreg Clayton     m_event_handler_thread (),
668afa91e33SGreg Clayton     m_io_handler_thread (),
669afa91e33SGreg Clayton     m_sync_broadcaster (NULL, "lldb.debugger.sync")
67030fdc8d8SChris Lattner {
67167cc0636SGreg Clayton     char instance_cstr[256];
67267cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
67367cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
674228063cdSJim Ingham     if (log_callback)
675228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6766611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
677ded470d3SGreg Clayton     // Always add our default platform to the platform list
678615eb7e6SGreg Clayton     PlatformSP default_platform_sp (Platform::GetHostPlatform());
679ded470d3SGreg Clayton     assert (default_platform_sp.get());
680ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
68167cc0636SGreg Clayton 
682754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
68367cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
68467cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
68567cc0636SGreg Clayton                                      true,
68667cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
68763acdfdeSOleksiy Vyalov     m_collection_sp->AppendProperty (ConstString("platform"),
68863acdfdeSOleksiy Vyalov                                      ConstString("Platform settings."),
68963acdfdeSOleksiy Vyalov                                      true,
69063acdfdeSOleksiy Vyalov                                      Platform::GetGlobalPlatformProperties()->GetValueProperties());
691754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
692754a9369SGreg Clayton     {
693754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
694754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
695754a9369SGreg Clayton                                          true,
696754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
697754a9369SGreg Clayton     }
69867cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
69967cc0636SGreg Clayton     term_width->SetMinimumValue(10);
70067cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
701c3ce7f27SMichael Sartain 
702c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
703c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
704c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
705c3ce7f27SMichael Sartain         SetUseColor (false);
70630fdc8d8SChris Lattner }
70730fdc8d8SChris Lattner 
70830fdc8d8SChris Lattner Debugger::~Debugger ()
70930fdc8d8SChris Lattner {
7108314c525SJim Ingham     Clear();
7118314c525SJim Ingham }
7128314c525SJim Ingham 
7138314c525SJim Ingham void
7148314c525SJim Ingham Debugger::Clear()
7158314c525SJim Ingham {
71644d93782SGreg Clayton     ClearIOHandlers();
71744d93782SGreg Clayton     StopIOHandlerThread();
71844d93782SGreg Clayton     StopEventHandlerThread();
7191ed54f50SGreg Clayton     m_listener.Clear();
7206611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
7216611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7226611103cSGreg Clayton     {
723ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
724ccbc08e6SGreg Clayton         if (target_sp)
725ccbc08e6SGreg Clayton         {
726ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7276611103cSGreg Clayton             if (process_sp)
7281fd07059SJim Ingham                 process_sp->Finalize();
729ccbc08e6SGreg Clayton             target_sp->Destroy();
7306611103cSGreg Clayton         }
73130fdc8d8SChris Lattner     }
7324bddaeb5SJim Ingham     BroadcasterManager::Clear ();
73330fdc8d8SChris Lattner 
7340d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7350d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
736c5917d9aSJim Ingham     m_terminal_state.Clear();
73744d93782SGreg Clayton     if (m_input_file_sp)
73844d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7390c4129f2SGreg Clayton 
7400c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7418314c525SJim Ingham }
74230fdc8d8SChris Lattner 
74330fdc8d8SChris Lattner bool
744fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
745fc3f027dSGreg Clayton {
74644d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
74744d93782SGreg Clayton     return false;
748fc3f027dSGreg Clayton }
749fc3f027dSGreg Clayton 
750fc3f027dSGreg Clayton void
751fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
752fc3f027dSGreg Clayton {
75344d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
754fc3f027dSGreg Clayton }
755fc3f027dSGreg Clayton 
756fc3f027dSGreg Clayton bool
75730fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
75830fdc8d8SChris Lattner {
7596611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
76030fdc8d8SChris Lattner }
76130fdc8d8SChris Lattner 
76230fdc8d8SChris Lattner void
76330fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
76430fdc8d8SChris Lattner {
7656611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
76630fdc8d8SChris Lattner }
76730fdc8d8SChris Lattner 
76830fdc8d8SChris Lattner 
76930fdc8d8SChris Lattner void
77030fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
77130fdc8d8SChris Lattner {
77244d93782SGreg Clayton     if (m_input_file_sp)
77344d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
77444d93782SGreg Clayton     else
77544d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
77644d93782SGreg Clayton 
77744d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
77851b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
77951b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
78030fdc8d8SChris Lattner 
781c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
782c5917d9aSJim Ingham     SaveInputTerminalState ();
78330fdc8d8SChris Lattner }
78430fdc8d8SChris Lattner 
78530fdc8d8SChris Lattner void
78630fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
78730fdc8d8SChris Lattner {
78844d93782SGreg Clayton     if (m_output_file_sp)
78944d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
79044d93782SGreg Clayton     else
79144d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
79244d93782SGreg Clayton 
79344d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
79451b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
79551b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7962f88aadfSCaroline Tice 
797b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
798b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
799b588726eSEnrico Granata     const bool can_create = false;
800b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
801b588726eSEnrico Granata     if (script_interpreter)
802b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
80330fdc8d8SChris Lattner }
80430fdc8d8SChris Lattner 
80530fdc8d8SChris Lattner void
80630fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
80730fdc8d8SChris Lattner {
80844d93782SGreg Clayton     if (m_error_file_sp)
80944d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
81044d93782SGreg Clayton     else
81144d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
81244d93782SGreg Clayton 
81344d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
81451b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
81551b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
81630fdc8d8SChris Lattner }
81730fdc8d8SChris Lattner 
818c5917d9aSJim Ingham void
819c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
820c5917d9aSJim Ingham {
82144d93782SGreg Clayton     if (m_input_file_sp)
82244d93782SGreg Clayton     {
82344d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
824c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
825c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
826c5917d9aSJim Ingham     }
82744d93782SGreg Clayton }
828c5917d9aSJim Ingham 
829c5917d9aSJim Ingham void
830c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
831c5917d9aSJim Ingham {
832c5917d9aSJim Ingham     m_terminal_state.Restore();
833c5917d9aSJim Ingham }
834c5917d9aSJim Ingham 
83530fdc8d8SChris Lattner ExecutionContext
8362976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
83730fdc8d8SChris Lattner {
83830fdc8d8SChris Lattner     ExecutionContext exe_ctx;
839c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
840c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
84130fdc8d8SChris Lattner 
84230fdc8d8SChris Lattner     if (target_sp)
84330fdc8d8SChris Lattner     {
844c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
845c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
846c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
84730fdc8d8SChris Lattner         {
848c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
849c14ee32dSGreg Clayton             if (thread_sp)
85030fdc8d8SChris Lattner             {
851c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
852c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
853c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
854c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
85530fdc8d8SChris Lattner             }
85630fdc8d8SChris Lattner         }
85730fdc8d8SChris Lattner     }
85830fdc8d8SChris Lattner     return exe_ctx;
85930fdc8d8SChris Lattner }
86030fdc8d8SChris Lattner 
86130fdc8d8SChris Lattner void
862efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
863efed6131SCaroline Tice {
86444d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
86544d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
866efed6131SCaroline Tice     if (reader_sp)
86744d93782SGreg Clayton         reader_sp->Interrupt();
868efed6131SCaroline Tice }
869efed6131SCaroline Tice 
870efed6131SCaroline Tice void
871efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
872efed6131SCaroline Tice {
87344d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
87444d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
875efed6131SCaroline Tice     if (reader_sp)
87644d93782SGreg Clayton         reader_sp->GotEOF();
877efed6131SCaroline Tice }
878efed6131SCaroline Tice 
879efed6131SCaroline Tice void
88044d93782SGreg Clayton Debugger::ClearIOHandlers ()
8813d6086f6SCaroline Tice {
882b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
88344d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
884d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8853d6086f6SCaroline Tice     {
88644d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8873d6086f6SCaroline Tice         if (reader_sp)
8883d6086f6SCaroline Tice         {
88944d93782SGreg Clayton             m_input_reader_stack.Pop();
8903d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
891e68f5d6bSGreg Clayton             reader_sp->Cancel();
8923d6086f6SCaroline Tice         }
8933d6086f6SCaroline Tice     }
8943d6086f6SCaroline Tice }
8953d6086f6SCaroline Tice 
8963d6086f6SCaroline Tice void
8979aaab558SSiva Chandra Debugger::ExecuteIOHandlers()
898969ed3d1SCaroline Tice {
89944d93782SGreg Clayton 
90044d93782SGreg Clayton     while (1)
901969ed3d1SCaroline Tice     {
90244d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
90330fdc8d8SChris Lattner         if (!reader_sp)
90430fdc8d8SChris Lattner             break;
90530fdc8d8SChris Lattner 
90644d93782SGreg Clayton         reader_sp->Activate();
90744d93782SGreg Clayton         reader_sp->Run();
90844d93782SGreg Clayton         reader_sp->Deactivate();
90944d93782SGreg Clayton 
91044d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
91144d93782SGreg Clayton         while (1)
91230fdc8d8SChris Lattner         {
91344d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
91444d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
91544d93782SGreg Clayton                 m_input_reader_stack.Pop();
91630fdc8d8SChris Lattner             else
91730fdc8d8SChris Lattner                 break;
91830fdc8d8SChris Lattner         }
91930fdc8d8SChris Lattner     }
92044d93782SGreg Clayton     ClearIOHandlers();
92144d93782SGreg Clayton }
92230fdc8d8SChris Lattner 
92344d93782SGreg Clayton bool
92444d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
92544d93782SGreg Clayton {
92644d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
92744d93782SGreg Clayton }
92830fdc8d8SChris Lattner 
92944d93782SGreg Clayton 
93044d93782SGreg Clayton ConstString
93144d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
93244d93782SGreg Clayton {
93344d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
93430fdc8d8SChris Lattner }
93530fdc8d8SChris Lattner 
936a487aa4cSKate Stone const char *
937a487aa4cSKate Stone Debugger::GetIOHandlerCommandPrefix()
938a487aa4cSKate Stone {
939a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
940a487aa4cSKate Stone }
941a487aa4cSKate Stone 
942a487aa4cSKate Stone const char *
943a487aa4cSKate Stone Debugger::GetIOHandlerHelpPrologue()
944a487aa4cSKate Stone {
945a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
946a487aa4cSKate Stone }
947a487aa4cSKate Stone 
94830fdc8d8SChris Lattner void
94944d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
95044d93782SGreg Clayton {
95144d93782SGreg Clayton     PushIOHandler (reader_sp);
952577508dfSGreg Clayton 
953577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
954577508dfSGreg Clayton     while (top_reader_sp)
955577508dfSGreg Clayton     {
956577508dfSGreg Clayton         top_reader_sp->Activate();
957577508dfSGreg Clayton         top_reader_sp->Run();
958577508dfSGreg Clayton         top_reader_sp->Deactivate();
959577508dfSGreg Clayton 
960577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
961577508dfSGreg Clayton         {
962577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
963577508dfSGreg Clayton                 break;
964577508dfSGreg Clayton         }
965577508dfSGreg Clayton 
966577508dfSGreg Clayton         while (1)
967577508dfSGreg Clayton         {
968577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
969577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
970577508dfSGreg Clayton                 m_input_reader_stack.Pop();
971577508dfSGreg Clayton             else
972577508dfSGreg Clayton                 break;
973577508dfSGreg Clayton         }
974577508dfSGreg Clayton     }
97544d93782SGreg Clayton }
97644d93782SGreg Clayton 
97744d93782SGreg Clayton void
97844d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
97944d93782SGreg Clayton {
98044d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
98144d93782SGreg Clayton     // This function is called when one ore more of the streams
98244d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
98344d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
98444d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
98544d93782SGreg Clayton 
98644d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
98744d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
98844d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
98944d93782SGreg Clayton     if (!in)
99044d93782SGreg Clayton     {
99144d93782SGreg Clayton         if (top_reader_sp)
99244d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
99344d93782SGreg Clayton         else
99444d93782SGreg Clayton             in = GetInputFile();
99544d93782SGreg Clayton 
99644d93782SGreg Clayton         // If there is nothing, use stdin
99744d93782SGreg Clayton         if (!in)
99844d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
99944d93782SGreg Clayton     }
100044d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
100144d93782SGreg Clayton     if (!out)
100244d93782SGreg Clayton     {
100344d93782SGreg Clayton         if (top_reader_sp)
100444d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
100544d93782SGreg Clayton         else
100644d93782SGreg Clayton             out = GetOutputFile();
100744d93782SGreg Clayton 
100844d93782SGreg Clayton         // If there is nothing, use stdout
100944d93782SGreg Clayton         if (!out)
101044d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
101144d93782SGreg Clayton     }
101244d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
101344d93782SGreg Clayton     if (!err)
101444d93782SGreg Clayton     {
101544d93782SGreg Clayton         if (top_reader_sp)
101644d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
101744d93782SGreg Clayton         else
101844d93782SGreg Clayton             err = GetErrorFile();
101944d93782SGreg Clayton 
102044d93782SGreg Clayton         // If there is nothing, use stderr
102144d93782SGreg Clayton         if (!err)
102244d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
102344d93782SGreg Clayton 
102444d93782SGreg Clayton     }
102544d93782SGreg Clayton }
102644d93782SGreg Clayton 
102744d93782SGreg Clayton void
102844d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
102930fdc8d8SChris Lattner {
103030fdc8d8SChris Lattner     if (!reader_sp)
103130fdc8d8SChris Lattner         return;
1032b44880caSCaroline Tice 
103344d93782SGreg Clayton     // Got the current top input reader...
103444d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1035b44880caSCaroline Tice 
1036b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
1037b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
1038b4874f1aSGreg Clayton     {
103944d93782SGreg Clayton         // Push our new input reader
1040d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
104144d93782SGreg Clayton 
104244d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
104344d93782SGreg Clayton         // and let this new input reader take over
104444d93782SGreg Clayton         if (top_reader_sp)
104544d93782SGreg Clayton             top_reader_sp->Deactivate();
104630fdc8d8SChris Lattner     }
1047b4874f1aSGreg Clayton }
104830fdc8d8SChris Lattner 
104930fdc8d8SChris Lattner bool
105044d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
105130fdc8d8SChris Lattner {
105230fdc8d8SChris Lattner     bool result = false;
105330fdc8d8SChris Lattner 
105444d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
105544d93782SGreg Clayton 
105630fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10576a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
1058d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
105930fdc8d8SChris Lattner     {
106044d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
106130fdc8d8SChris Lattner 
106230fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
106330fdc8d8SChris Lattner         {
106444d93782SGreg Clayton             reader_sp->Deactivate();
1065b4874f1aSGreg Clayton             reader_sp->Cancel();
1066d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
106730fdc8d8SChris Lattner 
1068d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
106930fdc8d8SChris Lattner             if (reader_sp)
107044d93782SGreg Clayton                 reader_sp->Activate();
107144d93782SGreg Clayton 
107244d93782SGreg Clayton             result = true;
107330fdc8d8SChris Lattner         }
107430fdc8d8SChris Lattner     }
107530fdc8d8SChris Lattner     return result;
107630fdc8d8SChris Lattner }
107730fdc8d8SChris Lattner 
107830fdc8d8SChris Lattner bool
107944d93782SGreg Clayton Debugger::HideTopIOHandler()
108030fdc8d8SChris Lattner {
108144d93782SGreg Clayton     Mutex::Locker locker;
108230fdc8d8SChris Lattner 
108344d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
108430fdc8d8SChris Lattner     {
108544d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
108644d93782SGreg Clayton         if (reader_sp)
108744d93782SGreg Clayton             reader_sp->Hide();
108844d93782SGreg Clayton         return true;
108930fdc8d8SChris Lattner     }
109044d93782SGreg Clayton     return false;
109130fdc8d8SChris Lattner }
109230fdc8d8SChris Lattner 
109330fdc8d8SChris Lattner void
109444d93782SGreg Clayton Debugger::RefreshTopIOHandler()
109530fdc8d8SChris Lattner {
109644d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
109744d93782SGreg Clayton     if (reader_sp)
109844d93782SGreg Clayton         reader_sp->Refresh();
109930fdc8d8SChris Lattner }
110044d93782SGreg Clayton 
11016611103cSGreg Clayton 
11025b52f0c7SJim Ingham StreamSP
11035b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
11045b52f0c7SJim Ingham {
11055b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
11065b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
11075b52f0c7SJim Ingham }
11085b52f0c7SJim Ingham 
11095b52f0c7SJim Ingham StreamSP
11105b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
11115b52f0c7SJim Ingham {
11125b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
11135b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
11145b52f0c7SJim Ingham }
11155b52f0c7SJim Ingham 
1116c7bece56SGreg Clayton size_t
1117061858ceSEnrico Granata Debugger::GetNumDebuggers()
1118061858ceSEnrico Granata {
1119*e6e2bb38SZachary Turner     if (lldb_initialized)
1120c15f55e2SGreg Clayton     {
1121061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1122061858ceSEnrico Granata         return GetDebuggerList().size();
1123061858ceSEnrico Granata     }
1124c15f55e2SGreg Clayton     return 0;
1125c15f55e2SGreg Clayton }
1126061858ceSEnrico Granata 
1127061858ceSEnrico Granata lldb::DebuggerSP
1128c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1129061858ceSEnrico Granata {
1130061858ceSEnrico Granata     DebuggerSP debugger_sp;
1131061858ceSEnrico Granata 
1132*e6e2bb38SZachary Turner     if (lldb_initialized)
1133c15f55e2SGreg Clayton     {
1134061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1135061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1136061858ceSEnrico Granata 
1137061858ceSEnrico Granata         if (index < debugger_list.size())
1138061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1139c15f55e2SGreg Clayton     }
1140061858ceSEnrico Granata 
1141061858ceSEnrico Granata     return debugger_sp;
1142061858ceSEnrico Granata }
1143061858ceSEnrico Granata 
1144ebc1bb27SCaroline Tice DebuggerSP
1145ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1146ebc1bb27SCaroline Tice {
11474d122c40SGreg Clayton     DebuggerSP debugger_sp;
1148ebc1bb27SCaroline Tice 
1149*e6e2bb38SZachary Turner     if (lldb_initialized)
1150c15f55e2SGreg Clayton     {
1151ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1152ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1153ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1154ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1155ebc1bb27SCaroline Tice         {
1156ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1157ebc1bb27SCaroline Tice             {
1158ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1159ebc1bb27SCaroline Tice                 break;
1160ebc1bb27SCaroline Tice             }
1161ebc1bb27SCaroline Tice         }
1162c15f55e2SGreg Clayton     }
1163ebc1bb27SCaroline Tice     return debugger_sp;
1164ebc1bb27SCaroline Tice }
11653df9a8dfSCaroline Tice 
11662643b905SSaleem Abdulrasool #if 0
11671b654882SGreg Clayton static void
1168b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11691b654882SGreg Clayton {
11701b654882SGreg Clayton     if (frame == NULL)
11711b654882SGreg Clayton         return;
11721b654882SGreg Clayton 
11731b654882SGreg Clayton     StreamString s;
11741b654882SGreg Clayton     const char *prompt_format =
11751b654882SGreg Clayton     "{addr = '${addr}'\n}"
1176aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1177aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
11781b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11791b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11801b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11811b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11821b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11831b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11841b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11851b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11861b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11871b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11881b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11891b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11901b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11911b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11921b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11931b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11941b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11951b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11961b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11971b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11981b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11991b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
12001b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
12011b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
12021b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
12031b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
12041b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1205aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1206aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
12071b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1208aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1209ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
12101b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1211aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
12121b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
12131b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
12141b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
12151b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
12161b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
12171b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
12181b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
12191b654882SGreg Clayton ;
12201b654882SGreg Clayton 
12211b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
12221b654882SGreg Clayton     ExecutionContext exe_ctx;
12230603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1224c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
12251b654882SGreg Clayton     {
12261b654882SGreg Clayton         printf("%s\n", s.GetData());
12271b654882SGreg Clayton     }
12281b654882SGreg Clayton     else
12291b654882SGreg Clayton     {
12301b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
12311b654882SGreg Clayton     }
12321b654882SGreg Clayton }
12332643b905SSaleem Abdulrasool #endif
12341b654882SGreg Clayton 
1235c3ce7f27SMichael Sartain bool
1236554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
1237aff1b357SJason Molenda                                      const SymbolContext *sc,
1238aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
1239aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
1240aff1b357SJason Molenda                                      const Address *addr,
1241aff1b357SJason Molenda                                      Stream &s)
1242aff1b357SJason Molenda {
1243554f68d3SGreg Clayton     FormatEntity::Entry format_entry;
1244554f68d3SGreg Clayton 
1245554f68d3SGreg Clayton     if (format == NULL)
1246aff1b357SJason Molenda     {
1247554f68d3SGreg Clayton         if (exe_ctx != NULL && exe_ctx->HasTargetScope())
1248aff1b357SJason Molenda             format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1249554f68d3SGreg Clayton         if (format == NULL)
1250554f68d3SGreg Clayton         {
1251554f68d3SGreg Clayton             FormatEntity::Parse("${addr}: ", format_entry);
1252554f68d3SGreg Clayton             format = &format_entry;
1253554f68d3SGreg Clayton         }
1254aff1b357SJason Molenda     }
1255aff1b357SJason Molenda     bool function_changed = false;
1256aff1b357SJason Molenda     bool initial_function = false;
1257aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
1258aff1b357SJason Molenda     {
1259aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
1260aff1b357SJason Molenda         {
1261aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
1262aff1b357SJason Molenda             {
1263aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
1264aff1b357SJason Molenda                 {
1265aff1b357SJason Molenda                     function_changed = true;
1266aff1b357SJason Molenda                 }
1267aff1b357SJason Molenda             }
1268aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
1269aff1b357SJason Molenda             {
1270aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
1271aff1b357SJason Molenda                 {
1272aff1b357SJason Molenda                     function_changed = true;
1273aff1b357SJason Molenda                 }
1274aff1b357SJason Molenda             }
1275aff1b357SJason Molenda         }
1276aff1b357SJason Molenda     }
1277aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
1278aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
1279aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
1280aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
1281aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
1282aff1b357SJason Molenda     {
1283aff1b357SJason Molenda         initial_function = true;
1284aff1b357SJason Molenda     }
1285554f68d3SGreg Clayton     return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function);
1286aff1b357SJason Molenda }
1287aff1b357SJason Molenda 
1288aff1b357SJason Molenda 
1289228063cdSJim Ingham void
1290228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
1291228063cdSJim Ingham {
12924f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
12934f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
12944f02b22dSJim Ingham     // callback.
1295228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
1296228063cdSJim Ingham }
1297228063cdSJim Ingham 
1298228063cdSJim Ingham bool
1299228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
1300228063cdSJim Ingham {
1301228063cdSJim Ingham     Log::Callbacks log_callbacks;
1302228063cdSJim Ingham 
1303228063cdSJim Ingham     StreamSP log_stream_sp;
13049a028519SSean Callanan     if (m_log_callback_stream_sp)
1305228063cdSJim Ingham     {
1306228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
1307228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
1308228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1309228063cdSJim Ingham     }
1310228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
1311228063cdSJim Ingham     {
131244d93782SGreg Clayton         log_stream_sp = GetOutputFile();
1313228063cdSJim Ingham     }
1314228063cdSJim Ingham     else
1315228063cdSJim Ingham     {
1316228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
1317c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
1318c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
1319c1b2ccfdSGreg Clayton         if (!log_stream_sp)
1320228063cdSJim Ingham         {
13218ac06996SPavel Labath             uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate
13228ac06996SPavel Labath                                 | File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
13238ac06996SPavel Labath             if (! (log_options & LLDB_LOG_OPTION_APPEND))
13248ac06996SPavel Labath                 options |= File::eOpenOptionTruncate;
13258ac06996SPavel Labath 
13268ac06996SPavel Labath             log_stream_sp.reset (new StreamFile (log_file, options));
1327228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
1328228063cdSJim Ingham         }
1329228063cdSJim Ingham     }
1330228063cdSJim Ingham     assert (log_stream_sp.get());
1331228063cdSJim Ingham 
1332228063cdSJim Ingham     if (log_options == 0)
1333228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
1334228063cdSJim Ingham 
133557abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
1336228063cdSJim Ingham     {
1337228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
1338228063cdSJim Ingham         return true;
1339228063cdSJim Ingham     }
1340228063cdSJim Ingham     else
1341228063cdSJim Ingham     {
1342228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
1343228063cdSJim Ingham         if (log_channel_sp)
1344228063cdSJim Ingham         {
1345228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
1346228063cdSJim Ingham             {
1347228063cdSJim Ingham                 return true;
1348228063cdSJim Ingham             }
1349228063cdSJim Ingham             else
1350228063cdSJim Ingham             {
1351228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
1352228063cdSJim Ingham                 return false;
1353228063cdSJim Ingham             }
1354228063cdSJim Ingham         }
1355228063cdSJim Ingham         else
1356228063cdSJim Ingham         {
1357228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
1358228063cdSJim Ingham             return false;
1359228063cdSJim Ingham         }
1360228063cdSJim Ingham     }
1361228063cdSJim Ingham     return false;
1362228063cdSJim Ingham }
1363228063cdSJim Ingham 
13649585fbfcSGreg Clayton SourceManager &
13659585fbfcSGreg Clayton Debugger::GetSourceManager ()
13669585fbfcSGreg Clayton {
13679585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
13689585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
13699585fbfcSGreg Clayton     return *m_source_manager_ap;
13709585fbfcSGreg Clayton }
13719585fbfcSGreg Clayton 
13729585fbfcSGreg Clayton 
137344d93782SGreg Clayton 
137444d93782SGreg Clayton // This function handles events that were broadcast by the process.
137544d93782SGreg Clayton void
137644d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
137744d93782SGreg Clayton {
137844d93782SGreg Clayton     using namespace lldb;
137944d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
138044d93782SGreg Clayton 
138144d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
138244d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
138344d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
138444d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
138544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
138644d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
138744d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
138844d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
138944d93782SGreg Clayton //    {
139044d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
139144d93782SGreg Clayton //    }
139244d93782SGreg Clayton //
139344d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
139444d93782SGreg Clayton     {
139544d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
139644d93782SGreg Clayton         if (num_new_locations > 0)
139744d93782SGreg Clayton         {
139844d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
139944d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
140044d93782SGreg Clayton             if (output_sp)
140144d93782SGreg Clayton             {
140244d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
140344d93782SGreg Clayton                                   num_new_locations,
140444d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
140544d93782SGreg Clayton                                   breakpoint->GetID());
140644d93782SGreg Clayton                 RefreshTopIOHandler();
140744d93782SGreg Clayton             }
140844d93782SGreg Clayton         }
140944d93782SGreg Clayton     }
141044d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
141144d93782SGreg Clayton //    {
141244d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
141344d93782SGreg Clayton //    }
141444d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
141544d93782SGreg Clayton //    {
141644d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
141744d93782SGreg Clayton //    }
141844d93782SGreg Clayton }
141944d93782SGreg Clayton 
142044d93782SGreg Clayton size_t
142144d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
142244d93782SGreg Clayton {
142344d93782SGreg Clayton     size_t total_bytes = 0;
142444d93782SGreg Clayton     if (stream == NULL)
142544d93782SGreg Clayton         stream = GetOutputFile().get();
142644d93782SGreg Clayton 
142744d93782SGreg Clayton     if (stream)
142844d93782SGreg Clayton     {
142944d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
143044d93782SGreg Clayton         if (process == NULL)
143144d93782SGreg Clayton         {
143244d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
143344d93782SGreg Clayton             if (target_sp)
143444d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
143544d93782SGreg Clayton         }
143644d93782SGreg Clayton         if (process)
143744d93782SGreg Clayton         {
143844d93782SGreg Clayton             Error error;
143944d93782SGreg Clayton             size_t len;
144044d93782SGreg Clayton             char stdio_buffer[1024];
144144d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
144244d93782SGreg Clayton             {
144344d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
144444d93782SGreg Clayton                 total_bytes += len;
144544d93782SGreg Clayton             }
144644d93782SGreg Clayton         }
144744d93782SGreg Clayton         stream->Flush();
144844d93782SGreg Clayton     }
144944d93782SGreg Clayton     return total_bytes;
145044d93782SGreg Clayton }
145144d93782SGreg Clayton 
145244d93782SGreg Clayton size_t
145344d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
145444d93782SGreg Clayton {
145544d93782SGreg Clayton     size_t total_bytes = 0;
145644d93782SGreg Clayton     if (stream == NULL)
145744d93782SGreg Clayton         stream = GetOutputFile().get();
145844d93782SGreg Clayton 
145944d93782SGreg Clayton     if (stream)
146044d93782SGreg Clayton     {
146144d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
146244d93782SGreg Clayton         if (process == NULL)
146344d93782SGreg Clayton         {
146444d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
146544d93782SGreg Clayton             if (target_sp)
146644d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
146744d93782SGreg Clayton         }
146844d93782SGreg Clayton         if (process)
146944d93782SGreg Clayton         {
147044d93782SGreg Clayton             Error error;
147144d93782SGreg Clayton             size_t len;
147244d93782SGreg Clayton             char stdio_buffer[1024];
147344d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
147444d93782SGreg Clayton             {
147544d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
147644d93782SGreg Clayton                 total_bytes += len;
147744d93782SGreg Clayton             }
147844d93782SGreg Clayton         }
147944d93782SGreg Clayton         stream->Flush();
148044d93782SGreg Clayton     }
148144d93782SGreg Clayton     return total_bytes;
148244d93782SGreg Clayton }
148344d93782SGreg Clayton 
1484dc6224e0SGreg Clayton 
148544d93782SGreg Clayton // This function handles events that were broadcast by the process.
148644d93782SGreg Clayton void
148744d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
148844d93782SGreg Clayton {
148944d93782SGreg Clayton     using namespace lldb;
149044d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
149144d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
149244d93782SGreg Clayton 
1493b4874f1aSGreg Clayton     StreamString output_stream;
1494b4874f1aSGreg Clayton     StreamString error_stream;
149544d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
149644d93782SGreg Clayton 
1497b4874f1aSGreg Clayton     if (!gui_enabled)
1498b4874f1aSGreg Clayton     {
1499b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
150044d93782SGreg Clayton         assert (process_sp);
150144d93782SGreg Clayton 
1502b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
150344d93782SGreg Clayton         {
1504b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
150544d93782SGreg Clayton         }
1506b4874f1aSGreg Clayton 
1507b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
150844d93782SGreg Clayton         {
1509b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
151044d93782SGreg Clayton         }
1511b4874f1aSGreg Clayton 
1512b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
151344d93782SGreg Clayton         {
1514dc6224e0SGreg Clayton             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
151544d93782SGreg Clayton         }
1516b4874f1aSGreg Clayton 
1517b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
1518b4874f1aSGreg Clayton         {
1519b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
15206fea17e8SGreg Clayton             bool top_io_handler_hid = false;
15216fea17e8SGreg Clayton 
15226fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
15236fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
1524b4874f1aSGreg Clayton 
1525b4874f1aSGreg Clayton             if (output_stream.GetSize())
1526b4874f1aSGreg Clayton             {
1527b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
1528b4874f1aSGreg Clayton                 if (output_stream_sp)
1529b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
1530b4874f1aSGreg Clayton             }
1531b4874f1aSGreg Clayton 
1532b4874f1aSGreg Clayton             if (error_stream.GetSize())
1533b4874f1aSGreg Clayton             {
1534b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
1535b4874f1aSGreg Clayton                 if (error_stream_sp)
1536b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
153744d93782SGreg Clayton             }
153844d93782SGreg Clayton 
153944d93782SGreg Clayton             if (top_io_handler_hid)
154044d93782SGreg Clayton                 RefreshTopIOHandler();
154144d93782SGreg Clayton         }
154244d93782SGreg Clayton 
1543b4874f1aSGreg Clayton         if (pop_process_io_handler)
1544b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
1545b4874f1aSGreg Clayton     }
1546b4874f1aSGreg Clayton }
1547b4874f1aSGreg Clayton 
154844d93782SGreg Clayton void
154944d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
155044d93782SGreg Clayton {
155144d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
155244d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
155344d93782SGreg Clayton     using namespace lldb;
155444d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
155544d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
155644d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
155744d93782SGreg Clayton     {
155844d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
155944d93782SGreg Clayton         if (thread_sp)
156044d93782SGreg Clayton         {
156144d93782SGreg Clayton             HideTopIOHandler();
156244d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
156344d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
156444d93782SGreg Clayton             RefreshTopIOHandler();
156544d93782SGreg Clayton         }
156644d93782SGreg Clayton     }
156744d93782SGreg Clayton }
156844d93782SGreg Clayton 
156944d93782SGreg Clayton bool
157044d93782SGreg Clayton Debugger::IsForwardingEvents ()
157144d93782SGreg Clayton {
157244d93782SGreg Clayton     return (bool)m_forward_listener_sp;
157344d93782SGreg Clayton }
157444d93782SGreg Clayton 
157544d93782SGreg Clayton void
157644d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
157744d93782SGreg Clayton {
157844d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
157944d93782SGreg Clayton }
158044d93782SGreg Clayton 
158144d93782SGreg Clayton void
158244d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
158344d93782SGreg Clayton {
158444d93782SGreg Clayton     m_forward_listener_sp.reset();
158544d93782SGreg Clayton }
158644d93782SGreg Clayton 
158744d93782SGreg Clayton 
158844d93782SGreg Clayton void
158944d93782SGreg Clayton Debugger::DefaultEventHandler()
159044d93782SGreg Clayton {
159144d93782SGreg Clayton     Listener& listener(GetListener());
159244d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
159344d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
159444d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
159544d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
159644d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
159744d93782SGreg Clayton 
159844d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
159944d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
160044d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
160144d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
160244d93782SGreg Clayton 
160344d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
160444d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
160544d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
160644d93782SGreg Clayton 
160744d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
160844d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
160944d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
161044d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
161144d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
161244d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
161344d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
161444d93782SGreg Clayton 
1615afa91e33SGreg Clayton     // Let the thread that spawned us know that we have started up and
1616afa91e33SGreg Clayton     // that we are now listening to all required events so no events get missed
1617afa91e33SGreg Clayton     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
1618afa91e33SGreg Clayton 
161944d93782SGreg Clayton     bool done = false;
162044d93782SGreg Clayton     while (!done)
162144d93782SGreg Clayton     {
162244d93782SGreg Clayton         EventSP event_sp;
162344d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
162444d93782SGreg Clayton         {
162544d93782SGreg Clayton             if (event_sp)
162644d93782SGreg Clayton             {
162744d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
162844d93782SGreg Clayton                 if (broadcaster)
162944d93782SGreg Clayton                 {
163044d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
163144d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
163244d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
163344d93782SGreg Clayton                     {
163444d93782SGreg Clayton                         HandleProcessEvent (event_sp);
163544d93782SGreg Clayton                     }
163644d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
163744d93782SGreg Clayton                     {
163844d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
163944d93782SGreg Clayton                         {
164044d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
164144d93782SGreg Clayton                         }
164244d93782SGreg Clayton                     }
164344d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
164444d93782SGreg Clayton                     {
164544d93782SGreg Clayton                         HandleThreadEvent (event_sp);
164644d93782SGreg Clayton                     }
164744d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
164844d93782SGreg Clayton                     {
164944d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
165044d93782SGreg Clayton                         {
165144d93782SGreg Clayton                             done = true;
165244d93782SGreg Clayton                         }
165344d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
165444d93782SGreg Clayton                         {
165544d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
165644d93782SGreg Clayton                             if (data && data[0])
165744d93782SGreg Clayton                             {
165844d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
165944d93782SGreg Clayton                                 if (error_sp)
166044d93782SGreg Clayton                                 {
166144d93782SGreg Clayton                                     HideTopIOHandler();
166244d93782SGreg Clayton                                     error_sp->PutCString(data);
166344d93782SGreg Clayton                                     error_sp->Flush();
166444d93782SGreg Clayton                                     RefreshTopIOHandler();
166544d93782SGreg Clayton                                 }
166644d93782SGreg Clayton                             }
166744d93782SGreg Clayton                         }
166844d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
166944d93782SGreg Clayton                         {
167044d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
167144d93782SGreg Clayton                             if (data && data[0])
167244d93782SGreg Clayton                             {
167344d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
167444d93782SGreg Clayton                                 if (output_sp)
167544d93782SGreg Clayton                                 {
167644d93782SGreg Clayton                                     HideTopIOHandler();
167744d93782SGreg Clayton                                     output_sp->PutCString(data);
167844d93782SGreg Clayton                                     output_sp->Flush();
167944d93782SGreg Clayton                                     RefreshTopIOHandler();
168044d93782SGreg Clayton                                 }
168144d93782SGreg Clayton                             }
168244d93782SGreg Clayton                         }
168344d93782SGreg Clayton                     }
168444d93782SGreg Clayton                 }
168544d93782SGreg Clayton 
168644d93782SGreg Clayton                 if (m_forward_listener_sp)
168744d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
168844d93782SGreg Clayton             }
168944d93782SGreg Clayton         }
169044d93782SGreg Clayton     }
169144d93782SGreg Clayton }
169244d93782SGreg Clayton 
169344d93782SGreg Clayton lldb::thread_result_t
169444d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
169544d93782SGreg Clayton {
169644d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
169744d93782SGreg Clayton     return NULL;
169844d93782SGreg Clayton }
169944d93782SGreg Clayton 
170044d93782SGreg Clayton bool
170144d93782SGreg Clayton Debugger::StartEventHandlerThread()
170244d93782SGreg Clayton {
1703acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
1704807b6b32SGreg Clayton     {
1705afa91e33SGreg Clayton         // We must synchronize with the DefaultEventHandler() thread to ensure
1706afa91e33SGreg Clayton         // it is up and running and listening to events before we return from
1707afa91e33SGreg Clayton         // this function. We do this by listening to events for the
1708afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
1709afa91e33SGreg Clayton         Listener listener("lldb.debugger.event-handler");
1710afa91e33SGreg Clayton         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
1711afa91e33SGreg Clayton 
17127c2896a2SZachary Turner         // Use larger 8MB stack for this thread
1713afa91e33SGreg Clayton         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
1714afa91e33SGreg Clayton                                                               this,
1715afa91e33SGreg Clayton                                                               NULL,
17167c2896a2SZachary Turner                                                               g_debugger_event_thread_stack_bytes);
1717afa91e33SGreg Clayton 
1718afa91e33SGreg Clayton         // Make sure DefaultEventHandler() is running and listening to events before we return
1719afa91e33SGreg Clayton         // from this function. We are only listening for events of type
1720afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
1721afa91e33SGreg Clayton         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
1722afa91e33SGreg Clayton         lldb::EventSP event_sp;
1723afa91e33SGreg Clayton         listener.WaitForEvent(NULL, event_sp);
1724807b6b32SGreg Clayton     }
1725acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
172644d93782SGreg Clayton }
172744d93782SGreg Clayton 
172844d93782SGreg Clayton void
172944d93782SGreg Clayton Debugger::StopEventHandlerThread()
173044d93782SGreg Clayton {
1731acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
173244d93782SGreg Clayton     {
173344d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
173439de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
173544d93782SGreg Clayton     }
173644d93782SGreg Clayton }
173744d93782SGreg Clayton 
173844d93782SGreg Clayton 
173944d93782SGreg Clayton lldb::thread_result_t
174044d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
174144d93782SGreg Clayton {
174244d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
17439aaab558SSiva Chandra     debugger->ExecuteIOHandlers();
174444d93782SGreg Clayton     debugger->StopEventHandlerThread();
174544d93782SGreg Clayton     return NULL;
174644d93782SGreg Clayton }
174744d93782SGreg Clayton 
174844d93782SGreg Clayton bool
174944d93782SGreg Clayton Debugger::StartIOHandlerThread()
175044d93782SGreg Clayton {
1751acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
1752807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
1753807b6b32SGreg Clayton                                                             IOHandlerThread,
1754807b6b32SGreg Clayton                                                             this,
1755807b6b32SGreg Clayton                                                             NULL,
1756807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
1757acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
175844d93782SGreg Clayton }
175944d93782SGreg Clayton 
176044d93782SGreg Clayton void
176144d93782SGreg Clayton Debugger::StopIOHandlerThread()
176244d93782SGreg Clayton {
1763acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
176444d93782SGreg Clayton     {
176544d93782SGreg Clayton         if (m_input_file_sp)
176644d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
176739de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
176844d93782SGreg Clayton     }
176944d93782SGreg Clayton }
177044d93782SGreg Clayton 
1771893c932aSJim Ingham Target *
1772893c932aSJim Ingham Debugger::GetDummyTarget()
1773893c932aSJim Ingham {
1774893c932aSJim Ingham     return m_target_list.GetDummyTarget (*this).get();
1775893c932aSJim Ingham }
1776893c932aSJim Ingham 
1777893c932aSJim Ingham Target *
177833df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
1779893c932aSJim Ingham {
178033df7cd3SJim Ingham     Target *target = nullptr;
178133df7cd3SJim Ingham     if (!prefer_dummy)
178233df7cd3SJim Ingham     {
178333df7cd3SJim Ingham         target = m_target_list.GetSelectedTarget().get();
178433df7cd3SJim Ingham         if (target)
178533df7cd3SJim Ingham             return target;
178633df7cd3SJim Ingham     }
1787893c932aSJim Ingham 
1788893c932aSJim Ingham     return GetDummyTarget();
1789893c932aSJim Ingham }
179044d93782SGreg Clayton 
1791