130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 124a33d318SGreg Clayton #include "lldb/Core/Debugger.h" 134a33d318SGreg Clayton 144a33d318SGreg Clayton #include <map> 154a33d318SGreg Clayton 164becb37eSEnrico Granata #include "clang/AST/DeclCXX.h" 174becb37eSEnrico Granata #include "clang/AST/Type.h" 18705b1809SJason Molenda #include "llvm/ADT/StringRef.h" 194becb37eSEnrico Granata 2030fdc8d8SChris Lattner #include "lldb/lldb-private.h" 21554f68d3SGreg Clayton #include "lldb/Core/FormatEntity.h" 221f746071SGreg Clayton #include "lldb/Core/Module.h" 23e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h" 247349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 2530fdc8d8SChris Lattner #include "lldb/Core/State.h" 265b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h" 27228063cdSJim Ingham #include "lldb/Core/StreamCallback.h" 2844d93782SGreg Clayton #include "lldb/Core/StreamFile.h" 291b654882SGreg Clayton #include "lldb/Core/StreamString.h" 30705b1809SJason Molenda #include "lldb/Core/StructuredData.h" 3130fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 324becb37eSEnrico Granata #include "lldb/Core/ValueObject.h" 336d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 345548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 355548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h" 36894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h" 3793a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h" 3842ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h" 39a3406614SGreg Clayton #include "lldb/Host/Terminal.h" 4039de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h" 416611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 4267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h" 4367cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 441f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h" 451f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 461f746071SGreg Clayton #include "lldb/Symbol/Function.h" 471f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 486d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h" 49aff1b357SJason Molenda #include "lldb/Target/CPPLanguageRuntime.h" 50aff1b357SJason Molenda #include "lldb/Target/ObjCLanguageRuntime.h" 5130fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 5230fdc8d8SChris Lattner #include "lldb/Target/Process.h" 531b654882SGreg Clayton #include "lldb/Target/RegisterContext.h" 545fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h" 551b654882SGreg Clayton #include "lldb/Target/StopInfo.h" 5684a53dfbSEnrico Granata #include "lldb/Target/Target.h" 5730fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 585a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h" 5930fdc8d8SChris Lattner 6058a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h" 6158a559c0SZachary Turner 6230fdc8d8SChris Lattner using namespace lldb; 6330fdc8d8SChris Lattner using namespace lldb_private; 6430fdc8d8SChris Lattner 6530fdc8d8SChris Lattner 661b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0; 67ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1; 687c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024; 69ebc1bb27SCaroline Tice 701b654882SGreg Clayton #pragma mark Static Functions 711b654882SGreg Clayton 721b654882SGreg Clayton static Mutex & 731b654882SGreg Clayton GetDebuggerListMutex () 741b654882SGreg Clayton { 751b654882SGreg Clayton static Mutex g_mutex(Mutex::eMutexTypeRecursive); 761b654882SGreg Clayton return g_mutex; 771b654882SGreg Clayton } 781b654882SGreg Clayton 791b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList; 801b654882SGreg Clayton 811b654882SGreg Clayton static DebuggerList & 821b654882SGreg Clayton GetDebuggerList() 831b654882SGreg Clayton { 841b654882SGreg Clayton // hide the static debugger list inside a singleton accessor to avoid 856a7f3338SBruce Mitchener // global init constructors 861b654882SGreg Clayton static DebuggerList g_list; 871b654882SGreg Clayton return g_list; 881b654882SGreg Clayton } 89e372b98dSGreg Clayton 90e372b98dSGreg Clayton OptionEnumValueElement 9167cc0636SGreg Clayton g_show_disassembly_enum_values[] = 92e372b98dSGreg Clayton { 9367cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, 9467cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, 9567cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, 96e372b98dSGreg Clayton { 0, NULL, NULL } 97e372b98dSGreg Clayton }; 98e372b98dSGreg Clayton 9967cc0636SGreg Clayton OptionEnumValueElement 10067cc0636SGreg Clayton g_language_enumerators[] = 10167cc0636SGreg Clayton { 10267cc0636SGreg Clayton { eScriptLanguageNone, "none", "Disable scripting languages."}, 10367cc0636SGreg Clayton { eScriptLanguagePython, "python", "Select python as the default scripting language."}, 10467cc0636SGreg Clayton { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."}, 105a12993c9SGreg Clayton { 0, NULL, NULL } 10667cc0636SGreg Clayton }; 107e372b98dSGreg Clayton 10867cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" 10967cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 11067cc0636SGreg Clayton 1110769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ 11267cc0636SGreg Clayton "{, ${frame.pc}}"\ 11367cc0636SGreg Clayton MODULE_WITH_FUNC\ 11467cc0636SGreg Clayton FILE_AND_LINE\ 1150769b2b1SMichael Sartain "{, name = '${thread.name}'}"\ 1160769b2b1SMichael Sartain "{, queue = '${thread.queue}'}"\ 117705b1809SJason Molenda "{, activity = '${thread.info.activity.name}'}" \ 118705b1809SJason Molenda "{, ${thread.info.trace_messages} messages}" \ 11967cc0636SGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 12067cc0636SGreg Clayton "{\\nReturn value: ${thread.return-value}}"\ 12130fadafeSJim Ingham "{\\nCompleted expression: ${thread.completed-expression}}"\ 12267cc0636SGreg Clayton "\\n" 12367cc0636SGreg Clayton 12467cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 12567cc0636SGreg Clayton MODULE_WITH_FUNC\ 12667cc0636SGreg Clayton FILE_AND_LINE\ 12767cc0636SGreg Clayton "\\n" 12867cc0636SGreg Clayton 129*c980fa92SJason Molenda // Three parts to this disassembly format specification: 130*c980fa92SJason Molenda // 1. If this is a new function/symbol (no previous symbol/function), print 131*c980fa92SJason Molenda // dylib`funcname:\n 132*c980fa92SJason Molenda // 2. If this is a symbol context change (different from previous symbol/function), print 133*c980fa92SJason Molenda // dylib`funcname:\n 134*c980fa92SJason Molenda // 3. print 135*c980fa92SJason Molenda // address <+offset>: 136*c980fa92SJason Molenda #define DEFAULT_DISASSEMBLY_FORMAT "{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: " 137*c980fa92SJason Molenda 138*c980fa92SJason Molenda // gdb's disassembly format can be emulated with 139*c980fa92SJason Molenda // ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: 140*c980fa92SJason Molenda 141*c980fa92SJason Molenda // lldb's original format for disassembly would look like this format string - 142*c980fa92SJason Molenda // {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: 143*c980fa92SJason Molenda 14467cc0636SGreg Clayton 145754a9369SGreg Clayton static PropertyDefinition 146754a9369SGreg Clayton g_properties[] = 14767cc0636SGreg Clayton { 14867cc0636SGreg Clayton { "auto-confirm", OptionValue::eTypeBoolean , true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, 149554f68d3SGreg Clayton { "disassembly-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." }, 150554f68d3SGreg Clayton { "frame-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." }, 15167cc0636SGreg Clayton { "notify-void", OptionValue::eTypeBoolean , true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, 1524c05410fSGreg Clayton { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 15367cc0636SGreg Clayton { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 15467cc0636SGreg Clayton { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, 15567cc0636SGreg Clayton { "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." }, 15667cc0636SGreg Clayton { "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." }, 15767cc0636SGreg Clayton { "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." }, 15867cc0636SGreg Clayton { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, 159554f68d3SGreg Clayton { "thread-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." }, 16067cc0636SGreg Clayton { "use-external-editor", OptionValue::eTypeBoolean , true, false, NULL, NULL, "Whether to use an external editor or not." }, 161c3ce7f27SMichael Sartain { "use-color", OptionValue::eTypeBoolean , true, true , NULL, NULL, "Whether to use Ansi color codes or not." }, 16290a8db30SEnrico Granata { "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." }, 163ebdc1ac0SEnrico Granata { "escape-non-printables", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." }, 16467cc0636SGreg Clayton { NULL, OptionValue::eTypeInvalid , true, 0 , NULL, NULL, NULL } 16567cc0636SGreg Clayton }; 16667cc0636SGreg Clayton 16767cc0636SGreg Clayton enum 16867cc0636SGreg Clayton { 16967cc0636SGreg Clayton ePropertyAutoConfirm = 0, 170aff1b357SJason Molenda ePropertyDisassemblyFormat, 17167cc0636SGreg Clayton ePropertyFrameFormat, 17267cc0636SGreg Clayton ePropertyNotiftVoid, 17367cc0636SGreg Clayton ePropertyPrompt, 17467cc0636SGreg Clayton ePropertyScriptLanguage, 17567cc0636SGreg Clayton ePropertyStopDisassemblyCount, 17667cc0636SGreg Clayton ePropertyStopDisassemblyDisplay, 17767cc0636SGreg Clayton ePropertyStopLineCountAfter, 17867cc0636SGreg Clayton ePropertyStopLineCountBefore, 17967cc0636SGreg Clayton ePropertyTerminalWidth, 18067cc0636SGreg Clayton ePropertyThreadFormat, 181c3ce7f27SMichael Sartain ePropertyUseExternalEditor, 182c3ce7f27SMichael Sartain ePropertyUseColor, 183ebdc1ac0SEnrico Granata ePropertyAutoOneLineSummaries, 184ebdc1ac0SEnrico Granata ePropertyEscapeNonPrintables 18567cc0636SGreg Clayton }; 18667cc0636SGreg Clayton 1875fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL; 1884c05410fSGreg Clayton 1894c05410fSGreg Clayton Error 1904c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 1914c05410fSGreg Clayton VarSetOperationType op, 1924c05410fSGreg Clayton const char *property_path, 1934c05410fSGreg Clayton const char *value) 1944c05410fSGreg Clayton { 19584a53dfbSEnrico Granata bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0; 196ebdc1ac0SEnrico Granata bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0; 19784a53dfbSEnrico Granata TargetSP target_sp; 198397ddd5fSEnrico Granata LoadScriptFromSymFile load_script_old_value; 19984a53dfbSEnrico Granata if (is_load_script && exe_ctx->GetTargetSP()) 20084a53dfbSEnrico Granata { 20184a53dfbSEnrico Granata target_sp = exe_ctx->GetTargetSP(); 20284a53dfbSEnrico Granata load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 20384a53dfbSEnrico Granata } 2044c05410fSGreg Clayton Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 2054c05410fSGreg Clayton if (error.Success()) 2064c05410fSGreg Clayton { 20784a53dfbSEnrico Granata // FIXME it would be nice to have "on-change" callbacks for properties 2084c05410fSGreg Clayton if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 2094c05410fSGreg Clayton { 2104c05410fSGreg Clayton const char *new_prompt = GetPrompt(); 211c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 212c3ce7f27SMichael Sartain if (str.length()) 213c3ce7f27SMichael Sartain new_prompt = str.c_str(); 21444d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 2154c05410fSGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 2164c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 2174c05410fSGreg Clayton } 218c3ce7f27SMichael Sartain else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0) 219c3ce7f27SMichael Sartain { 220c3ce7f27SMichael Sartain // use-color changed. Ping the prompt so it can reset the ansi terminal codes. 221c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 222c3ce7f27SMichael Sartain } 223397ddd5fSEnrico Granata else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) 22484a53dfbSEnrico Granata { 225397ddd5fSEnrico Granata if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue) 22684a53dfbSEnrico Granata { 22784a53dfbSEnrico Granata std::list<Error> errors; 2289730339bSEnrico Granata StreamString feedback_stream; 2299730339bSEnrico Granata if (!target_sp->LoadScriptingResources(errors,&feedback_stream)) 23084a53dfbSEnrico Granata { 23144d93782SGreg Clayton StreamFileSP stream_sp (GetErrorFile()); 23244d93782SGreg Clayton if (stream_sp) 23344d93782SGreg Clayton { 23484a53dfbSEnrico Granata for (auto error : errors) 23584a53dfbSEnrico Granata { 23644d93782SGreg Clayton stream_sp->Printf("%s\n",error.AsCString()); 23784a53dfbSEnrico Granata } 2389730339bSEnrico Granata if (feedback_stream.GetSize()) 23944d93782SGreg Clayton stream_sp->Printf("%s",feedback_stream.GetData()); 24044d93782SGreg Clayton } 24184a53dfbSEnrico Granata } 24284a53dfbSEnrico Granata } 24384a53dfbSEnrico Granata } 244ebdc1ac0SEnrico Granata else if (is_escape_non_printables) 245ebdc1ac0SEnrico Granata { 246ebdc1ac0SEnrico Granata DataVisualization::ForceUpdate(); 247ebdc1ac0SEnrico Granata } 2484c05410fSGreg Clayton } 2494c05410fSGreg Clayton return error; 2504c05410fSGreg Clayton } 2514c05410fSGreg Clayton 25267cc0636SGreg Clayton bool 25367cc0636SGreg Clayton Debugger::GetAutoConfirm () const 25467cc0636SGreg Clayton { 25567cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 256754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 25767cc0636SGreg Clayton } 25867cc0636SGreg Clayton 259554f68d3SGreg Clayton const FormatEntity::Entry * 260aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const 261aff1b357SJason Molenda { 262aff1b357SJason Molenda const uint32_t idx = ePropertyDisassemblyFormat; 263554f68d3SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx); 264aff1b357SJason Molenda } 265aff1b357SJason Molenda 266554f68d3SGreg Clayton const FormatEntity::Entry * 26767cc0636SGreg Clayton Debugger::GetFrameFormat() const 26867cc0636SGreg Clayton { 26967cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 270554f68d3SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx); 27167cc0636SGreg Clayton } 27267cc0636SGreg Clayton 27367cc0636SGreg Clayton bool 27467cc0636SGreg Clayton Debugger::GetNotifyVoid () const 27567cc0636SGreg Clayton { 27667cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 277754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 27867cc0636SGreg Clayton } 27967cc0636SGreg Clayton 28067cc0636SGreg Clayton const char * 28167cc0636SGreg Clayton Debugger::GetPrompt() const 28267cc0636SGreg Clayton { 28367cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 284754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 28567cc0636SGreg Clayton } 28667cc0636SGreg Clayton 28767cc0636SGreg Clayton void 28867cc0636SGreg Clayton Debugger::SetPrompt(const char *p) 28967cc0636SGreg Clayton { 29067cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 29167cc0636SGreg Clayton m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 29267cc0636SGreg Clayton const char *new_prompt = GetPrompt(); 293c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 294c3ce7f27SMichael Sartain if (str.length()) 295c3ce7f27SMichael Sartain new_prompt = str.c_str(); 29644d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 29767cc0636SGreg Clayton } 29867cc0636SGreg Clayton 299554f68d3SGreg Clayton const FormatEntity::Entry * 30067cc0636SGreg Clayton Debugger::GetThreadFormat() const 30167cc0636SGreg Clayton { 30267cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 303554f68d3SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx); 30467cc0636SGreg Clayton } 30567cc0636SGreg Clayton 30667cc0636SGreg Clayton lldb::ScriptLanguage 30767cc0636SGreg Clayton Debugger::GetScriptLanguage() const 30867cc0636SGreg Clayton { 30967cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 310754a9369SGreg Clayton return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 31167cc0636SGreg Clayton } 31267cc0636SGreg Clayton 31367cc0636SGreg Clayton bool 31467cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 31567cc0636SGreg Clayton { 31667cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 31767cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 31867cc0636SGreg Clayton } 31967cc0636SGreg Clayton 32067cc0636SGreg Clayton uint32_t 32167cc0636SGreg Clayton Debugger::GetTerminalWidth () const 32267cc0636SGreg Clayton { 32367cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 324754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 32567cc0636SGreg Clayton } 32667cc0636SGreg Clayton 32767cc0636SGreg Clayton bool 32867cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width) 32967cc0636SGreg Clayton { 33067cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 33167cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 33267cc0636SGreg Clayton } 33367cc0636SGreg Clayton 33467cc0636SGreg Clayton bool 33567cc0636SGreg Clayton Debugger::GetUseExternalEditor () const 33667cc0636SGreg Clayton { 33767cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 338754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 33967cc0636SGreg Clayton } 34067cc0636SGreg Clayton 34167cc0636SGreg Clayton bool 34267cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b) 34367cc0636SGreg Clayton { 34467cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 34567cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 34667cc0636SGreg Clayton } 34767cc0636SGreg Clayton 348c3ce7f27SMichael Sartain bool 349c3ce7f27SMichael Sartain Debugger::GetUseColor () const 350c3ce7f27SMichael Sartain { 351c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 352c3ce7f27SMichael Sartain return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 353c3ce7f27SMichael Sartain } 354c3ce7f27SMichael Sartain 355c3ce7f27SMichael Sartain bool 356c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b) 357c3ce7f27SMichael Sartain { 358c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 359c3ce7f27SMichael Sartain bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 360c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 361c3ce7f27SMichael Sartain return ret; 362c3ce7f27SMichael Sartain } 363c3ce7f27SMichael Sartain 36467cc0636SGreg Clayton uint32_t 36567cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const 36667cc0636SGreg Clayton { 36767cc0636SGreg Clayton const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 368754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 36967cc0636SGreg Clayton } 37067cc0636SGreg Clayton 37167cc0636SGreg Clayton Debugger::StopDisassemblyType 37267cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const 37367cc0636SGreg Clayton { 37467cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 375754a9369SGreg Clayton return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 37667cc0636SGreg Clayton } 37767cc0636SGreg Clayton 37867cc0636SGreg Clayton uint32_t 37967cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const 38067cc0636SGreg Clayton { 38167cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 382754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 38367cc0636SGreg Clayton } 384e372b98dSGreg Clayton 385553fad5cSEnrico Granata bool 38690a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const 387553fad5cSEnrico Granata { 38890a8db30SEnrico Granata const uint32_t idx = ePropertyAutoOneLineSummaries; 389553fad5cSEnrico Granata return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); 390ebdc1ac0SEnrico Granata } 391553fad5cSEnrico Granata 392ebdc1ac0SEnrico Granata bool 393ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const 394ebdc1ac0SEnrico Granata { 395ebdc1ac0SEnrico Granata const uint32_t idx = ePropertyEscapeNonPrintables; 396ebdc1ac0SEnrico Granata return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); 397553fad5cSEnrico Granata } 398553fad5cSEnrico Granata 3991b654882SGreg Clayton #pragma mark Debugger 4001b654882SGreg Clayton 40167cc0636SGreg Clayton //const DebuggerPropertiesSP & 40267cc0636SGreg Clayton //Debugger::GetSettings() const 40367cc0636SGreg Clayton //{ 40467cc0636SGreg Clayton // return m_properties_sp; 40567cc0636SGreg Clayton //} 40667cc0636SGreg Clayton // 40799d0faf2SGreg Clayton 4082f88aadfSCaroline Tice int 4092f88aadfSCaroline Tice Debugger::TestDebuggerRefCount () 4102f88aadfSCaroline Tice { 4112f88aadfSCaroline Tice return g_shared_debugger_refcount; 4122f88aadfSCaroline Tice } 4132f88aadfSCaroline Tice 41430fdc8d8SChris Lattner void 4155fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback) 41630fdc8d8SChris Lattner { 4175fb8f797SGreg Clayton g_load_plugin_callback = load_plugin_callback; 418c15f55e2SGreg Clayton if (g_shared_debugger_refcount++ == 0) 419dbe54508SGreg Clayton lldb_private::Initialize(); 42099d0faf2SGreg Clayton } 42130fdc8d8SChris Lattner 42230fdc8d8SChris Lattner void 42330fdc8d8SChris Lattner Debugger::Terminate () 42430fdc8d8SChris Lattner { 4256611103cSGreg Clayton if (g_shared_debugger_refcount > 0) 4266611103cSGreg Clayton { 42730fdc8d8SChris Lattner g_shared_debugger_refcount--; 42830fdc8d8SChris Lattner if (g_shared_debugger_refcount == 0) 42930fdc8d8SChris Lattner { 430dbe54508SGreg Clayton lldb_private::WillTerminate(); 431dbe54508SGreg Clayton lldb_private::Terminate(); 4326760a517SCaroline Tice 43399d0faf2SGreg Clayton // Clear our master list of debugger objects 43499d0faf2SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 43599d0faf2SGreg Clayton GetDebuggerList().clear(); 43630fdc8d8SChris Lattner } 4376760a517SCaroline Tice } 4386760a517SCaroline Tice } 43930fdc8d8SChris Lattner 44020bd37f7SCaroline Tice void 44120bd37f7SCaroline Tice Debugger::SettingsInitialize () 44220bd37f7SCaroline Tice { 4436920b52bSGreg Clayton Target::SettingsInitialize (); 44420bd37f7SCaroline Tice } 44520bd37f7SCaroline Tice 44620bd37f7SCaroline Tice void 44720bd37f7SCaroline Tice Debugger::SettingsTerminate () 44820bd37f7SCaroline Tice { 4496920b52bSGreg Clayton Target::SettingsTerminate (); 45020bd37f7SCaroline Tice } 45120bd37f7SCaroline Tice 45221dfcd9dSEnrico Granata bool 453e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error) 45421dfcd9dSEnrico Granata { 4555fb8f797SGreg Clayton if (g_load_plugin_callback) 456e743c782SEnrico Granata { 45758a559c0SZachary Turner llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error); 45858a559c0SZachary Turner if (dynlib.isValid()) 45921dfcd9dSEnrico Granata { 46058a559c0SZachary Turner m_loaded_plugins.push_back(dynlib); 46121dfcd9dSEnrico Granata return true; 46221dfcd9dSEnrico Granata } 4635fb8f797SGreg Clayton } 4645fb8f797SGreg Clayton else 4655fb8f797SGreg Clayton { 4665fb8f797SGreg Clayton // The g_load_plugin_callback is registered in SBDebugger::Initialize() 4675fb8f797SGreg Clayton // and if the public API layer isn't available (code is linking against 4685fb8f797SGreg Clayton // all of the internal LLDB static libraries), then we can't load plugins 4695fb8f797SGreg Clayton error.SetErrorString("Public API layer is not available"); 4705fb8f797SGreg Clayton } 47121dfcd9dSEnrico Granata return false; 47221dfcd9dSEnrico Granata } 47321dfcd9dSEnrico Granata 47421dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 47521dfcd9dSEnrico Granata LoadPluginCallback 47621dfcd9dSEnrico Granata ( 47721dfcd9dSEnrico Granata void *baton, 47821dfcd9dSEnrico Granata FileSpec::FileType file_type, 47921dfcd9dSEnrico Granata const FileSpec &file_spec 48021dfcd9dSEnrico Granata ) 48121dfcd9dSEnrico Granata { 48221dfcd9dSEnrico Granata Error error; 48321dfcd9dSEnrico Granata 48421dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 4853cf443ddSMichael Sartain static ConstString g_solibext("so"); 48621dfcd9dSEnrico Granata 48721dfcd9dSEnrico Granata if (!baton) 48821dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 48921dfcd9dSEnrico Granata 49021dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 49121dfcd9dSEnrico Granata 49221dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 49321dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 49421dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 49521dfcd9dSEnrico Granata // file type information. 49621dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 49721dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 49821dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 49921dfcd9dSEnrico Granata { 50021dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 50121dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 50221dfcd9dSEnrico Granata 5033cf443ddSMichael Sartain if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 5043cf443ddSMichael Sartain plugin_file_spec.GetFileNameExtension() != g_solibext) 5053cf443ddSMichael Sartain { 50621dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 5073cf443ddSMichael Sartain } 50821dfcd9dSEnrico Granata 509e743c782SEnrico Granata Error plugin_load_error; 510e743c782SEnrico Granata debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 51121dfcd9dSEnrico Granata 51221dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 51321dfcd9dSEnrico Granata } 51421dfcd9dSEnrico Granata 51521dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 51621dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 51721dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 51821dfcd9dSEnrico Granata { 51921dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 52021dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 5216a7f3338SBruce Mitchener // might be enumerating a file system that doesn't have correct file type 52221dfcd9dSEnrico Granata // information. 52321dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 52421dfcd9dSEnrico Granata } 52521dfcd9dSEnrico Granata 52621dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 52721dfcd9dSEnrico Granata } 52821dfcd9dSEnrico Granata 52921dfcd9dSEnrico Granata void 53021dfcd9dSEnrico Granata Debugger::InstanceInitialize () 53121dfcd9dSEnrico Granata { 53221dfcd9dSEnrico Granata FileSpec dir_spec; 53321dfcd9dSEnrico Granata const bool find_directories = true; 53421dfcd9dSEnrico Granata const bool find_files = true; 53521dfcd9dSEnrico Granata const bool find_other = true; 53621dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 53742ff0ad8SZachary Turner if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) 53821dfcd9dSEnrico Granata { 53921dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 54021dfcd9dSEnrico Granata { 54121dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 54221dfcd9dSEnrico Granata find_directories, 54321dfcd9dSEnrico Granata find_files, 54421dfcd9dSEnrico Granata find_other, 54521dfcd9dSEnrico Granata LoadPluginCallback, 54621dfcd9dSEnrico Granata this); 54721dfcd9dSEnrico Granata } 54821dfcd9dSEnrico Granata } 54921dfcd9dSEnrico Granata 55042ff0ad8SZachary Turner if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) 55121dfcd9dSEnrico Granata { 55221dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 55321dfcd9dSEnrico Granata { 55421dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 55521dfcd9dSEnrico Granata find_directories, 55621dfcd9dSEnrico Granata find_files, 55721dfcd9dSEnrico Granata find_other, 55821dfcd9dSEnrico Granata LoadPluginCallback, 55921dfcd9dSEnrico Granata this); 56021dfcd9dSEnrico Granata } 56121dfcd9dSEnrico Granata } 562e8cd0c98SGreg Clayton 563e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 56421dfcd9dSEnrico Granata } 56521dfcd9dSEnrico Granata 5666611103cSGreg Clayton DebuggerSP 567228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 5686611103cSGreg Clayton { 569228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 570c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 5716611103cSGreg Clayton { 5726611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5736611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 5746611103cSGreg Clayton } 57521dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 5766611103cSGreg Clayton return debugger_sp; 5776611103cSGreg Clayton } 5786611103cSGreg Clayton 579e02657b1SCaroline Tice void 5804d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 581e02657b1SCaroline Tice { 582e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 583e02657b1SCaroline Tice return; 584e02657b1SCaroline Tice 5858314c525SJim Ingham debugger_sp->Clear(); 5868314c525SJim Ingham 587c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 588c15f55e2SGreg Clayton { 589e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 590e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 591e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 592e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 593e02657b1SCaroline Tice { 594e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 595e02657b1SCaroline Tice { 596e02657b1SCaroline Tice debugger_list.erase (pos); 597e02657b1SCaroline Tice return; 598e02657b1SCaroline Tice } 599e02657b1SCaroline Tice } 600e02657b1SCaroline Tice } 601c15f55e2SGreg Clayton } 602e02657b1SCaroline Tice 6034d122c40SGreg Clayton DebuggerSP 6043df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 6053df9a8dfSCaroline Tice { 6064d122c40SGreg Clayton DebuggerSP debugger_sp; 6076920b52bSGreg Clayton if (g_shared_debugger_refcount > 0) 6086920b52bSGreg Clayton { 6096920b52bSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 6106920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 6116920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 6126920b52bSGreg Clayton 6136920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 6146920b52bSGreg Clayton { 6156920b52bSGreg Clayton if ((*pos).get()->m_instance_name == instance_name) 6166920b52bSGreg Clayton { 6176920b52bSGreg Clayton debugger_sp = *pos; 6186920b52bSGreg Clayton break; 6196920b52bSGreg Clayton } 6206920b52bSGreg Clayton } 6216920b52bSGreg Clayton } 6223df9a8dfSCaroline Tice return debugger_sp; 6233df9a8dfSCaroline Tice } 6246611103cSGreg Clayton 6256611103cSGreg Clayton TargetSP 6266611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 6276611103cSGreg Clayton { 6284d122c40SGreg Clayton TargetSP target_sp; 629c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 630c15f55e2SGreg Clayton { 6316611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 6326611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 6336611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 6346611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 6356611103cSGreg Clayton { 6366611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 6376611103cSGreg Clayton if (target_sp) 6386611103cSGreg Clayton break; 6396611103cSGreg Clayton } 640c15f55e2SGreg Clayton } 6416611103cSGreg Clayton return target_sp; 6426611103cSGreg Clayton } 6436611103cSGreg Clayton 644e4e45924SGreg Clayton TargetSP 645e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 646e4e45924SGreg Clayton { 647e4e45924SGreg Clayton TargetSP target_sp; 648c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 649c15f55e2SGreg Clayton { 650e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 651e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 652e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 653e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 654e4e45924SGreg Clayton { 655e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 656e4e45924SGreg Clayton if (target_sp) 657e4e45924SGreg Clayton break; 658e4e45924SGreg Clayton } 659c15f55e2SGreg Clayton } 660e4e45924SGreg Clayton return target_sp; 661e4e45924SGreg Clayton } 662e4e45924SGreg Clayton 663e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) : 664e6481c7eSJason Molenda UserID(g_unique_id++), 665e6481c7eSJason Molenda Properties(OptionValuePropertiesSP(new OptionValueProperties())), 666e6481c7eSJason Molenda m_input_file_sp(new StreamFile(stdin, false)), 667e6481c7eSJason Molenda m_output_file_sp(new StreamFile(stdout, false)), 668e6481c7eSJason Molenda m_error_file_sp(new StreamFile(stderr, false)), 669e6481c7eSJason Molenda m_terminal_state(), 670e6481c7eSJason Molenda m_target_list(*this), 671e6481c7eSJason Molenda m_platform_list(), 672e6481c7eSJason Molenda m_listener("lldb.Debugger"), 673e6481c7eSJason Molenda m_source_manager_ap(), 674e6481c7eSJason Molenda m_source_file_cache(), 675e6481c7eSJason Molenda m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)), 676e6481c7eSJason Molenda m_input_reader_stack(), 677e6481c7eSJason Molenda m_instance_name(), 678afa91e33SGreg Clayton m_loaded_plugins(), 679afa91e33SGreg Clayton m_event_handler_thread (), 680afa91e33SGreg Clayton m_io_handler_thread (), 681afa91e33SGreg Clayton m_sync_broadcaster (NULL, "lldb.debugger.sync") 68230fdc8d8SChris Lattner { 68367cc0636SGreg Clayton char instance_cstr[256]; 68467cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 68567cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 686228063cdSJim Ingham if (log_callback) 687228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 6886611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 689ded470d3SGreg Clayton // Always add our default platform to the platform list 690615eb7e6SGreg Clayton PlatformSP default_platform_sp (Platform::GetHostPlatform()); 691ded470d3SGreg Clayton assert (default_platform_sp.get()); 692ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 69367cc0636SGreg Clayton 694754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 69567cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 69667cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 69767cc0636SGreg Clayton true, 69867cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 699754a9369SGreg Clayton if (m_command_interpreter_ap.get()) 700754a9369SGreg Clayton { 701754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 702754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 703754a9369SGreg Clayton true, 704754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 705754a9369SGreg Clayton } 70667cc0636SGreg Clayton OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 70767cc0636SGreg Clayton term_width->SetMinimumValue(10); 70867cc0636SGreg Clayton term_width->SetMaximumValue(1024); 709c3ce7f27SMichael Sartain 710c3ce7f27SMichael Sartain // Turn off use-color if this is a dumb terminal. 711c3ce7f27SMichael Sartain const char *term = getenv ("TERM"); 712c3ce7f27SMichael Sartain if (term && !strcmp (term, "dumb")) 713c3ce7f27SMichael Sartain SetUseColor (false); 71430fdc8d8SChris Lattner } 71530fdc8d8SChris Lattner 71630fdc8d8SChris Lattner Debugger::~Debugger () 71730fdc8d8SChris Lattner { 7188314c525SJim Ingham Clear(); 7198314c525SJim Ingham } 7208314c525SJim Ingham 7218314c525SJim Ingham void 7228314c525SJim Ingham Debugger::Clear() 7238314c525SJim Ingham { 72444d93782SGreg Clayton ClearIOHandlers(); 72544d93782SGreg Clayton StopIOHandlerThread(); 72644d93782SGreg Clayton StopEventHandlerThread(); 7271ed54f50SGreg Clayton m_listener.Clear(); 7286611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 7296611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 7306611103cSGreg Clayton { 731ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 732ccbc08e6SGreg Clayton if (target_sp) 733ccbc08e6SGreg Clayton { 734ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 7356611103cSGreg Clayton if (process_sp) 7361fd07059SJim Ingham process_sp->Finalize(); 737ccbc08e6SGreg Clayton target_sp->Destroy(); 7386611103cSGreg Clayton } 73930fdc8d8SChris Lattner } 7404bddaeb5SJim Ingham BroadcasterManager::Clear (); 74130fdc8d8SChris Lattner 7420d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 7430d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 744c5917d9aSJim Ingham m_terminal_state.Clear(); 74544d93782SGreg Clayton if (m_input_file_sp) 74644d93782SGreg Clayton m_input_file_sp->GetFile().Close (); 7470c4129f2SGreg Clayton 7480c4129f2SGreg Clayton m_command_interpreter_ap->Clear(); 7498314c525SJim Ingham } 75030fdc8d8SChris Lattner 75130fdc8d8SChris Lattner bool 752fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 753fc3f027dSGreg Clayton { 75444d93782SGreg Clayton // return m_input_comm.GetCloseOnEOF(); 75544d93782SGreg Clayton return false; 756fc3f027dSGreg Clayton } 757fc3f027dSGreg Clayton 758fc3f027dSGreg Clayton void 759fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 760fc3f027dSGreg Clayton { 76144d93782SGreg Clayton // m_input_comm.SetCloseOnEOF(b); 762fc3f027dSGreg Clayton } 763fc3f027dSGreg Clayton 764fc3f027dSGreg Clayton bool 76530fdc8d8SChris Lattner Debugger::GetAsyncExecution () 76630fdc8d8SChris Lattner { 7676611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 76830fdc8d8SChris Lattner } 76930fdc8d8SChris Lattner 77030fdc8d8SChris Lattner void 77130fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 77230fdc8d8SChris Lattner { 7736611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 77430fdc8d8SChris Lattner } 77530fdc8d8SChris Lattner 77630fdc8d8SChris Lattner 77730fdc8d8SChris Lattner void 77830fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 77930fdc8d8SChris Lattner { 78044d93782SGreg Clayton if (m_input_file_sp) 78144d93782SGreg Clayton m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership); 78244d93782SGreg Clayton else 78344d93782SGreg Clayton m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 78444d93782SGreg Clayton 78544d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 78651b1e2d2SGreg Clayton if (in_file.IsValid() == false) 78751b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 78830fdc8d8SChris Lattner 789c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 790c5917d9aSJim Ingham SaveInputTerminalState (); 79130fdc8d8SChris Lattner } 79230fdc8d8SChris Lattner 79330fdc8d8SChris Lattner void 79430fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 79530fdc8d8SChris Lattner { 79644d93782SGreg Clayton if (m_output_file_sp) 79744d93782SGreg Clayton m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership); 79844d93782SGreg Clayton else 79944d93782SGreg Clayton m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 80044d93782SGreg Clayton 80144d93782SGreg Clayton File &out_file = m_output_file_sp->GetFile(); 80251b1e2d2SGreg Clayton if (out_file.IsValid() == false) 80351b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 8042f88aadfSCaroline Tice 805b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 806b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 807b588726eSEnrico Granata const bool can_create = false; 808b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 809b588726eSEnrico Granata if (script_interpreter) 810b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 81130fdc8d8SChris Lattner } 81230fdc8d8SChris Lattner 81330fdc8d8SChris Lattner void 81430fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 81530fdc8d8SChris Lattner { 81644d93782SGreg Clayton if (m_error_file_sp) 81744d93782SGreg Clayton m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership); 81844d93782SGreg Clayton else 81944d93782SGreg Clayton m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 82044d93782SGreg Clayton 82144d93782SGreg Clayton File &err_file = m_error_file_sp->GetFile(); 82251b1e2d2SGreg Clayton if (err_file.IsValid() == false) 82351b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 82430fdc8d8SChris Lattner } 82530fdc8d8SChris Lattner 826c5917d9aSJim Ingham void 827c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 828c5917d9aSJim Ingham { 82944d93782SGreg Clayton if (m_input_file_sp) 83044d93782SGreg Clayton { 83144d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 832c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 833c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 834c5917d9aSJim Ingham } 83544d93782SGreg Clayton } 836c5917d9aSJim Ingham 837c5917d9aSJim Ingham void 838c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 839c5917d9aSJim Ingham { 840c5917d9aSJim Ingham m_terminal_state.Restore(); 841c5917d9aSJim Ingham } 842c5917d9aSJim Ingham 84330fdc8d8SChris Lattner ExecutionContext 8442976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 84530fdc8d8SChris Lattner { 84630fdc8d8SChris Lattner ExecutionContext exe_ctx; 847c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 848c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 84930fdc8d8SChris Lattner 85030fdc8d8SChris Lattner if (target_sp) 85130fdc8d8SChris Lattner { 852c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 853c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 854c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 85530fdc8d8SChris Lattner { 856c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 857c14ee32dSGreg Clayton if (thread_sp) 85830fdc8d8SChris Lattner { 859c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 860c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 861c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 862c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 86330fdc8d8SChris Lattner } 86430fdc8d8SChris Lattner } 86530fdc8d8SChris Lattner } 86630fdc8d8SChris Lattner return exe_ctx; 86730fdc8d8SChris Lattner } 86830fdc8d8SChris Lattner 86930fdc8d8SChris Lattner void 870efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 871efed6131SCaroline Tice { 87244d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 87344d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 874efed6131SCaroline Tice if (reader_sp) 87544d93782SGreg Clayton reader_sp->Interrupt(); 876efed6131SCaroline Tice } 877efed6131SCaroline Tice 878efed6131SCaroline Tice void 879efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 880efed6131SCaroline Tice { 88144d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 88244d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 883efed6131SCaroline Tice if (reader_sp) 88444d93782SGreg Clayton reader_sp->GotEOF(); 885efed6131SCaroline Tice } 886efed6131SCaroline Tice 887efed6131SCaroline Tice void 88844d93782SGreg Clayton Debugger::ClearIOHandlers () 8893d6086f6SCaroline Tice { 890b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 89144d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 892d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 8933d6086f6SCaroline Tice { 89444d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 8953d6086f6SCaroline Tice if (reader_sp) 8963d6086f6SCaroline Tice { 89744d93782SGreg Clayton m_input_reader_stack.Pop(); 8983d6086f6SCaroline Tice reader_sp->SetIsDone(true); 899e68f5d6bSGreg Clayton reader_sp->Cancel(); 9003d6086f6SCaroline Tice } 9013d6086f6SCaroline Tice } 9023d6086f6SCaroline Tice } 9033d6086f6SCaroline Tice 9043d6086f6SCaroline Tice void 90544d93782SGreg Clayton Debugger::ExecuteIOHanders() 906969ed3d1SCaroline Tice { 90744d93782SGreg Clayton 90844d93782SGreg Clayton while (1) 909969ed3d1SCaroline Tice { 91044d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 91130fdc8d8SChris Lattner if (!reader_sp) 91230fdc8d8SChris Lattner break; 91330fdc8d8SChris Lattner 91444d93782SGreg Clayton reader_sp->Activate(); 91544d93782SGreg Clayton reader_sp->Run(); 91644d93782SGreg Clayton reader_sp->Deactivate(); 91744d93782SGreg Clayton 91844d93782SGreg Clayton // Remove all input readers that are done from the top of the stack 91944d93782SGreg Clayton while (1) 92030fdc8d8SChris Lattner { 92144d93782SGreg Clayton IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); 92244d93782SGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 92344d93782SGreg Clayton m_input_reader_stack.Pop(); 92430fdc8d8SChris Lattner else 92530fdc8d8SChris Lattner break; 92630fdc8d8SChris Lattner } 92730fdc8d8SChris Lattner } 92844d93782SGreg Clayton ClearIOHandlers(); 92944d93782SGreg Clayton } 93030fdc8d8SChris Lattner 93144d93782SGreg Clayton bool 93244d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp) 93344d93782SGreg Clayton { 93444d93782SGreg Clayton return m_input_reader_stack.IsTop (reader_sp); 93544d93782SGreg Clayton } 93630fdc8d8SChris Lattner 93744d93782SGreg Clayton 93844d93782SGreg Clayton ConstString 93944d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch) 94044d93782SGreg Clayton { 94144d93782SGreg Clayton return m_input_reader_stack.GetTopIOHandlerControlSequence (ch); 94230fdc8d8SChris Lattner } 94330fdc8d8SChris Lattner 944a487aa4cSKate Stone const char * 945a487aa4cSKate Stone Debugger::GetIOHandlerCommandPrefix() 946a487aa4cSKate Stone { 947a487aa4cSKate Stone return m_input_reader_stack.GetTopIOHandlerCommandPrefix(); 948a487aa4cSKate Stone } 949a487aa4cSKate Stone 950a487aa4cSKate Stone const char * 951a487aa4cSKate Stone Debugger::GetIOHandlerHelpPrologue() 952a487aa4cSKate Stone { 953a487aa4cSKate Stone return m_input_reader_stack.GetTopIOHandlerHelpPrologue(); 954a487aa4cSKate Stone } 955a487aa4cSKate Stone 95630fdc8d8SChris Lattner void 95744d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp) 95844d93782SGreg Clayton { 95944d93782SGreg Clayton PushIOHandler (reader_sp); 960577508dfSGreg Clayton 961577508dfSGreg Clayton IOHandlerSP top_reader_sp = reader_sp; 962577508dfSGreg Clayton while (top_reader_sp) 963577508dfSGreg Clayton { 964577508dfSGreg Clayton top_reader_sp->Activate(); 965577508dfSGreg Clayton top_reader_sp->Run(); 966577508dfSGreg Clayton top_reader_sp->Deactivate(); 967577508dfSGreg Clayton 968577508dfSGreg Clayton if (top_reader_sp.get() == reader_sp.get()) 969577508dfSGreg Clayton { 970577508dfSGreg Clayton if (PopIOHandler (reader_sp)) 971577508dfSGreg Clayton break; 972577508dfSGreg Clayton } 973577508dfSGreg Clayton 974577508dfSGreg Clayton while (1) 975577508dfSGreg Clayton { 976577508dfSGreg Clayton top_reader_sp = m_input_reader_stack.Top(); 977577508dfSGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 978577508dfSGreg Clayton m_input_reader_stack.Pop(); 979577508dfSGreg Clayton else 980577508dfSGreg Clayton break; 981577508dfSGreg Clayton } 982577508dfSGreg Clayton } 98344d93782SGreg Clayton } 98444d93782SGreg Clayton 98544d93782SGreg Clayton void 98644d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err) 98744d93782SGreg Clayton { 98844d93782SGreg Clayton // Before an IOHandler runs, it must have in/out/err streams. 98944d93782SGreg Clayton // This function is called when one ore more of the streams 99044d93782SGreg Clayton // are NULL. We use the top input reader's in/out/err streams, 99144d93782SGreg Clayton // or fall back to the debugger file handles, or we fall back 99244d93782SGreg Clayton // onto stdin/stdout/stderr as a last resort. 99344d93782SGreg Clayton 99444d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 99544d93782SGreg Clayton IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 99644d93782SGreg Clayton // If no STDIN has been set, then set it appropriately 99744d93782SGreg Clayton if (!in) 99844d93782SGreg Clayton { 99944d93782SGreg Clayton if (top_reader_sp) 100044d93782SGreg Clayton in = top_reader_sp->GetInputStreamFile(); 100144d93782SGreg Clayton else 100244d93782SGreg Clayton in = GetInputFile(); 100344d93782SGreg Clayton 100444d93782SGreg Clayton // If there is nothing, use stdin 100544d93782SGreg Clayton if (!in) 100644d93782SGreg Clayton in = StreamFileSP(new StreamFile(stdin, false)); 100744d93782SGreg Clayton } 100844d93782SGreg Clayton // If no STDOUT has been set, then set it appropriately 100944d93782SGreg Clayton if (!out) 101044d93782SGreg Clayton { 101144d93782SGreg Clayton if (top_reader_sp) 101244d93782SGreg Clayton out = top_reader_sp->GetOutputStreamFile(); 101344d93782SGreg Clayton else 101444d93782SGreg Clayton out = GetOutputFile(); 101544d93782SGreg Clayton 101644d93782SGreg Clayton // If there is nothing, use stdout 101744d93782SGreg Clayton if (!out) 101844d93782SGreg Clayton out = StreamFileSP(new StreamFile(stdout, false)); 101944d93782SGreg Clayton } 102044d93782SGreg Clayton // If no STDERR has been set, then set it appropriately 102144d93782SGreg Clayton if (!err) 102244d93782SGreg Clayton { 102344d93782SGreg Clayton if (top_reader_sp) 102444d93782SGreg Clayton err = top_reader_sp->GetErrorStreamFile(); 102544d93782SGreg Clayton else 102644d93782SGreg Clayton err = GetErrorFile(); 102744d93782SGreg Clayton 102844d93782SGreg Clayton // If there is nothing, use stderr 102944d93782SGreg Clayton if (!err) 103044d93782SGreg Clayton err = StreamFileSP(new StreamFile(stdout, false)); 103144d93782SGreg Clayton 103244d93782SGreg Clayton } 103344d93782SGreg Clayton } 103444d93782SGreg Clayton 103544d93782SGreg Clayton void 103644d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp) 103730fdc8d8SChris Lattner { 103830fdc8d8SChris Lattner if (!reader_sp) 103930fdc8d8SChris Lattner return; 1040b44880caSCaroline Tice 104144d93782SGreg Clayton // Got the current top input reader... 104244d93782SGreg Clayton IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 1043b44880caSCaroline Tice 1044b4874f1aSGreg Clayton // Don't push the same IO handler twice... 1045b4874f1aSGreg Clayton if (reader_sp.get() != top_reader_sp.get()) 1046b4874f1aSGreg Clayton { 104744d93782SGreg Clayton // Push our new input reader 1048d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 104944d93782SGreg Clayton 105044d93782SGreg Clayton // Interrupt the top input reader to it will exit its Run() function 105144d93782SGreg Clayton // and let this new input reader take over 105244d93782SGreg Clayton if (top_reader_sp) 105344d93782SGreg Clayton top_reader_sp->Deactivate(); 105430fdc8d8SChris Lattner } 1055b4874f1aSGreg Clayton } 105630fdc8d8SChris Lattner 105730fdc8d8SChris Lattner bool 105844d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp) 105930fdc8d8SChris Lattner { 106030fdc8d8SChris Lattner bool result = false; 106130fdc8d8SChris Lattner 106244d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 106344d93782SGreg Clayton 106430fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 10656a7f3338SBruce Mitchener // read on the stack refresh its prompt and if there is one... 1066d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 106730fdc8d8SChris Lattner { 106844d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 106930fdc8d8SChris Lattner 107030fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 107130fdc8d8SChris Lattner { 107244d93782SGreg Clayton reader_sp->Deactivate(); 1073b4874f1aSGreg Clayton reader_sp->Cancel(); 1074d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 107530fdc8d8SChris Lattner 1076d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 107730fdc8d8SChris Lattner if (reader_sp) 107844d93782SGreg Clayton reader_sp->Activate(); 107944d93782SGreg Clayton 108044d93782SGreg Clayton result = true; 108130fdc8d8SChris Lattner } 108230fdc8d8SChris Lattner } 108330fdc8d8SChris Lattner return result; 108430fdc8d8SChris Lattner } 108530fdc8d8SChris Lattner 108630fdc8d8SChris Lattner bool 108744d93782SGreg Clayton Debugger::HideTopIOHandler() 108830fdc8d8SChris Lattner { 108944d93782SGreg Clayton Mutex::Locker locker; 109030fdc8d8SChris Lattner 109144d93782SGreg Clayton if (locker.TryLock(m_input_reader_stack.GetMutex())) 109230fdc8d8SChris Lattner { 109344d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 109444d93782SGreg Clayton if (reader_sp) 109544d93782SGreg Clayton reader_sp->Hide(); 109644d93782SGreg Clayton return true; 109730fdc8d8SChris Lattner } 109844d93782SGreg Clayton return false; 109930fdc8d8SChris Lattner } 110030fdc8d8SChris Lattner 110130fdc8d8SChris Lattner void 110244d93782SGreg Clayton Debugger::RefreshTopIOHandler() 110330fdc8d8SChris Lattner { 110444d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 110544d93782SGreg Clayton if (reader_sp) 110644d93782SGreg Clayton reader_sp->Refresh(); 110730fdc8d8SChris Lattner } 110844d93782SGreg Clayton 11096611103cSGreg Clayton 11105b52f0c7SJim Ingham StreamSP 11115b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 11125b52f0c7SJim Ingham { 11135b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 11145b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 11155b52f0c7SJim Ingham } 11165b52f0c7SJim Ingham 11175b52f0c7SJim Ingham StreamSP 11185b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 11195b52f0c7SJim Ingham { 11205b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 11215b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 11225b52f0c7SJim Ingham } 11235b52f0c7SJim Ingham 1124c7bece56SGreg Clayton size_t 1125061858ceSEnrico Granata Debugger::GetNumDebuggers() 1126061858ceSEnrico Granata { 1127c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1128c15f55e2SGreg Clayton { 1129061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1130061858ceSEnrico Granata return GetDebuggerList().size(); 1131061858ceSEnrico Granata } 1132c15f55e2SGreg Clayton return 0; 1133c15f55e2SGreg Clayton } 1134061858ceSEnrico Granata 1135061858ceSEnrico Granata lldb::DebuggerSP 1136c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1137061858ceSEnrico Granata { 1138061858ceSEnrico Granata DebuggerSP debugger_sp; 1139061858ceSEnrico Granata 1140c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1141c15f55e2SGreg Clayton { 1142061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1143061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1144061858ceSEnrico Granata 1145061858ceSEnrico Granata if (index < debugger_list.size()) 1146061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1147c15f55e2SGreg Clayton } 1148061858ceSEnrico Granata 1149061858ceSEnrico Granata return debugger_sp; 1150061858ceSEnrico Granata } 1151061858ceSEnrico Granata 1152ebc1bb27SCaroline Tice DebuggerSP 1153ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1154ebc1bb27SCaroline Tice { 11554d122c40SGreg Clayton DebuggerSP debugger_sp; 1156ebc1bb27SCaroline Tice 1157c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1158c15f55e2SGreg Clayton { 1159ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 1160ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1161ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1162ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1163ebc1bb27SCaroline Tice { 1164ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 1165ebc1bb27SCaroline Tice { 1166ebc1bb27SCaroline Tice debugger_sp = *pos; 1167ebc1bb27SCaroline Tice break; 1168ebc1bb27SCaroline Tice } 1169ebc1bb27SCaroline Tice } 1170c15f55e2SGreg Clayton } 1171ebc1bb27SCaroline Tice return debugger_sp; 1172ebc1bb27SCaroline Tice } 11733df9a8dfSCaroline Tice 11742643b905SSaleem Abdulrasool #if 0 11751b654882SGreg Clayton static void 1176b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame) 11771b654882SGreg Clayton { 11781b654882SGreg Clayton if (frame == NULL) 11791b654882SGreg Clayton return; 11801b654882SGreg Clayton 11811b654882SGreg Clayton StreamString s; 11821b654882SGreg Clayton const char *prompt_format = 11831b654882SGreg Clayton "{addr = '${addr}'\n}" 1184aff1b357SJason Molenda "{addr-file-or-load = '${addr-file-or-load}'\n}" 1185aff1b357SJason Molenda "{current-pc-arrow = '${current-pc-arrow}'\n}" 11861b654882SGreg Clayton "{process.id = '${process.id}'\n}" 11871b654882SGreg Clayton "{process.name = '${process.name}'\n}" 11881b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 11891b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 11901b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 11911b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 11921b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 11931b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 11941b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 11951b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 11961b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 11971b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 11981b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 11991b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 12001b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 12011b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 12021b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 12031b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 12041b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 12051b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 12061b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 12071b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 12081b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 12091b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 12101b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 12111b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 12121b654882SGreg Clayton "{function.id = '${function.id}'\n}" 1213aff1b357SJason Molenda "{function.changed = '${function.changed}'\n}" 1214aff1b357SJason Molenda "{function.initial-function = '${function.initial-function}'\n}" 12151b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1216aff1b357SJason Molenda "{function.name-without-args = '${function.name-without-args}'\n}" 1217ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 12181b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 1219aff1b357SJason Molenda "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}" 12201b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 12211b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 12221b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 12231b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 12241b654882SGreg Clayton "{line.number = '${line.number}'\n}" 12251b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 12261b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 12271b654882SGreg Clayton ; 12281b654882SGreg Clayton 12291b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 12301b654882SGreg Clayton ExecutionContext exe_ctx; 12310603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 1232c3ce7f27SMichael Sartain if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 12331b654882SGreg Clayton { 12341b654882SGreg Clayton printf("%s\n", s.GetData()); 12351b654882SGreg Clayton } 12361b654882SGreg Clayton else 12371b654882SGreg Clayton { 12381b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 12391b654882SGreg Clayton } 12401b654882SGreg Clayton } 12412643b905SSaleem Abdulrasool #endif 12421b654882SGreg Clayton 1243c3ce7f27SMichael Sartain bool 1244554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format, 1245aff1b357SJason Molenda const SymbolContext *sc, 1246aff1b357SJason Molenda const SymbolContext *prev_sc, 1247aff1b357SJason Molenda const ExecutionContext *exe_ctx, 1248aff1b357SJason Molenda const Address *addr, 1249aff1b357SJason Molenda Stream &s) 1250aff1b357SJason Molenda { 1251554f68d3SGreg Clayton FormatEntity::Entry format_entry; 1252554f68d3SGreg Clayton 1253554f68d3SGreg Clayton if (format == NULL) 1254aff1b357SJason Molenda { 1255554f68d3SGreg Clayton if (exe_ctx != NULL && exe_ctx->HasTargetScope()) 1256aff1b357SJason Molenda format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat(); 1257554f68d3SGreg Clayton if (format == NULL) 1258554f68d3SGreg Clayton { 1259554f68d3SGreg Clayton FormatEntity::Parse("${addr}: ", format_entry); 1260554f68d3SGreg Clayton format = &format_entry; 1261554f68d3SGreg Clayton } 1262aff1b357SJason Molenda } 1263aff1b357SJason Molenda bool function_changed = false; 1264aff1b357SJason Molenda bool initial_function = false; 1265aff1b357SJason Molenda if (prev_sc && (prev_sc->function || prev_sc->symbol)) 1266aff1b357SJason Molenda { 1267aff1b357SJason Molenda if (sc && (sc->function || sc->symbol)) 1268aff1b357SJason Molenda { 1269aff1b357SJason Molenda if (prev_sc->symbol && sc->symbol) 1270aff1b357SJason Molenda { 1271aff1b357SJason Molenda if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType())) 1272aff1b357SJason Molenda { 1273aff1b357SJason Molenda function_changed = true; 1274aff1b357SJason Molenda } 1275aff1b357SJason Molenda } 1276aff1b357SJason Molenda else if (prev_sc->function && sc->function) 1277aff1b357SJason Molenda { 1278aff1b357SJason Molenda if (prev_sc->function->GetMangled() != sc->function->GetMangled()) 1279aff1b357SJason Molenda { 1280aff1b357SJason Molenda function_changed = true; 1281aff1b357SJason Molenda } 1282aff1b357SJason Molenda } 1283aff1b357SJason Molenda } 1284aff1b357SJason Molenda } 1285aff1b357SJason Molenda // The first context on a list of instructions will have a prev_sc that 1286aff1b357SJason Molenda // has no Function or Symbol -- if SymbolContext had an IsValid() method, it 1287aff1b357SJason Molenda // would return false. But we do get a prev_sc pointer. 1288aff1b357SJason Molenda if ((sc && (sc->function || sc->symbol)) 1289aff1b357SJason Molenda && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL)) 1290aff1b357SJason Molenda { 1291aff1b357SJason Molenda initial_function = true; 1292aff1b357SJason Molenda } 1293554f68d3SGreg Clayton return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function); 1294aff1b357SJason Molenda } 1295aff1b357SJason Molenda 1296aff1b357SJason Molenda 1297228063cdSJim Ingham void 1298228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 1299228063cdSJim Ingham { 13004f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 13014f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 13024f02b22dSJim Ingham // callback. 1303228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 1304228063cdSJim Ingham } 1305228063cdSJim Ingham 1306228063cdSJim Ingham bool 1307228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 1308228063cdSJim Ingham { 1309228063cdSJim Ingham Log::Callbacks log_callbacks; 1310228063cdSJim Ingham 1311228063cdSJim Ingham StreamSP log_stream_sp; 13129a028519SSean Callanan if (m_log_callback_stream_sp) 1313228063cdSJim Ingham { 1314228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 1315228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 1316228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 1317228063cdSJim Ingham } 1318228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 1319228063cdSJim Ingham { 132044d93782SGreg Clayton log_stream_sp = GetOutputFile(); 1321228063cdSJim Ingham } 1322228063cdSJim Ingham else 1323228063cdSJim Ingham { 1324228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 1325c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 1326c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 1327c1b2ccfdSGreg Clayton if (!log_stream_sp) 1328228063cdSJim Ingham { 1329228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 1330228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 1331228063cdSJim Ingham } 1332228063cdSJim Ingham } 1333228063cdSJim Ingham assert (log_stream_sp.get()); 1334228063cdSJim Ingham 1335228063cdSJim Ingham if (log_options == 0) 1336228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 1337228063cdSJim Ingham 133857abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 1339228063cdSJim Ingham { 1340228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 1341228063cdSJim Ingham return true; 1342228063cdSJim Ingham } 1343228063cdSJim Ingham else 1344228063cdSJim Ingham { 1345228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 1346228063cdSJim Ingham if (log_channel_sp) 1347228063cdSJim Ingham { 1348228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 1349228063cdSJim Ingham { 1350228063cdSJim Ingham return true; 1351228063cdSJim Ingham } 1352228063cdSJim Ingham else 1353228063cdSJim Ingham { 1354228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 1355228063cdSJim Ingham return false; 1356228063cdSJim Ingham } 1357228063cdSJim Ingham } 1358228063cdSJim Ingham else 1359228063cdSJim Ingham { 1360228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 1361228063cdSJim Ingham return false; 1362228063cdSJim Ingham } 1363228063cdSJim Ingham } 1364228063cdSJim Ingham return false; 1365228063cdSJim Ingham } 1366228063cdSJim Ingham 13679585fbfcSGreg Clayton SourceManager & 13689585fbfcSGreg Clayton Debugger::GetSourceManager () 13699585fbfcSGreg Clayton { 13709585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 13719585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 13729585fbfcSGreg Clayton return *m_source_manager_ap; 13739585fbfcSGreg Clayton } 13749585fbfcSGreg Clayton 13759585fbfcSGreg Clayton 137644d93782SGreg Clayton 137744d93782SGreg Clayton // This function handles events that were broadcast by the process. 137844d93782SGreg Clayton void 137944d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp) 138044d93782SGreg Clayton { 138144d93782SGreg Clayton using namespace lldb; 138244d93782SGreg Clayton const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp); 138344d93782SGreg Clayton 138444d93782SGreg Clayton // if (event_type & eBreakpointEventTypeAdded 138544d93782SGreg Clayton // || event_type & eBreakpointEventTypeRemoved 138644d93782SGreg Clayton // || event_type & eBreakpointEventTypeEnabled 138744d93782SGreg Clayton // || event_type & eBreakpointEventTypeDisabled 138844d93782SGreg Clayton // || event_type & eBreakpointEventTypeCommandChanged 138944d93782SGreg Clayton // || event_type & eBreakpointEventTypeConditionChanged 139044d93782SGreg Clayton // || event_type & eBreakpointEventTypeIgnoreChanged 139144d93782SGreg Clayton // || event_type & eBreakpointEventTypeLocationsResolved) 139244d93782SGreg Clayton // { 139344d93782SGreg Clayton // // Don't do anything about these events, since the breakpoint commands already echo these actions. 139444d93782SGreg Clayton // } 139544d93782SGreg Clayton // 139644d93782SGreg Clayton if (event_type & eBreakpointEventTypeLocationsAdded) 139744d93782SGreg Clayton { 139844d93782SGreg Clayton uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp); 139944d93782SGreg Clayton if (num_new_locations > 0) 140044d93782SGreg Clayton { 140144d93782SGreg Clayton BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 140244d93782SGreg Clayton StreamFileSP output_sp (GetOutputFile()); 140344d93782SGreg Clayton if (output_sp) 140444d93782SGreg Clayton { 140544d93782SGreg Clayton output_sp->Printf("%d location%s added to breakpoint %d\n", 140644d93782SGreg Clayton num_new_locations, 140744d93782SGreg Clayton num_new_locations == 1 ? "" : "s", 140844d93782SGreg Clayton breakpoint->GetID()); 140944d93782SGreg Clayton RefreshTopIOHandler(); 141044d93782SGreg Clayton } 141144d93782SGreg Clayton } 141244d93782SGreg Clayton } 141344d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsRemoved) 141444d93782SGreg Clayton // { 141544d93782SGreg Clayton // // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 141644d93782SGreg Clayton // } 141744d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsResolved) 141844d93782SGreg Clayton // { 141944d93782SGreg Clayton // // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 142044d93782SGreg Clayton // } 142144d93782SGreg Clayton } 142244d93782SGreg Clayton 142344d93782SGreg Clayton size_t 142444d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream) 142544d93782SGreg Clayton { 142644d93782SGreg Clayton size_t total_bytes = 0; 142744d93782SGreg Clayton if (stream == NULL) 142844d93782SGreg Clayton stream = GetOutputFile().get(); 142944d93782SGreg Clayton 143044d93782SGreg Clayton if (stream) 143144d93782SGreg Clayton { 143244d93782SGreg Clayton // The process has stuff waiting for stdout; get it and write it out to the appropriate place. 143344d93782SGreg Clayton if (process == NULL) 143444d93782SGreg Clayton { 143544d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 143644d93782SGreg Clayton if (target_sp) 143744d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 143844d93782SGreg Clayton } 143944d93782SGreg Clayton if (process) 144044d93782SGreg Clayton { 144144d93782SGreg Clayton Error error; 144244d93782SGreg Clayton size_t len; 144344d93782SGreg Clayton char stdio_buffer[1024]; 144444d93782SGreg Clayton while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 144544d93782SGreg Clayton { 144644d93782SGreg Clayton stream->Write(stdio_buffer, len); 144744d93782SGreg Clayton total_bytes += len; 144844d93782SGreg Clayton } 144944d93782SGreg Clayton } 145044d93782SGreg Clayton stream->Flush(); 145144d93782SGreg Clayton } 145244d93782SGreg Clayton return total_bytes; 145344d93782SGreg Clayton } 145444d93782SGreg Clayton 145544d93782SGreg Clayton size_t 145644d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream) 145744d93782SGreg Clayton { 145844d93782SGreg Clayton size_t total_bytes = 0; 145944d93782SGreg Clayton if (stream == NULL) 146044d93782SGreg Clayton stream = GetOutputFile().get(); 146144d93782SGreg Clayton 146244d93782SGreg Clayton if (stream) 146344d93782SGreg Clayton { 146444d93782SGreg Clayton // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 146544d93782SGreg Clayton if (process == NULL) 146644d93782SGreg Clayton { 146744d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 146844d93782SGreg Clayton if (target_sp) 146944d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 147044d93782SGreg Clayton } 147144d93782SGreg Clayton if (process) 147244d93782SGreg Clayton { 147344d93782SGreg Clayton Error error; 147444d93782SGreg Clayton size_t len; 147544d93782SGreg Clayton char stdio_buffer[1024]; 147644d93782SGreg Clayton while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 147744d93782SGreg Clayton { 147844d93782SGreg Clayton stream->Write(stdio_buffer, len); 147944d93782SGreg Clayton total_bytes += len; 148044d93782SGreg Clayton } 148144d93782SGreg Clayton } 148244d93782SGreg Clayton stream->Flush(); 148344d93782SGreg Clayton } 148444d93782SGreg Clayton return total_bytes; 148544d93782SGreg Clayton } 148644d93782SGreg Clayton 1487dc6224e0SGreg Clayton 148844d93782SGreg Clayton // This function handles events that were broadcast by the process. 148944d93782SGreg Clayton void 149044d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp) 149144d93782SGreg Clayton { 149244d93782SGreg Clayton using namespace lldb; 149344d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 149444d93782SGreg Clayton ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 149544d93782SGreg Clayton 1496b4874f1aSGreg Clayton StreamString output_stream; 1497b4874f1aSGreg Clayton StreamString error_stream; 149844d93782SGreg Clayton const bool gui_enabled = IsForwardingEvents(); 149944d93782SGreg Clayton 1500b4874f1aSGreg Clayton if (!gui_enabled) 1501b4874f1aSGreg Clayton { 1502b4874f1aSGreg Clayton bool pop_process_io_handler = false; 150344d93782SGreg Clayton assert (process_sp); 150444d93782SGreg Clayton 1505b4874f1aSGreg Clayton if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged) 150644d93782SGreg Clayton { 1507b4874f1aSGreg Clayton GetProcessSTDOUT (process_sp.get(), &output_stream); 150844d93782SGreg Clayton } 1509b4874f1aSGreg Clayton 1510b4874f1aSGreg Clayton if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged) 151144d93782SGreg Clayton { 1512b4874f1aSGreg Clayton GetProcessSTDERR (process_sp.get(), &error_stream); 151344d93782SGreg Clayton } 1514b4874f1aSGreg Clayton 1515b4874f1aSGreg Clayton if (event_type & Process::eBroadcastBitStateChanged) 151644d93782SGreg Clayton { 1517dc6224e0SGreg Clayton Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler); 151844d93782SGreg Clayton } 1519b4874f1aSGreg Clayton 1520b4874f1aSGreg Clayton if (output_stream.GetSize() || error_stream.GetSize()) 1521b4874f1aSGreg Clayton { 1522b4874f1aSGreg Clayton StreamFileSP error_stream_sp (GetOutputFile()); 15236fea17e8SGreg Clayton bool top_io_handler_hid = false; 15246fea17e8SGreg Clayton 15256fea17e8SGreg Clayton if (process_sp->ProcessIOHandlerIsActive() == false) 15266fea17e8SGreg Clayton top_io_handler_hid = HideTopIOHandler(); 1527b4874f1aSGreg Clayton 1528b4874f1aSGreg Clayton if (output_stream.GetSize()) 1529b4874f1aSGreg Clayton { 1530b4874f1aSGreg Clayton StreamFileSP output_stream_sp (GetOutputFile()); 1531b4874f1aSGreg Clayton if (output_stream_sp) 1532b4874f1aSGreg Clayton output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize()); 1533b4874f1aSGreg Clayton } 1534b4874f1aSGreg Clayton 1535b4874f1aSGreg Clayton if (error_stream.GetSize()) 1536b4874f1aSGreg Clayton { 1537b4874f1aSGreg Clayton StreamFileSP error_stream_sp (GetErrorFile()); 1538b4874f1aSGreg Clayton if (error_stream_sp) 1539b4874f1aSGreg Clayton error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize()); 154044d93782SGreg Clayton } 154144d93782SGreg Clayton 154244d93782SGreg Clayton if (top_io_handler_hid) 154344d93782SGreg Clayton RefreshTopIOHandler(); 154444d93782SGreg Clayton } 154544d93782SGreg Clayton 1546b4874f1aSGreg Clayton if (pop_process_io_handler) 1547b4874f1aSGreg Clayton process_sp->PopProcessIOHandler(); 1548b4874f1aSGreg Clayton } 1549b4874f1aSGreg Clayton } 1550b4874f1aSGreg Clayton 155144d93782SGreg Clayton void 155244d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp) 155344d93782SGreg Clayton { 155444d93782SGreg Clayton // At present the only thread event we handle is the Frame Changed event, 155544d93782SGreg Clayton // and all we do for that is just reprint the thread status for that thread. 155644d93782SGreg Clayton using namespace lldb; 155744d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 155844d93782SGreg Clayton if (event_type == Thread::eBroadcastBitStackChanged || 155944d93782SGreg Clayton event_type == Thread::eBroadcastBitThreadSelected ) 156044d93782SGreg Clayton { 156144d93782SGreg Clayton ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get())); 156244d93782SGreg Clayton if (thread_sp) 156344d93782SGreg Clayton { 156444d93782SGreg Clayton HideTopIOHandler(); 156544d93782SGreg Clayton StreamFileSP stream_sp (GetOutputFile()); 156644d93782SGreg Clayton thread_sp->GetStatus(*stream_sp, 0, 1, 1); 156744d93782SGreg Clayton RefreshTopIOHandler(); 156844d93782SGreg Clayton } 156944d93782SGreg Clayton } 157044d93782SGreg Clayton } 157144d93782SGreg Clayton 157244d93782SGreg Clayton bool 157344d93782SGreg Clayton Debugger::IsForwardingEvents () 157444d93782SGreg Clayton { 157544d93782SGreg Clayton return (bool)m_forward_listener_sp; 157644d93782SGreg Clayton } 157744d93782SGreg Clayton 157844d93782SGreg Clayton void 157944d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp) 158044d93782SGreg Clayton { 158144d93782SGreg Clayton m_forward_listener_sp = listener_sp; 158244d93782SGreg Clayton } 158344d93782SGreg Clayton 158444d93782SGreg Clayton void 158544d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp) 158644d93782SGreg Clayton { 158744d93782SGreg Clayton m_forward_listener_sp.reset(); 158844d93782SGreg Clayton } 158944d93782SGreg Clayton 159044d93782SGreg Clayton 159144d93782SGreg Clayton void 159244d93782SGreg Clayton Debugger::DefaultEventHandler() 159344d93782SGreg Clayton { 159444d93782SGreg Clayton Listener& listener(GetListener()); 159544d93782SGreg Clayton ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 159644d93782SGreg Clayton ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 159744d93782SGreg Clayton ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 159844d93782SGreg Clayton BroadcastEventSpec target_event_spec (broadcaster_class_target, 159944d93782SGreg Clayton Target::eBroadcastBitBreakpointChanged); 160044d93782SGreg Clayton 160144d93782SGreg Clayton BroadcastEventSpec process_event_spec (broadcaster_class_process, 160244d93782SGreg Clayton Process::eBroadcastBitStateChanged | 160344d93782SGreg Clayton Process::eBroadcastBitSTDOUT | 160444d93782SGreg Clayton Process::eBroadcastBitSTDERR); 160544d93782SGreg Clayton 160644d93782SGreg Clayton BroadcastEventSpec thread_event_spec (broadcaster_class_thread, 160744d93782SGreg Clayton Thread::eBroadcastBitStackChanged | 160844d93782SGreg Clayton Thread::eBroadcastBitThreadSelected ); 160944d93782SGreg Clayton 161044d93782SGreg Clayton listener.StartListeningForEventSpec (*this, target_event_spec); 161144d93782SGreg Clayton listener.StartListeningForEventSpec (*this, process_event_spec); 161244d93782SGreg Clayton listener.StartListeningForEventSpec (*this, thread_event_spec); 161344d93782SGreg Clayton listener.StartListeningForEvents (m_command_interpreter_ap.get(), 161444d93782SGreg Clayton CommandInterpreter::eBroadcastBitQuitCommandReceived | 161544d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousOutputData | 161644d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousErrorData ); 161744d93782SGreg Clayton 1618afa91e33SGreg Clayton // Let the thread that spawned us know that we have started up and 1619afa91e33SGreg Clayton // that we are now listening to all required events so no events get missed 1620afa91e33SGreg Clayton m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening); 1621afa91e33SGreg Clayton 162244d93782SGreg Clayton bool done = false; 162344d93782SGreg Clayton while (!done) 162444d93782SGreg Clayton { 162544d93782SGreg Clayton EventSP event_sp; 162644d93782SGreg Clayton if (listener.WaitForEvent(NULL, event_sp)) 162744d93782SGreg Clayton { 162844d93782SGreg Clayton if (event_sp) 162944d93782SGreg Clayton { 163044d93782SGreg Clayton Broadcaster *broadcaster = event_sp->GetBroadcaster(); 163144d93782SGreg Clayton if (broadcaster) 163244d93782SGreg Clayton { 163344d93782SGreg Clayton uint32_t event_type = event_sp->GetType(); 163444d93782SGreg Clayton ConstString broadcaster_class (broadcaster->GetBroadcasterClass()); 163544d93782SGreg Clayton if (broadcaster_class == broadcaster_class_process) 163644d93782SGreg Clayton { 163744d93782SGreg Clayton HandleProcessEvent (event_sp); 163844d93782SGreg Clayton } 163944d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_target) 164044d93782SGreg Clayton { 164144d93782SGreg Clayton if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get())) 164244d93782SGreg Clayton { 164344d93782SGreg Clayton HandleBreakpointEvent (event_sp); 164444d93782SGreg Clayton } 164544d93782SGreg Clayton } 164644d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_thread) 164744d93782SGreg Clayton { 164844d93782SGreg Clayton HandleThreadEvent (event_sp); 164944d93782SGreg Clayton } 165044d93782SGreg Clayton else if (broadcaster == m_command_interpreter_ap.get()) 165144d93782SGreg Clayton { 165244d93782SGreg Clayton if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived) 165344d93782SGreg Clayton { 165444d93782SGreg Clayton done = true; 165544d93782SGreg Clayton } 165644d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData) 165744d93782SGreg Clayton { 165844d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 165944d93782SGreg Clayton if (data && data[0]) 166044d93782SGreg Clayton { 166144d93782SGreg Clayton StreamFileSP error_sp (GetErrorFile()); 166244d93782SGreg Clayton if (error_sp) 166344d93782SGreg Clayton { 166444d93782SGreg Clayton HideTopIOHandler(); 166544d93782SGreg Clayton error_sp->PutCString(data); 166644d93782SGreg Clayton error_sp->Flush(); 166744d93782SGreg Clayton RefreshTopIOHandler(); 166844d93782SGreg Clayton } 166944d93782SGreg Clayton } 167044d93782SGreg Clayton } 167144d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData) 167244d93782SGreg Clayton { 167344d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 167444d93782SGreg Clayton if (data && data[0]) 167544d93782SGreg Clayton { 167644d93782SGreg Clayton StreamFileSP output_sp (GetOutputFile()); 167744d93782SGreg Clayton if (output_sp) 167844d93782SGreg Clayton { 167944d93782SGreg Clayton HideTopIOHandler(); 168044d93782SGreg Clayton output_sp->PutCString(data); 168144d93782SGreg Clayton output_sp->Flush(); 168244d93782SGreg Clayton RefreshTopIOHandler(); 168344d93782SGreg Clayton } 168444d93782SGreg Clayton } 168544d93782SGreg Clayton } 168644d93782SGreg Clayton } 168744d93782SGreg Clayton } 168844d93782SGreg Clayton 168944d93782SGreg Clayton if (m_forward_listener_sp) 169044d93782SGreg Clayton m_forward_listener_sp->AddEvent(event_sp); 169144d93782SGreg Clayton } 169244d93782SGreg Clayton } 169344d93782SGreg Clayton } 169444d93782SGreg Clayton } 169544d93782SGreg Clayton 169644d93782SGreg Clayton lldb::thread_result_t 169744d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg) 169844d93782SGreg Clayton { 169944d93782SGreg Clayton ((Debugger *)arg)->DefaultEventHandler(); 170044d93782SGreg Clayton return NULL; 170144d93782SGreg Clayton } 170244d93782SGreg Clayton 170344d93782SGreg Clayton bool 170444d93782SGreg Clayton Debugger::StartEventHandlerThread() 170544d93782SGreg Clayton { 1706acee96aeSZachary Turner if (!m_event_handler_thread.IsJoinable()) 1707807b6b32SGreg Clayton { 1708afa91e33SGreg Clayton // We must synchronize with the DefaultEventHandler() thread to ensure 1709afa91e33SGreg Clayton // it is up and running and listening to events before we return from 1710afa91e33SGreg Clayton // this function. We do this by listening to events for the 1711afa91e33SGreg Clayton // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster 1712afa91e33SGreg Clayton Listener listener("lldb.debugger.event-handler"); 1713afa91e33SGreg Clayton listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening); 1714afa91e33SGreg Clayton 17157c2896a2SZachary Turner // Use larger 8MB stack for this thread 1716afa91e33SGreg Clayton m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread, 1717afa91e33SGreg Clayton this, 1718afa91e33SGreg Clayton NULL, 17197c2896a2SZachary Turner g_debugger_event_thread_stack_bytes); 1720afa91e33SGreg Clayton 1721afa91e33SGreg Clayton // Make sure DefaultEventHandler() is running and listening to events before we return 1722afa91e33SGreg Clayton // from this function. We are only listening for events of type 1723afa91e33SGreg Clayton // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need 1724afa91e33SGreg Clayton // to wait an infinite amount of time for it (NULL timeout as the first parameter) 1725afa91e33SGreg Clayton lldb::EventSP event_sp; 1726afa91e33SGreg Clayton listener.WaitForEvent(NULL, event_sp); 1727807b6b32SGreg Clayton } 1728acee96aeSZachary Turner return m_event_handler_thread.IsJoinable(); 172944d93782SGreg Clayton } 173044d93782SGreg Clayton 173144d93782SGreg Clayton void 173244d93782SGreg Clayton Debugger::StopEventHandlerThread() 173344d93782SGreg Clayton { 1734acee96aeSZachary Turner if (m_event_handler_thread.IsJoinable()) 173544d93782SGreg Clayton { 173644d93782SGreg Clayton GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived); 173739de3110SZachary Turner m_event_handler_thread.Join(nullptr); 173844d93782SGreg Clayton } 173944d93782SGreg Clayton } 174044d93782SGreg Clayton 174144d93782SGreg Clayton 174244d93782SGreg Clayton lldb::thread_result_t 174344d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg) 174444d93782SGreg Clayton { 174544d93782SGreg Clayton Debugger *debugger = (Debugger *)arg; 174644d93782SGreg Clayton debugger->ExecuteIOHanders(); 174744d93782SGreg Clayton debugger->StopEventHandlerThread(); 174844d93782SGreg Clayton return NULL; 174944d93782SGreg Clayton } 175044d93782SGreg Clayton 175144d93782SGreg Clayton bool 175244d93782SGreg Clayton Debugger::StartIOHandlerThread() 175344d93782SGreg Clayton { 1754acee96aeSZachary Turner if (!m_io_handler_thread.IsJoinable()) 1755807b6b32SGreg Clayton m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler", 1756807b6b32SGreg Clayton IOHandlerThread, 1757807b6b32SGreg Clayton this, 1758807b6b32SGreg Clayton NULL, 1759807b6b32SGreg Clayton 8*1024*1024); // Use larger 8MB stack for this thread 1760acee96aeSZachary Turner return m_io_handler_thread.IsJoinable(); 176144d93782SGreg Clayton } 176244d93782SGreg Clayton 176344d93782SGreg Clayton void 176444d93782SGreg Clayton Debugger::StopIOHandlerThread() 176544d93782SGreg Clayton { 1766acee96aeSZachary Turner if (m_io_handler_thread.IsJoinable()) 176744d93782SGreg Clayton { 176844d93782SGreg Clayton if (m_input_file_sp) 176944d93782SGreg Clayton m_input_file_sp->GetFile().Close(); 177039de3110SZachary Turner m_io_handler_thread.Join(nullptr); 177144d93782SGreg Clayton } 177244d93782SGreg Clayton } 177344d93782SGreg Clayton 1774893c932aSJim Ingham Target * 1775893c932aSJim Ingham Debugger::GetDummyTarget() 1776893c932aSJim Ingham { 1777893c932aSJim Ingham return m_target_list.GetDummyTarget (*this).get(); 1778893c932aSJim Ingham } 1779893c932aSJim Ingham 1780893c932aSJim Ingham Target * 178133df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) 1782893c932aSJim Ingham { 178333df7cd3SJim Ingham Target *target = nullptr; 178433df7cd3SJim Ingham if (!prefer_dummy) 178533df7cd3SJim Ingham { 178633df7cd3SJim Ingham target = m_target_list.GetSelectedTarget().get(); 178733df7cd3SJim Ingham if (target) 178833df7cd3SJim Ingham return target; 178933df7cd3SJim Ingham } 1790893c932aSJim Ingham 1791893c932aSJim Ingham return GetDummyTarget(); 1792893c932aSJim Ingham } 179344d93782SGreg Clayton 1794