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