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