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