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"
4267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4367cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
441f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
451f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
461f746071SGreg Clayton #include "lldb/Symbol/Function.h"
471f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
486d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
49aff1b357SJason Molenda #include "lldb/Target/CPPLanguageRuntime.h"
50aff1b357SJason Molenda #include "lldb/Target/ObjCLanguageRuntime.h"
5130fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
5230fdc8d8SChris Lattner #include "lldb/Target/Process.h"
531b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
545fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h"
551b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5684a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5730fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
585a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5930fdc8d8SChris Lattner 
6058a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h"
6158a559c0SZachary Turner 
6230fdc8d8SChris Lattner using namespace lldb;
6330fdc8d8SChris Lattner using namespace lldb_private;
6430fdc8d8SChris Lattner 
6530fdc8d8SChris Lattner 
661b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
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 
129*c980fa92SJason Molenda // Three parts to this disassembly format specification:
130*c980fa92SJason Molenda //   1. If this is a new function/symbol (no previous symbol/function), print
131*c980fa92SJason Molenda //      dylib`funcname:\n
132*c980fa92SJason Molenda //   2. If this is a symbol context change (different from previous symbol/function), print
133*c980fa92SJason Molenda //      dylib`funcname:\n
134*c980fa92SJason Molenda //   3. print
135*c980fa92SJason Molenda //      address <+offset>:
136*c980fa92SJason 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}>}: "
137*c980fa92SJason Molenda 
138*c980fa92SJason Molenda // gdb's disassembly format can be emulated with
139*c980fa92SJason Molenda // ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
140*c980fa92SJason Molenda 
141*c980fa92SJason Molenda // lldb's original format for disassembly would look like this format string -
142*c980fa92SJason 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}}:
143*c980fa92SJason 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 
1875fb8f797SGreg Clayton Debugger::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 
4082f88aadfSCaroline Tice int
4092f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
4102f88aadfSCaroline Tice {
4112f88aadfSCaroline Tice     return g_shared_debugger_refcount;
4122f88aadfSCaroline Tice }
4132f88aadfSCaroline Tice 
41430fdc8d8SChris Lattner void
4155fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
41630fdc8d8SChris Lattner {
4175fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
418c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
419dbe54508SGreg Clayton         lldb_private::Initialize();
42099d0faf2SGreg Clayton }
42130fdc8d8SChris Lattner 
42230fdc8d8SChris Lattner void
42330fdc8d8SChris Lattner Debugger::Terminate ()
42430fdc8d8SChris Lattner {
4256611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
4266611103cSGreg Clayton     {
42730fdc8d8SChris Lattner         g_shared_debugger_refcount--;
42830fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
42930fdc8d8SChris Lattner         {
430dbe54508SGreg Clayton             lldb_private::WillTerminate();
431dbe54508SGreg Clayton             lldb_private::Terminate();
4326760a517SCaroline Tice 
43399d0faf2SGreg Clayton             // Clear our master list of debugger objects
43499d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
43599d0faf2SGreg Clayton             GetDebuggerList().clear();
43630fdc8d8SChris Lattner         }
4376760a517SCaroline Tice     }
4386760a517SCaroline Tice }
43930fdc8d8SChris Lattner 
44020bd37f7SCaroline Tice void
44120bd37f7SCaroline Tice Debugger::SettingsInitialize ()
44220bd37f7SCaroline Tice {
4436920b52bSGreg Clayton     Target::SettingsInitialize ();
44420bd37f7SCaroline Tice }
44520bd37f7SCaroline Tice 
44620bd37f7SCaroline Tice void
44720bd37f7SCaroline Tice Debugger::SettingsTerminate ()
44820bd37f7SCaroline Tice {
4496920b52bSGreg Clayton     Target::SettingsTerminate ();
45020bd37f7SCaroline Tice }
45120bd37f7SCaroline Tice 
45221dfcd9dSEnrico Granata bool
453e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
45421dfcd9dSEnrico Granata {
4555fb8f797SGreg Clayton     if (g_load_plugin_callback)
456e743c782SEnrico Granata     {
45758a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
45858a559c0SZachary Turner         if (dynlib.isValid())
45921dfcd9dSEnrico Granata         {
46058a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
46121dfcd9dSEnrico Granata             return true;
46221dfcd9dSEnrico Granata         }
4635fb8f797SGreg Clayton     }
4645fb8f797SGreg Clayton     else
4655fb8f797SGreg Clayton     {
4665fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4675fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4685fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4695fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4705fb8f797SGreg Clayton     }
47121dfcd9dSEnrico Granata     return false;
47221dfcd9dSEnrico Granata }
47321dfcd9dSEnrico Granata 
47421dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
47521dfcd9dSEnrico Granata LoadPluginCallback
47621dfcd9dSEnrico Granata (
47721dfcd9dSEnrico Granata  void *baton,
47821dfcd9dSEnrico Granata  FileSpec::FileType file_type,
47921dfcd9dSEnrico Granata  const FileSpec &file_spec
48021dfcd9dSEnrico Granata  )
48121dfcd9dSEnrico Granata {
48221dfcd9dSEnrico Granata     Error error;
48321dfcd9dSEnrico Granata 
48421dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4853cf443ddSMichael Sartain     static ConstString g_solibext("so");
48621dfcd9dSEnrico Granata 
48721dfcd9dSEnrico Granata     if (!baton)
48821dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
48921dfcd9dSEnrico Granata 
49021dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
49121dfcd9dSEnrico Granata 
49221dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
49321dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
49421dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
49521dfcd9dSEnrico Granata     // file type information.
49621dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
49721dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
49821dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
49921dfcd9dSEnrico Granata     {
50021dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
50121dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
50221dfcd9dSEnrico Granata 
5033cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
5043cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
5053cf443ddSMichael Sartain         {
50621dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
5073cf443ddSMichael Sartain         }
50821dfcd9dSEnrico Granata 
509e743c782SEnrico Granata         Error plugin_load_error;
510e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
51121dfcd9dSEnrico Granata 
51221dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
51321dfcd9dSEnrico Granata     }
51421dfcd9dSEnrico Granata 
51521dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
51621dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
51721dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
51821dfcd9dSEnrico Granata     {
51921dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
52021dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
5216a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
52221dfcd9dSEnrico Granata         // information.
52321dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
52421dfcd9dSEnrico Granata     }
52521dfcd9dSEnrico Granata 
52621dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
52721dfcd9dSEnrico Granata }
52821dfcd9dSEnrico Granata 
52921dfcd9dSEnrico Granata void
53021dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
53121dfcd9dSEnrico Granata {
53221dfcd9dSEnrico Granata     FileSpec dir_spec;
53321dfcd9dSEnrico Granata     const bool find_directories = true;
53421dfcd9dSEnrico Granata     const bool find_files = true;
53521dfcd9dSEnrico Granata     const bool find_other = true;
53621dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
53742ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
53821dfcd9dSEnrico Granata     {
53921dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
54021dfcd9dSEnrico Granata         {
54121dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
54221dfcd9dSEnrico Granata                                           find_directories,
54321dfcd9dSEnrico Granata                                           find_files,
54421dfcd9dSEnrico Granata                                           find_other,
54521dfcd9dSEnrico Granata                                           LoadPluginCallback,
54621dfcd9dSEnrico Granata                                           this);
54721dfcd9dSEnrico Granata         }
54821dfcd9dSEnrico Granata     }
54921dfcd9dSEnrico Granata 
55042ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
55121dfcd9dSEnrico Granata     {
55221dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
55321dfcd9dSEnrico Granata         {
55421dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
55521dfcd9dSEnrico Granata                                           find_directories,
55621dfcd9dSEnrico Granata                                           find_files,
55721dfcd9dSEnrico Granata                                           find_other,
55821dfcd9dSEnrico Granata                                           LoadPluginCallback,
55921dfcd9dSEnrico Granata                                           this);
56021dfcd9dSEnrico Granata         }
56121dfcd9dSEnrico Granata     }
562e8cd0c98SGreg Clayton 
563e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
56421dfcd9dSEnrico Granata }
56521dfcd9dSEnrico Granata 
5666611103cSGreg Clayton DebuggerSP
567228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5686611103cSGreg Clayton {
569228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
570c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5716611103cSGreg Clayton     {
5726611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5736611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5746611103cSGreg Clayton     }
57521dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5766611103cSGreg Clayton     return debugger_sp;
5776611103cSGreg Clayton }
5786611103cSGreg Clayton 
579e02657b1SCaroline Tice void
5804d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
581e02657b1SCaroline Tice {
582e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
583e02657b1SCaroline Tice         return;
584e02657b1SCaroline Tice 
5858314c525SJim Ingham     debugger_sp->Clear();
5868314c525SJim Ingham 
587c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
588c15f55e2SGreg Clayton     {
589e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
590e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
591e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
592e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
593e02657b1SCaroline Tice         {
594e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
595e02657b1SCaroline Tice             {
596e02657b1SCaroline Tice                 debugger_list.erase (pos);
597e02657b1SCaroline Tice                 return;
598e02657b1SCaroline Tice             }
599e02657b1SCaroline Tice         }
600e02657b1SCaroline Tice     }
601c15f55e2SGreg Clayton }
602e02657b1SCaroline Tice 
6034d122c40SGreg Clayton DebuggerSP
6043df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
6053df9a8dfSCaroline Tice {
6064d122c40SGreg Clayton     DebuggerSP debugger_sp;
6076920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
6086920b52bSGreg Clayton     {
6096920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6106920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6116920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6126920b52bSGreg Clayton 
6136920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6146920b52bSGreg Clayton         {
6156920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
6166920b52bSGreg Clayton             {
6176920b52bSGreg Clayton                 debugger_sp = *pos;
6186920b52bSGreg Clayton                 break;
6196920b52bSGreg Clayton             }
6206920b52bSGreg Clayton         }
6216920b52bSGreg Clayton     }
6223df9a8dfSCaroline Tice     return debugger_sp;
6233df9a8dfSCaroline Tice }
6246611103cSGreg Clayton 
6256611103cSGreg Clayton TargetSP
6266611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6276611103cSGreg Clayton {
6284d122c40SGreg Clayton     TargetSP target_sp;
629c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
630c15f55e2SGreg Clayton     {
6316611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6326611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6336611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6346611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6356611103cSGreg Clayton         {
6366611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6376611103cSGreg Clayton             if (target_sp)
6386611103cSGreg Clayton                 break;
6396611103cSGreg Clayton         }
640c15f55e2SGreg Clayton     }
6416611103cSGreg Clayton     return target_sp;
6426611103cSGreg Clayton }
6436611103cSGreg Clayton 
644e4e45924SGreg Clayton TargetSP
645e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
646e4e45924SGreg Clayton {
647e4e45924SGreg Clayton     TargetSP target_sp;
648c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
649c15f55e2SGreg Clayton     {
650e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
651e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
652e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
653e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
654e4e45924SGreg Clayton         {
655e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
656e4e45924SGreg Clayton             if (target_sp)
657e4e45924SGreg Clayton                 break;
658e4e45924SGreg Clayton         }
659c15f55e2SGreg Clayton     }
660e4e45924SGreg Clayton     return target_sp;
661e4e45924SGreg Clayton }
662e4e45924SGreg Clayton 
663e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
664e6481c7eSJason Molenda     UserID(g_unique_id++),
665e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
666e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
667e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
668e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
669e6481c7eSJason Molenda     m_terminal_state(),
670e6481c7eSJason Molenda     m_target_list(*this),
671e6481c7eSJason Molenda     m_platform_list(),
672e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
673e6481c7eSJason Molenda     m_source_manager_ap(),
674e6481c7eSJason Molenda     m_source_file_cache(),
675e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
676e6481c7eSJason Molenda     m_input_reader_stack(),
677e6481c7eSJason Molenda     m_instance_name(),
678afa91e33SGreg Clayton     m_loaded_plugins(),
679afa91e33SGreg Clayton     m_event_handler_thread (),
680afa91e33SGreg Clayton     m_io_handler_thread (),
681afa91e33SGreg Clayton     m_sync_broadcaster (NULL, "lldb.debugger.sync")
68230fdc8d8SChris Lattner {
68367cc0636SGreg Clayton     char instance_cstr[256];
68467cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
68567cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
686228063cdSJim Ingham     if (log_callback)
687228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6886611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
689ded470d3SGreg Clayton     // Always add our default platform to the platform list
690615eb7e6SGreg Clayton     PlatformSP default_platform_sp (Platform::GetHostPlatform());
691ded470d3SGreg Clayton     assert (default_platform_sp.get());
692ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
69367cc0636SGreg Clayton 
694754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
69567cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
69667cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
69767cc0636SGreg Clayton                                      true,
69867cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
699754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
700754a9369SGreg Clayton     {
701754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
702754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
703754a9369SGreg Clayton                                          true,
704754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
705754a9369SGreg Clayton     }
70667cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
70767cc0636SGreg Clayton     term_width->SetMinimumValue(10);
70867cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
709c3ce7f27SMichael Sartain 
710c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
711c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
712c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
713c3ce7f27SMichael Sartain         SetUseColor (false);
71430fdc8d8SChris Lattner }
71530fdc8d8SChris Lattner 
71630fdc8d8SChris Lattner Debugger::~Debugger ()
71730fdc8d8SChris Lattner {
7188314c525SJim Ingham     Clear();
7198314c525SJim Ingham }
7208314c525SJim Ingham 
7218314c525SJim Ingham void
7228314c525SJim Ingham Debugger::Clear()
7238314c525SJim Ingham {
72444d93782SGreg Clayton     ClearIOHandlers();
72544d93782SGreg Clayton     StopIOHandlerThread();
72644d93782SGreg Clayton     StopEventHandlerThread();
7271ed54f50SGreg Clayton     m_listener.Clear();
7286611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
7296611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7306611103cSGreg Clayton     {
731ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
732ccbc08e6SGreg Clayton         if (target_sp)
733ccbc08e6SGreg Clayton         {
734ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7356611103cSGreg Clayton             if (process_sp)
7361fd07059SJim Ingham                 process_sp->Finalize();
737ccbc08e6SGreg Clayton             target_sp->Destroy();
7386611103cSGreg Clayton         }
73930fdc8d8SChris Lattner     }
7404bddaeb5SJim Ingham     BroadcasterManager::Clear ();
74130fdc8d8SChris Lattner 
7420d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7430d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
744c5917d9aSJim Ingham     m_terminal_state.Clear();
74544d93782SGreg Clayton     if (m_input_file_sp)
74644d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7470c4129f2SGreg Clayton 
7480c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7498314c525SJim Ingham }
75030fdc8d8SChris Lattner 
75130fdc8d8SChris Lattner bool
752fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
753fc3f027dSGreg Clayton {
75444d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
75544d93782SGreg Clayton     return false;
756fc3f027dSGreg Clayton }
757fc3f027dSGreg Clayton 
758fc3f027dSGreg Clayton void
759fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
760fc3f027dSGreg Clayton {
76144d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
762fc3f027dSGreg Clayton }
763fc3f027dSGreg Clayton 
764fc3f027dSGreg Clayton bool
76530fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
76630fdc8d8SChris Lattner {
7676611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
76830fdc8d8SChris Lattner }
76930fdc8d8SChris Lattner 
77030fdc8d8SChris Lattner void
77130fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
77230fdc8d8SChris Lattner {
7736611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
77430fdc8d8SChris Lattner }
77530fdc8d8SChris Lattner 
77630fdc8d8SChris Lattner 
77730fdc8d8SChris Lattner void
77830fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
77930fdc8d8SChris Lattner {
78044d93782SGreg Clayton     if (m_input_file_sp)
78144d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
78244d93782SGreg Clayton     else
78344d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
78444d93782SGreg Clayton 
78544d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
78651b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
78751b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
78830fdc8d8SChris Lattner 
789c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
790c5917d9aSJim Ingham     SaveInputTerminalState ();
79130fdc8d8SChris Lattner }
79230fdc8d8SChris Lattner 
79330fdc8d8SChris Lattner void
79430fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
79530fdc8d8SChris Lattner {
79644d93782SGreg Clayton     if (m_output_file_sp)
79744d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
79844d93782SGreg Clayton     else
79944d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
80044d93782SGreg Clayton 
80144d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
80251b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
80351b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
8042f88aadfSCaroline Tice 
805b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
806b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
807b588726eSEnrico Granata     const bool can_create = false;
808b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
809b588726eSEnrico Granata     if (script_interpreter)
810b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
81130fdc8d8SChris Lattner }
81230fdc8d8SChris Lattner 
81330fdc8d8SChris Lattner void
81430fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
81530fdc8d8SChris Lattner {
81644d93782SGreg Clayton     if (m_error_file_sp)
81744d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
81844d93782SGreg Clayton     else
81944d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
82044d93782SGreg Clayton 
82144d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
82251b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
82351b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
82430fdc8d8SChris Lattner }
82530fdc8d8SChris Lattner 
826c5917d9aSJim Ingham void
827c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
828c5917d9aSJim Ingham {
82944d93782SGreg Clayton     if (m_input_file_sp)
83044d93782SGreg Clayton     {
83144d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
832c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
833c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
834c5917d9aSJim Ingham     }
83544d93782SGreg Clayton }
836c5917d9aSJim Ingham 
837c5917d9aSJim Ingham void
838c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
839c5917d9aSJim Ingham {
840c5917d9aSJim Ingham     m_terminal_state.Restore();
841c5917d9aSJim Ingham }
842c5917d9aSJim Ingham 
84330fdc8d8SChris Lattner ExecutionContext
8442976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
84530fdc8d8SChris Lattner {
84630fdc8d8SChris Lattner     ExecutionContext exe_ctx;
847c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
848c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
84930fdc8d8SChris Lattner 
85030fdc8d8SChris Lattner     if (target_sp)
85130fdc8d8SChris Lattner     {
852c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
853c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
854c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
85530fdc8d8SChris Lattner         {
856c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
857c14ee32dSGreg Clayton             if (thread_sp)
85830fdc8d8SChris Lattner             {
859c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
860c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
861c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
862c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
86330fdc8d8SChris Lattner             }
86430fdc8d8SChris Lattner         }
86530fdc8d8SChris Lattner     }
86630fdc8d8SChris Lattner     return exe_ctx;
86730fdc8d8SChris Lattner }
86830fdc8d8SChris Lattner 
86930fdc8d8SChris Lattner void
870efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
871efed6131SCaroline Tice {
87244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
87344d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
874efed6131SCaroline Tice     if (reader_sp)
87544d93782SGreg Clayton         reader_sp->Interrupt();
876efed6131SCaroline Tice }
877efed6131SCaroline Tice 
878efed6131SCaroline Tice void
879efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
880efed6131SCaroline Tice {
88144d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
88244d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
883efed6131SCaroline Tice     if (reader_sp)
88444d93782SGreg Clayton         reader_sp->GotEOF();
885efed6131SCaroline Tice }
886efed6131SCaroline Tice 
887efed6131SCaroline Tice void
88844d93782SGreg Clayton Debugger::ClearIOHandlers ()
8893d6086f6SCaroline Tice {
890b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
89144d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
892d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8933d6086f6SCaroline Tice     {
89444d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8953d6086f6SCaroline Tice         if (reader_sp)
8963d6086f6SCaroline Tice         {
89744d93782SGreg Clayton             m_input_reader_stack.Pop();
8983d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
899e68f5d6bSGreg Clayton             reader_sp->Cancel();
9003d6086f6SCaroline Tice         }
9013d6086f6SCaroline Tice     }
9023d6086f6SCaroline Tice }
9033d6086f6SCaroline Tice 
9043d6086f6SCaroline Tice void
90544d93782SGreg Clayton Debugger::ExecuteIOHanders()
906969ed3d1SCaroline Tice {
90744d93782SGreg Clayton 
90844d93782SGreg Clayton     while (1)
909969ed3d1SCaroline Tice     {
91044d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
91130fdc8d8SChris Lattner         if (!reader_sp)
91230fdc8d8SChris Lattner             break;
91330fdc8d8SChris Lattner 
91444d93782SGreg Clayton         reader_sp->Activate();
91544d93782SGreg Clayton         reader_sp->Run();
91644d93782SGreg Clayton         reader_sp->Deactivate();
91744d93782SGreg Clayton 
91844d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
91944d93782SGreg Clayton         while (1)
92030fdc8d8SChris Lattner         {
92144d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
92244d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
92344d93782SGreg Clayton                 m_input_reader_stack.Pop();
92430fdc8d8SChris Lattner             else
92530fdc8d8SChris Lattner                 break;
92630fdc8d8SChris Lattner         }
92730fdc8d8SChris Lattner     }
92844d93782SGreg Clayton     ClearIOHandlers();
92944d93782SGreg Clayton }
93030fdc8d8SChris Lattner 
93144d93782SGreg Clayton bool
93244d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
93344d93782SGreg Clayton {
93444d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
93544d93782SGreg Clayton }
93630fdc8d8SChris Lattner 
93744d93782SGreg Clayton 
93844d93782SGreg Clayton ConstString
93944d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
94044d93782SGreg Clayton {
94144d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
94230fdc8d8SChris Lattner }
94330fdc8d8SChris Lattner 
944a487aa4cSKate Stone const char *
945a487aa4cSKate Stone Debugger::GetIOHandlerCommandPrefix()
946a487aa4cSKate Stone {
947a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
948a487aa4cSKate Stone }
949a487aa4cSKate Stone 
950a487aa4cSKate Stone const char *
951a487aa4cSKate Stone Debugger::GetIOHandlerHelpPrologue()
952a487aa4cSKate Stone {
953a487aa4cSKate Stone     return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
954a487aa4cSKate Stone }
955a487aa4cSKate Stone 
95630fdc8d8SChris Lattner void
95744d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
95844d93782SGreg Clayton {
95944d93782SGreg Clayton     PushIOHandler (reader_sp);
960577508dfSGreg Clayton 
961577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
962577508dfSGreg Clayton     while (top_reader_sp)
963577508dfSGreg Clayton     {
964577508dfSGreg Clayton         top_reader_sp->Activate();
965577508dfSGreg Clayton         top_reader_sp->Run();
966577508dfSGreg Clayton         top_reader_sp->Deactivate();
967577508dfSGreg Clayton 
968577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
969577508dfSGreg Clayton         {
970577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
971577508dfSGreg Clayton                 break;
972577508dfSGreg Clayton         }
973577508dfSGreg Clayton 
974577508dfSGreg Clayton         while (1)
975577508dfSGreg Clayton         {
976577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
977577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
978577508dfSGreg Clayton                 m_input_reader_stack.Pop();
979577508dfSGreg Clayton             else
980577508dfSGreg Clayton                 break;
981577508dfSGreg Clayton         }
982577508dfSGreg Clayton     }
98344d93782SGreg Clayton }
98444d93782SGreg Clayton 
98544d93782SGreg Clayton void
98644d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
98744d93782SGreg Clayton {
98844d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
98944d93782SGreg Clayton     // This function is called when one ore more of the streams
99044d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
99144d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
99244d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
99344d93782SGreg Clayton 
99444d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
99544d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
99644d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
99744d93782SGreg Clayton     if (!in)
99844d93782SGreg Clayton     {
99944d93782SGreg Clayton         if (top_reader_sp)
100044d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
100144d93782SGreg Clayton         else
100244d93782SGreg Clayton             in = GetInputFile();
100344d93782SGreg Clayton 
100444d93782SGreg Clayton         // If there is nothing, use stdin
100544d93782SGreg Clayton         if (!in)
100644d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
100744d93782SGreg Clayton     }
100844d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
100944d93782SGreg Clayton     if (!out)
101044d93782SGreg Clayton     {
101144d93782SGreg Clayton         if (top_reader_sp)
101244d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
101344d93782SGreg Clayton         else
101444d93782SGreg Clayton             out = GetOutputFile();
101544d93782SGreg Clayton 
101644d93782SGreg Clayton         // If there is nothing, use stdout
101744d93782SGreg Clayton         if (!out)
101844d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
101944d93782SGreg Clayton     }
102044d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
102144d93782SGreg Clayton     if (!err)
102244d93782SGreg Clayton     {
102344d93782SGreg Clayton         if (top_reader_sp)
102444d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
102544d93782SGreg Clayton         else
102644d93782SGreg Clayton             err = GetErrorFile();
102744d93782SGreg Clayton 
102844d93782SGreg Clayton         // If there is nothing, use stderr
102944d93782SGreg Clayton         if (!err)
103044d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
103144d93782SGreg Clayton 
103244d93782SGreg Clayton     }
103344d93782SGreg Clayton }
103444d93782SGreg Clayton 
103544d93782SGreg Clayton void
103644d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
103730fdc8d8SChris Lattner {
103830fdc8d8SChris Lattner     if (!reader_sp)
103930fdc8d8SChris Lattner         return;
1040b44880caSCaroline Tice 
104144d93782SGreg Clayton     // Got the current top input reader...
104244d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1043b44880caSCaroline Tice 
1044b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
1045b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
1046b4874f1aSGreg Clayton     {
104744d93782SGreg Clayton         // Push our new input reader
1048d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
104944d93782SGreg Clayton 
105044d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
105144d93782SGreg Clayton         // and let this new input reader take over
105244d93782SGreg Clayton         if (top_reader_sp)
105344d93782SGreg Clayton             top_reader_sp->Deactivate();
105430fdc8d8SChris Lattner     }
1055b4874f1aSGreg Clayton }
105630fdc8d8SChris Lattner 
105730fdc8d8SChris Lattner bool
105844d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
105930fdc8d8SChris Lattner {
106030fdc8d8SChris Lattner     bool result = false;
106130fdc8d8SChris Lattner 
106244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
106344d93782SGreg Clayton 
106430fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10656a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
1066d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
106730fdc8d8SChris Lattner     {
106844d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
106930fdc8d8SChris Lattner 
107030fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
107130fdc8d8SChris Lattner         {
107244d93782SGreg Clayton             reader_sp->Deactivate();
1073b4874f1aSGreg Clayton             reader_sp->Cancel();
1074d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
107530fdc8d8SChris Lattner 
1076d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
107730fdc8d8SChris Lattner             if (reader_sp)
107844d93782SGreg Clayton                 reader_sp->Activate();
107944d93782SGreg Clayton 
108044d93782SGreg Clayton             result = true;
108130fdc8d8SChris Lattner         }
108230fdc8d8SChris Lattner     }
108330fdc8d8SChris Lattner     return result;
108430fdc8d8SChris Lattner }
108530fdc8d8SChris Lattner 
108630fdc8d8SChris Lattner bool
108744d93782SGreg Clayton Debugger::HideTopIOHandler()
108830fdc8d8SChris Lattner {
108944d93782SGreg Clayton     Mutex::Locker locker;
109030fdc8d8SChris Lattner 
109144d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
109230fdc8d8SChris Lattner     {
109344d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
109444d93782SGreg Clayton         if (reader_sp)
109544d93782SGreg Clayton             reader_sp->Hide();
109644d93782SGreg Clayton         return true;
109730fdc8d8SChris Lattner     }
109844d93782SGreg Clayton     return false;
109930fdc8d8SChris Lattner }
110030fdc8d8SChris Lattner 
110130fdc8d8SChris Lattner void
110244d93782SGreg Clayton Debugger::RefreshTopIOHandler()
110330fdc8d8SChris Lattner {
110444d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
110544d93782SGreg Clayton     if (reader_sp)
110644d93782SGreg Clayton         reader_sp->Refresh();
110730fdc8d8SChris Lattner }
110844d93782SGreg Clayton 
11096611103cSGreg Clayton 
11105b52f0c7SJim Ingham StreamSP
11115b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
11125b52f0c7SJim Ingham {
11135b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
11145b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
11155b52f0c7SJim Ingham }
11165b52f0c7SJim Ingham 
11175b52f0c7SJim Ingham StreamSP
11185b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
11195b52f0c7SJim Ingham {
11205b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
11215b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
11225b52f0c7SJim Ingham }
11235b52f0c7SJim Ingham 
1124c7bece56SGreg Clayton size_t
1125061858ceSEnrico Granata Debugger::GetNumDebuggers()
1126061858ceSEnrico Granata {
1127c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1128c15f55e2SGreg Clayton     {
1129061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1130061858ceSEnrico Granata         return GetDebuggerList().size();
1131061858ceSEnrico Granata     }
1132c15f55e2SGreg Clayton     return 0;
1133c15f55e2SGreg Clayton }
1134061858ceSEnrico Granata 
1135061858ceSEnrico Granata lldb::DebuggerSP
1136c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1137061858ceSEnrico Granata {
1138061858ceSEnrico Granata     DebuggerSP debugger_sp;
1139061858ceSEnrico Granata 
1140c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1141c15f55e2SGreg Clayton     {
1142061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1143061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1144061858ceSEnrico Granata 
1145061858ceSEnrico Granata         if (index < debugger_list.size())
1146061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1147c15f55e2SGreg Clayton     }
1148061858ceSEnrico Granata 
1149061858ceSEnrico Granata     return debugger_sp;
1150061858ceSEnrico Granata }
1151061858ceSEnrico Granata 
1152ebc1bb27SCaroline Tice DebuggerSP
1153ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1154ebc1bb27SCaroline Tice {
11554d122c40SGreg Clayton     DebuggerSP debugger_sp;
1156ebc1bb27SCaroline Tice 
1157c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1158c15f55e2SGreg Clayton     {
1159ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1160ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1161ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1162ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1163ebc1bb27SCaroline Tice         {
1164ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1165ebc1bb27SCaroline Tice             {
1166ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1167ebc1bb27SCaroline Tice                 break;
1168ebc1bb27SCaroline Tice             }
1169ebc1bb27SCaroline Tice         }
1170c15f55e2SGreg Clayton     }
1171ebc1bb27SCaroline Tice     return debugger_sp;
1172ebc1bb27SCaroline Tice }
11733df9a8dfSCaroline Tice 
11742643b905SSaleem Abdulrasool #if 0
11751b654882SGreg Clayton static void
1176b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11771b654882SGreg Clayton {
11781b654882SGreg Clayton     if (frame == NULL)
11791b654882SGreg Clayton         return;
11801b654882SGreg Clayton 
11811b654882SGreg Clayton     StreamString s;
11821b654882SGreg Clayton     const char *prompt_format =
11831b654882SGreg Clayton     "{addr = '${addr}'\n}"
1184aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1185aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
11861b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11871b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11881b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11891b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11901b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11911b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11921b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11931b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11941b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11951b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11961b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11971b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11981b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11991b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
12001b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
12011b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
12021b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
12031b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
12041b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
12051b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
12061b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
12071b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
12081b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
12091b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
12101b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
12111b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
12121b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1213aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1214aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
12151b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1216aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1217ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
12181b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1219aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
12201b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
12211b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
12221b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
12231b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
12241b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
12251b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
12261b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
12271b654882SGreg Clayton ;
12281b654882SGreg Clayton 
12291b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
12301b654882SGreg Clayton     ExecutionContext exe_ctx;
12310603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1232c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
12331b654882SGreg Clayton     {
12341b654882SGreg Clayton         printf("%s\n", s.GetData());
12351b654882SGreg Clayton     }
12361b654882SGreg Clayton     else
12371b654882SGreg Clayton     {
12381b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
12391b654882SGreg Clayton     }
12401b654882SGreg Clayton }
12412643b905SSaleem Abdulrasool #endif
12421b654882SGreg Clayton 
1243c3ce7f27SMichael Sartain bool
1244554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
1245aff1b357SJason Molenda                                      const SymbolContext *sc,
1246aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
1247aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
1248aff1b357SJason Molenda                                      const Address *addr,
1249aff1b357SJason Molenda                                      Stream &s)
1250aff1b357SJason Molenda {
1251554f68d3SGreg Clayton     FormatEntity::Entry format_entry;
1252554f68d3SGreg Clayton 
1253554f68d3SGreg Clayton     if (format == NULL)
1254aff1b357SJason Molenda     {
1255554f68d3SGreg Clayton         if (exe_ctx != NULL && exe_ctx->HasTargetScope())
1256aff1b357SJason Molenda             format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1257554f68d3SGreg Clayton         if (format == NULL)
1258554f68d3SGreg Clayton         {
1259554f68d3SGreg Clayton             FormatEntity::Parse("${addr}: ", format_entry);
1260554f68d3SGreg Clayton             format = &format_entry;
1261554f68d3SGreg Clayton         }
1262aff1b357SJason Molenda     }
1263aff1b357SJason Molenda     bool function_changed = false;
1264aff1b357SJason Molenda     bool initial_function = false;
1265aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
1266aff1b357SJason Molenda     {
1267aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
1268aff1b357SJason Molenda         {
1269aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
1270aff1b357SJason Molenda             {
1271aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
1272aff1b357SJason Molenda                 {
1273aff1b357SJason Molenda                     function_changed = true;
1274aff1b357SJason Molenda                 }
1275aff1b357SJason Molenda             }
1276aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
1277aff1b357SJason Molenda             {
1278aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
1279aff1b357SJason Molenda                 {
1280aff1b357SJason Molenda                     function_changed = true;
1281aff1b357SJason Molenda                 }
1282aff1b357SJason Molenda             }
1283aff1b357SJason Molenda         }
1284aff1b357SJason Molenda     }
1285aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
1286aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
1287aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
1288aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
1289aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
1290aff1b357SJason Molenda     {
1291aff1b357SJason Molenda         initial_function = true;
1292aff1b357SJason Molenda     }
1293554f68d3SGreg Clayton     return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function);
1294aff1b357SJason Molenda }
1295aff1b357SJason Molenda 
1296aff1b357SJason Molenda 
1297228063cdSJim Ingham void
1298228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
1299228063cdSJim Ingham {
13004f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
13014f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
13024f02b22dSJim Ingham     // callback.
1303228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
1304228063cdSJim Ingham }
1305228063cdSJim Ingham 
1306228063cdSJim Ingham bool
1307228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
1308228063cdSJim Ingham {
1309228063cdSJim Ingham     Log::Callbacks log_callbacks;
1310228063cdSJim Ingham 
1311228063cdSJim Ingham     StreamSP log_stream_sp;
13129a028519SSean Callanan     if (m_log_callback_stream_sp)
1313228063cdSJim Ingham     {
1314228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
1315228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
1316228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1317228063cdSJim Ingham     }
1318228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
1319228063cdSJim Ingham     {
132044d93782SGreg Clayton         log_stream_sp = GetOutputFile();
1321228063cdSJim Ingham     }
1322228063cdSJim Ingham     else
1323228063cdSJim Ingham     {
1324228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
1325c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
1326c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
1327c1b2ccfdSGreg Clayton         if (!log_stream_sp)
1328228063cdSJim Ingham         {
1329228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
1330228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
1331228063cdSJim Ingham         }
1332228063cdSJim Ingham     }
1333228063cdSJim Ingham     assert (log_stream_sp.get());
1334228063cdSJim Ingham 
1335228063cdSJim Ingham     if (log_options == 0)
1336228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
1337228063cdSJim Ingham 
133857abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
1339228063cdSJim Ingham     {
1340228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
1341228063cdSJim Ingham         return true;
1342228063cdSJim Ingham     }
1343228063cdSJim Ingham     else
1344228063cdSJim Ingham     {
1345228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
1346228063cdSJim Ingham         if (log_channel_sp)
1347228063cdSJim Ingham         {
1348228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
1349228063cdSJim Ingham             {
1350228063cdSJim Ingham                 return true;
1351228063cdSJim Ingham             }
1352228063cdSJim Ingham             else
1353228063cdSJim Ingham             {
1354228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
1355228063cdSJim Ingham                 return false;
1356228063cdSJim Ingham             }
1357228063cdSJim Ingham         }
1358228063cdSJim Ingham         else
1359228063cdSJim Ingham         {
1360228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
1361228063cdSJim Ingham             return false;
1362228063cdSJim Ingham         }
1363228063cdSJim Ingham     }
1364228063cdSJim Ingham     return false;
1365228063cdSJim Ingham }
1366228063cdSJim Ingham 
13679585fbfcSGreg Clayton SourceManager &
13689585fbfcSGreg Clayton Debugger::GetSourceManager ()
13699585fbfcSGreg Clayton {
13709585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
13719585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
13729585fbfcSGreg Clayton     return *m_source_manager_ap;
13739585fbfcSGreg Clayton }
13749585fbfcSGreg Clayton 
13759585fbfcSGreg Clayton 
137644d93782SGreg Clayton 
137744d93782SGreg Clayton // This function handles events that were broadcast by the process.
137844d93782SGreg Clayton void
137944d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
138044d93782SGreg Clayton {
138144d93782SGreg Clayton     using namespace lldb;
138244d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
138344d93782SGreg Clayton 
138444d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
138544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
138644d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
138744d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
138844d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
138944d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
139044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
139144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
139244d93782SGreg Clayton //    {
139344d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
139444d93782SGreg Clayton //    }
139544d93782SGreg Clayton //
139644d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
139744d93782SGreg Clayton     {
139844d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
139944d93782SGreg Clayton         if (num_new_locations > 0)
140044d93782SGreg Clayton         {
140144d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
140244d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
140344d93782SGreg Clayton             if (output_sp)
140444d93782SGreg Clayton             {
140544d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
140644d93782SGreg Clayton                                   num_new_locations,
140744d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
140844d93782SGreg Clayton                                   breakpoint->GetID());
140944d93782SGreg Clayton                 RefreshTopIOHandler();
141044d93782SGreg Clayton             }
141144d93782SGreg Clayton         }
141244d93782SGreg Clayton     }
141344d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
141444d93782SGreg Clayton //    {
141544d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
141644d93782SGreg Clayton //    }
141744d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
141844d93782SGreg Clayton //    {
141944d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
142044d93782SGreg Clayton //    }
142144d93782SGreg Clayton }
142244d93782SGreg Clayton 
142344d93782SGreg Clayton size_t
142444d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
142544d93782SGreg Clayton {
142644d93782SGreg Clayton     size_t total_bytes = 0;
142744d93782SGreg Clayton     if (stream == NULL)
142844d93782SGreg Clayton         stream = GetOutputFile().get();
142944d93782SGreg Clayton 
143044d93782SGreg Clayton     if (stream)
143144d93782SGreg Clayton     {
143244d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
143344d93782SGreg Clayton         if (process == NULL)
143444d93782SGreg Clayton         {
143544d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
143644d93782SGreg Clayton             if (target_sp)
143744d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
143844d93782SGreg Clayton         }
143944d93782SGreg Clayton         if (process)
144044d93782SGreg Clayton         {
144144d93782SGreg Clayton             Error error;
144244d93782SGreg Clayton             size_t len;
144344d93782SGreg Clayton             char stdio_buffer[1024];
144444d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
144544d93782SGreg Clayton             {
144644d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
144744d93782SGreg Clayton                 total_bytes += len;
144844d93782SGreg Clayton             }
144944d93782SGreg Clayton         }
145044d93782SGreg Clayton         stream->Flush();
145144d93782SGreg Clayton     }
145244d93782SGreg Clayton     return total_bytes;
145344d93782SGreg Clayton }
145444d93782SGreg Clayton 
145544d93782SGreg Clayton size_t
145644d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
145744d93782SGreg Clayton {
145844d93782SGreg Clayton     size_t total_bytes = 0;
145944d93782SGreg Clayton     if (stream == NULL)
146044d93782SGreg Clayton         stream = GetOutputFile().get();
146144d93782SGreg Clayton 
146244d93782SGreg Clayton     if (stream)
146344d93782SGreg Clayton     {
146444d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
146544d93782SGreg Clayton         if (process == NULL)
146644d93782SGreg Clayton         {
146744d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
146844d93782SGreg Clayton             if (target_sp)
146944d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
147044d93782SGreg Clayton         }
147144d93782SGreg Clayton         if (process)
147244d93782SGreg Clayton         {
147344d93782SGreg Clayton             Error error;
147444d93782SGreg Clayton             size_t len;
147544d93782SGreg Clayton             char stdio_buffer[1024];
147644d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
147744d93782SGreg Clayton             {
147844d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
147944d93782SGreg Clayton                 total_bytes += len;
148044d93782SGreg Clayton             }
148144d93782SGreg Clayton         }
148244d93782SGreg Clayton         stream->Flush();
148344d93782SGreg Clayton     }
148444d93782SGreg Clayton     return total_bytes;
148544d93782SGreg Clayton }
148644d93782SGreg Clayton 
1487dc6224e0SGreg Clayton 
148844d93782SGreg Clayton // This function handles events that were broadcast by the process.
148944d93782SGreg Clayton void
149044d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
149144d93782SGreg Clayton {
149244d93782SGreg Clayton     using namespace lldb;
149344d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
149444d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
149544d93782SGreg Clayton 
1496b4874f1aSGreg Clayton     StreamString output_stream;
1497b4874f1aSGreg Clayton     StreamString error_stream;
149844d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
149944d93782SGreg Clayton 
1500b4874f1aSGreg Clayton     if (!gui_enabled)
1501b4874f1aSGreg Clayton     {
1502b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
150344d93782SGreg Clayton         assert (process_sp);
150444d93782SGreg Clayton 
1505b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
150644d93782SGreg Clayton         {
1507b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
150844d93782SGreg Clayton         }
1509b4874f1aSGreg Clayton 
1510b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
151144d93782SGreg Clayton         {
1512b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
151344d93782SGreg Clayton         }
1514b4874f1aSGreg Clayton 
1515b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
151644d93782SGreg Clayton         {
1517dc6224e0SGreg Clayton             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
151844d93782SGreg Clayton         }
1519b4874f1aSGreg Clayton 
1520b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
1521b4874f1aSGreg Clayton         {
1522b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
15236fea17e8SGreg Clayton             bool top_io_handler_hid = false;
15246fea17e8SGreg Clayton 
15256fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
15266fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
1527b4874f1aSGreg Clayton 
1528b4874f1aSGreg Clayton             if (output_stream.GetSize())
1529b4874f1aSGreg Clayton             {
1530b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
1531b4874f1aSGreg Clayton                 if (output_stream_sp)
1532b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
1533b4874f1aSGreg Clayton             }
1534b4874f1aSGreg Clayton 
1535b4874f1aSGreg Clayton             if (error_stream.GetSize())
1536b4874f1aSGreg Clayton             {
1537b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
1538b4874f1aSGreg Clayton                 if (error_stream_sp)
1539b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
154044d93782SGreg Clayton             }
154144d93782SGreg Clayton 
154244d93782SGreg Clayton             if (top_io_handler_hid)
154344d93782SGreg Clayton                 RefreshTopIOHandler();
154444d93782SGreg Clayton         }
154544d93782SGreg Clayton 
1546b4874f1aSGreg Clayton         if (pop_process_io_handler)
1547b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
1548b4874f1aSGreg Clayton     }
1549b4874f1aSGreg Clayton }
1550b4874f1aSGreg Clayton 
155144d93782SGreg Clayton void
155244d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
155344d93782SGreg Clayton {
155444d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
155544d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
155644d93782SGreg Clayton     using namespace lldb;
155744d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
155844d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
155944d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
156044d93782SGreg Clayton     {
156144d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
156244d93782SGreg Clayton         if (thread_sp)
156344d93782SGreg Clayton         {
156444d93782SGreg Clayton             HideTopIOHandler();
156544d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
156644d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
156744d93782SGreg Clayton             RefreshTopIOHandler();
156844d93782SGreg Clayton         }
156944d93782SGreg Clayton     }
157044d93782SGreg Clayton }
157144d93782SGreg Clayton 
157244d93782SGreg Clayton bool
157344d93782SGreg Clayton Debugger::IsForwardingEvents ()
157444d93782SGreg Clayton {
157544d93782SGreg Clayton     return (bool)m_forward_listener_sp;
157644d93782SGreg Clayton }
157744d93782SGreg Clayton 
157844d93782SGreg Clayton void
157944d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
158044d93782SGreg Clayton {
158144d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
158244d93782SGreg Clayton }
158344d93782SGreg Clayton 
158444d93782SGreg Clayton void
158544d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
158644d93782SGreg Clayton {
158744d93782SGreg Clayton     m_forward_listener_sp.reset();
158844d93782SGreg Clayton }
158944d93782SGreg Clayton 
159044d93782SGreg Clayton 
159144d93782SGreg Clayton void
159244d93782SGreg Clayton Debugger::DefaultEventHandler()
159344d93782SGreg Clayton {
159444d93782SGreg Clayton     Listener& listener(GetListener());
159544d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
159644d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
159744d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
159844d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
159944d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
160044d93782SGreg Clayton 
160144d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
160244d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
160344d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
160444d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
160544d93782SGreg Clayton 
160644d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
160744d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
160844d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
160944d93782SGreg Clayton 
161044d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
161144d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
161244d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
161344d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
161444d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
161544d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
161644d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
161744d93782SGreg Clayton 
1618afa91e33SGreg Clayton     // Let the thread that spawned us know that we have started up and
1619afa91e33SGreg Clayton     // that we are now listening to all required events so no events get missed
1620afa91e33SGreg Clayton     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
1621afa91e33SGreg Clayton 
162244d93782SGreg Clayton     bool done = false;
162344d93782SGreg Clayton     while (!done)
162444d93782SGreg Clayton     {
162544d93782SGreg Clayton         EventSP event_sp;
162644d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
162744d93782SGreg Clayton         {
162844d93782SGreg Clayton             if (event_sp)
162944d93782SGreg Clayton             {
163044d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
163144d93782SGreg Clayton                 if (broadcaster)
163244d93782SGreg Clayton                 {
163344d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
163444d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
163544d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
163644d93782SGreg Clayton                     {
163744d93782SGreg Clayton                         HandleProcessEvent (event_sp);
163844d93782SGreg Clayton                     }
163944d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
164044d93782SGreg Clayton                     {
164144d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
164244d93782SGreg Clayton                         {
164344d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
164444d93782SGreg Clayton                         }
164544d93782SGreg Clayton                     }
164644d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
164744d93782SGreg Clayton                     {
164844d93782SGreg Clayton                         HandleThreadEvent (event_sp);
164944d93782SGreg Clayton                     }
165044d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
165144d93782SGreg Clayton                     {
165244d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
165344d93782SGreg Clayton                         {
165444d93782SGreg Clayton                             done = true;
165544d93782SGreg Clayton                         }
165644d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
165744d93782SGreg Clayton                         {
165844d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
165944d93782SGreg Clayton                             if (data && data[0])
166044d93782SGreg Clayton                             {
166144d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
166244d93782SGreg Clayton                                 if (error_sp)
166344d93782SGreg Clayton                                 {
166444d93782SGreg Clayton                                     HideTopIOHandler();
166544d93782SGreg Clayton                                     error_sp->PutCString(data);
166644d93782SGreg Clayton                                     error_sp->Flush();
166744d93782SGreg Clayton                                     RefreshTopIOHandler();
166844d93782SGreg Clayton                                 }
166944d93782SGreg Clayton                             }
167044d93782SGreg Clayton                         }
167144d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
167244d93782SGreg Clayton                         {
167344d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
167444d93782SGreg Clayton                             if (data && data[0])
167544d93782SGreg Clayton                             {
167644d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
167744d93782SGreg Clayton                                 if (output_sp)
167844d93782SGreg Clayton                                 {
167944d93782SGreg Clayton                                     HideTopIOHandler();
168044d93782SGreg Clayton                                     output_sp->PutCString(data);
168144d93782SGreg Clayton                                     output_sp->Flush();
168244d93782SGreg Clayton                                     RefreshTopIOHandler();
168344d93782SGreg Clayton                                 }
168444d93782SGreg Clayton                             }
168544d93782SGreg Clayton                         }
168644d93782SGreg Clayton                     }
168744d93782SGreg Clayton                 }
168844d93782SGreg Clayton 
168944d93782SGreg Clayton                 if (m_forward_listener_sp)
169044d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
169144d93782SGreg Clayton             }
169244d93782SGreg Clayton         }
169344d93782SGreg Clayton     }
169444d93782SGreg Clayton }
169544d93782SGreg Clayton 
169644d93782SGreg Clayton lldb::thread_result_t
169744d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
169844d93782SGreg Clayton {
169944d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
170044d93782SGreg Clayton     return NULL;
170144d93782SGreg Clayton }
170244d93782SGreg Clayton 
170344d93782SGreg Clayton bool
170444d93782SGreg Clayton Debugger::StartEventHandlerThread()
170544d93782SGreg Clayton {
1706acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
1707807b6b32SGreg Clayton     {
1708afa91e33SGreg Clayton         // We must synchronize with the DefaultEventHandler() thread to ensure
1709afa91e33SGreg Clayton         // it is up and running and listening to events before we return from
1710afa91e33SGreg Clayton         // this function. We do this by listening to events for the
1711afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
1712afa91e33SGreg Clayton         Listener listener("lldb.debugger.event-handler");
1713afa91e33SGreg Clayton         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
1714afa91e33SGreg Clayton 
17157c2896a2SZachary Turner         // Use larger 8MB stack for this thread
1716afa91e33SGreg Clayton         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
1717afa91e33SGreg Clayton                                                               this,
1718afa91e33SGreg Clayton                                                               NULL,
17197c2896a2SZachary Turner                                                               g_debugger_event_thread_stack_bytes);
1720afa91e33SGreg Clayton 
1721afa91e33SGreg Clayton         // Make sure DefaultEventHandler() is running and listening to events before we return
1722afa91e33SGreg Clayton         // from this function. We are only listening for events of type
1723afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
1724afa91e33SGreg Clayton         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
1725afa91e33SGreg Clayton         lldb::EventSP event_sp;
1726afa91e33SGreg Clayton         listener.WaitForEvent(NULL, event_sp);
1727807b6b32SGreg Clayton     }
1728acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
172944d93782SGreg Clayton }
173044d93782SGreg Clayton 
173144d93782SGreg Clayton void
173244d93782SGreg Clayton Debugger::StopEventHandlerThread()
173344d93782SGreg Clayton {
1734acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
173544d93782SGreg Clayton     {
173644d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
173739de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
173844d93782SGreg Clayton     }
173944d93782SGreg Clayton }
174044d93782SGreg Clayton 
174144d93782SGreg Clayton 
174244d93782SGreg Clayton lldb::thread_result_t
174344d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
174444d93782SGreg Clayton {
174544d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
174644d93782SGreg Clayton     debugger->ExecuteIOHanders();
174744d93782SGreg Clayton     debugger->StopEventHandlerThread();
174844d93782SGreg Clayton     return NULL;
174944d93782SGreg Clayton }
175044d93782SGreg Clayton 
175144d93782SGreg Clayton bool
175244d93782SGreg Clayton Debugger::StartIOHandlerThread()
175344d93782SGreg Clayton {
1754acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
1755807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
1756807b6b32SGreg Clayton                                                             IOHandlerThread,
1757807b6b32SGreg Clayton                                                             this,
1758807b6b32SGreg Clayton                                                             NULL,
1759807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
1760acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
176144d93782SGreg Clayton }
176244d93782SGreg Clayton 
176344d93782SGreg Clayton void
176444d93782SGreg Clayton Debugger::StopIOHandlerThread()
176544d93782SGreg Clayton {
1766acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
176744d93782SGreg Clayton     {
176844d93782SGreg Clayton         if (m_input_file_sp)
176944d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
177039de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
177144d93782SGreg Clayton     }
177244d93782SGreg Clayton }
177344d93782SGreg Clayton 
1774893c932aSJim Ingham Target *
1775893c932aSJim Ingham Debugger::GetDummyTarget()
1776893c932aSJim Ingham {
1777893c932aSJim Ingham     return m_target_list.GetDummyTarget (*this).get();
1778893c932aSJim Ingham }
1779893c932aSJim Ingham 
1780893c932aSJim Ingham Target *
178133df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
1782893c932aSJim Ingham {
178333df7cd3SJim Ingham     Target *target = nullptr;
178433df7cd3SJim Ingham     if (!prefer_dummy)
178533df7cd3SJim Ingham     {
178633df7cd3SJim Ingham         target = m_target_list.GetSelectedTarget().get();
178733df7cd3SJim Ingham         if (target)
178833df7cd3SJim Ingham             return target;
178933df7cd3SJim Ingham     }
1790893c932aSJim Ingham 
1791893c932aSJim Ingham     return GetDummyTarget();
1792893c932aSJim Ingham }
179344d93782SGreg Clayton 
1794