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" 184becb37eSEnrico Granata 1930fdc8d8SChris Lattner #include "lldb/lldb-private.h" 2030fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h" 211f746071SGreg Clayton #include "lldb/Core/Module.h" 22e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h" 237349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 2430fdc8d8SChris Lattner #include "lldb/Core/State.h" 255b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h" 26228063cdSJim Ingham #include "lldb/Core/StreamCallback.h" 2744d93782SGreg Clayton #include "lldb/Core/StreamFile.h" 281b654882SGreg Clayton #include "lldb/Core/StreamString.h" 2930fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 304becb37eSEnrico Granata #include "lldb/Core/ValueObject.h" 316d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 325548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 335548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h" 3421dfcd9dSEnrico Granata #include "lldb/Host/DynamicLibrary.h" 35a3406614SGreg Clayton #include "lldb/Host/Terminal.h" 366611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 3767cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h" 3867cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 391f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h" 401f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 411f746071SGreg Clayton #include "lldb/Symbol/Function.h" 421f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 436d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h" 4430fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 4530fdc8d8SChris Lattner #include "lldb/Target/Process.h" 461b654882SGreg Clayton #include "lldb/Target/RegisterContext.h" 475fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h" 481b654882SGreg Clayton #include "lldb/Target/StopInfo.h" 4984a53dfbSEnrico Granata #include "lldb/Target/Target.h" 5030fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 515a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h" 5230fdc8d8SChris Lattner 5330fdc8d8SChris Lattner using namespace lldb; 5430fdc8d8SChris Lattner using namespace lldb_private; 5530fdc8d8SChris Lattner 5630fdc8d8SChris Lattner 571b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0; 58ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1; 59ebc1bb27SCaroline Tice 601b654882SGreg Clayton #pragma mark Static Functions 611b654882SGreg Clayton 621b654882SGreg Clayton static Mutex & 631b654882SGreg Clayton GetDebuggerListMutex () 641b654882SGreg Clayton { 651b654882SGreg Clayton static Mutex g_mutex(Mutex::eMutexTypeRecursive); 661b654882SGreg Clayton return g_mutex; 671b654882SGreg Clayton } 681b654882SGreg Clayton 691b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList; 701b654882SGreg Clayton 711b654882SGreg Clayton static DebuggerList & 721b654882SGreg Clayton GetDebuggerList() 731b654882SGreg Clayton { 741b654882SGreg Clayton // hide the static debugger list inside a singleton accessor to avoid 751b654882SGreg Clayton // global init contructors 761b654882SGreg Clayton static DebuggerList g_list; 771b654882SGreg Clayton return g_list; 781b654882SGreg Clayton } 79e372b98dSGreg Clayton 80e372b98dSGreg Clayton OptionEnumValueElement 8167cc0636SGreg Clayton g_show_disassembly_enum_values[] = 82e372b98dSGreg Clayton { 8367cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, 8467cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, 8567cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, 86e372b98dSGreg Clayton { 0, NULL, NULL } 87e372b98dSGreg Clayton }; 88e372b98dSGreg Clayton 8967cc0636SGreg Clayton OptionEnumValueElement 9067cc0636SGreg Clayton g_language_enumerators[] = 9167cc0636SGreg Clayton { 9267cc0636SGreg Clayton { eScriptLanguageNone, "none", "Disable scripting languages."}, 9367cc0636SGreg Clayton { eScriptLanguagePython, "python", "Select python as the default scripting language."}, 9467cc0636SGreg Clayton { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."}, 95a12993c9SGreg Clayton { 0, NULL, NULL } 9667cc0636SGreg Clayton }; 97e372b98dSGreg Clayton 9867cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" 9967cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 10067cc0636SGreg Clayton 1010769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ 10267cc0636SGreg Clayton "{, ${frame.pc}}"\ 10367cc0636SGreg Clayton MODULE_WITH_FUNC\ 10467cc0636SGreg Clayton FILE_AND_LINE\ 1050769b2b1SMichael Sartain "{, name = '${thread.name}'}"\ 1060769b2b1SMichael Sartain "{, queue = '${thread.queue}'}"\ 10767cc0636SGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 10867cc0636SGreg Clayton "{\\nReturn value: ${thread.return-value}}"\ 10967cc0636SGreg Clayton "\\n" 11067cc0636SGreg Clayton 11167cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 11267cc0636SGreg Clayton MODULE_WITH_FUNC\ 11367cc0636SGreg Clayton FILE_AND_LINE\ 11467cc0636SGreg Clayton "\\n" 11567cc0636SGreg Clayton 11667cc0636SGreg Clayton 11767cc0636SGreg Clayton 118754a9369SGreg Clayton static PropertyDefinition 119754a9369SGreg Clayton g_properties[] = 12067cc0636SGreg Clayton { 12167cc0636SGreg Clayton { "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, 12267cc0636SGreg Clayton { "frame-format", OptionValue::eTypeString , true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." }, 12367cc0636SGreg Clayton { "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, 1244c05410fSGreg Clayton { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 12567cc0636SGreg Clayton { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 12667cc0636SGreg Clayton { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, 12767cc0636SGreg 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." }, 12867cc0636SGreg 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." }, 12967cc0636SGreg 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." }, 13067cc0636SGreg Clayton { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, 13167cc0636SGreg Clayton { "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." }, 13267cc0636SGreg Clayton { "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." }, 133c3ce7f27SMichael Sartain { "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." }, 13490a8db30SEnrico 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)." }, 135e8cd0c98SGreg Clayton 13667cc0636SGreg Clayton { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 13767cc0636SGreg Clayton }; 13867cc0636SGreg Clayton 13967cc0636SGreg Clayton enum 14067cc0636SGreg Clayton { 14167cc0636SGreg Clayton ePropertyAutoConfirm = 0, 14267cc0636SGreg Clayton ePropertyFrameFormat, 14367cc0636SGreg Clayton ePropertyNotiftVoid, 14467cc0636SGreg Clayton ePropertyPrompt, 14567cc0636SGreg Clayton ePropertyScriptLanguage, 14667cc0636SGreg Clayton ePropertyStopDisassemblyCount, 14767cc0636SGreg Clayton ePropertyStopDisassemblyDisplay, 14867cc0636SGreg Clayton ePropertyStopLineCountAfter, 14967cc0636SGreg Clayton ePropertyStopLineCountBefore, 15067cc0636SGreg Clayton ePropertyTerminalWidth, 15167cc0636SGreg Clayton ePropertyThreadFormat, 152c3ce7f27SMichael Sartain ePropertyUseExternalEditor, 153c3ce7f27SMichael Sartain ePropertyUseColor, 15490a8db30SEnrico Granata ePropertyAutoOneLineSummaries 15567cc0636SGreg Clayton }; 15667cc0636SGreg Clayton 1575fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL; 1584c05410fSGreg Clayton 1594c05410fSGreg Clayton Error 1604c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 1614c05410fSGreg Clayton VarSetOperationType op, 1624c05410fSGreg Clayton const char *property_path, 1634c05410fSGreg Clayton const char *value) 1644c05410fSGreg Clayton { 16584a53dfbSEnrico Granata bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0; 16684a53dfbSEnrico Granata TargetSP target_sp; 167397ddd5fSEnrico Granata LoadScriptFromSymFile load_script_old_value; 16884a53dfbSEnrico Granata if (is_load_script && exe_ctx->GetTargetSP()) 16984a53dfbSEnrico Granata { 17084a53dfbSEnrico Granata target_sp = exe_ctx->GetTargetSP(); 17184a53dfbSEnrico Granata load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 17284a53dfbSEnrico Granata } 1734c05410fSGreg Clayton Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 1744c05410fSGreg Clayton if (error.Success()) 1754c05410fSGreg Clayton { 17684a53dfbSEnrico Granata // FIXME it would be nice to have "on-change" callbacks for properties 1774c05410fSGreg Clayton if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 1784c05410fSGreg Clayton { 1794c05410fSGreg Clayton const char *new_prompt = GetPrompt(); 180c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 181c3ce7f27SMichael Sartain if (str.length()) 182c3ce7f27SMichael Sartain new_prompt = str.c_str(); 18344d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 1844c05410fSGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 1854c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 1864c05410fSGreg Clayton } 187c3ce7f27SMichael Sartain else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0) 188c3ce7f27SMichael Sartain { 189c3ce7f27SMichael Sartain // use-color changed. Ping the prompt so it can reset the ansi terminal codes. 190c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 191c3ce7f27SMichael Sartain } 192397ddd5fSEnrico Granata else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) 19384a53dfbSEnrico Granata { 194397ddd5fSEnrico Granata if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue) 19584a53dfbSEnrico Granata { 19684a53dfbSEnrico Granata std::list<Error> errors; 1979730339bSEnrico Granata StreamString feedback_stream; 1989730339bSEnrico Granata if (!target_sp->LoadScriptingResources(errors,&feedback_stream)) 19984a53dfbSEnrico Granata { 20044d93782SGreg Clayton StreamFileSP stream_sp (GetErrorFile()); 20144d93782SGreg Clayton if (stream_sp) 20244d93782SGreg Clayton { 20384a53dfbSEnrico Granata for (auto error : errors) 20484a53dfbSEnrico Granata { 20544d93782SGreg Clayton stream_sp->Printf("%s\n",error.AsCString()); 20684a53dfbSEnrico Granata } 2079730339bSEnrico Granata if (feedback_stream.GetSize()) 20844d93782SGreg Clayton stream_sp->Printf("%s",feedback_stream.GetData()); 20944d93782SGreg Clayton } 21084a53dfbSEnrico Granata } 21184a53dfbSEnrico Granata } 21284a53dfbSEnrico Granata } 2134c05410fSGreg Clayton } 2144c05410fSGreg Clayton return error; 2154c05410fSGreg Clayton } 2164c05410fSGreg Clayton 21767cc0636SGreg Clayton bool 21867cc0636SGreg Clayton Debugger::GetAutoConfirm () const 21967cc0636SGreg Clayton { 22067cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 221754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 22267cc0636SGreg Clayton } 22367cc0636SGreg Clayton 22467cc0636SGreg Clayton const char * 22567cc0636SGreg Clayton Debugger::GetFrameFormat() const 22667cc0636SGreg Clayton { 22767cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 228754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 22967cc0636SGreg Clayton } 23067cc0636SGreg Clayton 23167cc0636SGreg Clayton bool 23267cc0636SGreg Clayton Debugger::GetNotifyVoid () const 23367cc0636SGreg Clayton { 23467cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 235754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 23667cc0636SGreg Clayton } 23767cc0636SGreg Clayton 23867cc0636SGreg Clayton const char * 23967cc0636SGreg Clayton Debugger::GetPrompt() const 24067cc0636SGreg Clayton { 24167cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 242754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 24367cc0636SGreg Clayton } 24467cc0636SGreg Clayton 24567cc0636SGreg Clayton void 24667cc0636SGreg Clayton Debugger::SetPrompt(const char *p) 24767cc0636SGreg Clayton { 24867cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 24967cc0636SGreg Clayton m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 25067cc0636SGreg Clayton const char *new_prompt = GetPrompt(); 251c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 252c3ce7f27SMichael Sartain if (str.length()) 253c3ce7f27SMichael Sartain new_prompt = str.c_str(); 25444d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 25567cc0636SGreg Clayton } 25667cc0636SGreg Clayton 25767cc0636SGreg Clayton const char * 25867cc0636SGreg Clayton Debugger::GetThreadFormat() const 25967cc0636SGreg Clayton { 26067cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 261754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 26267cc0636SGreg Clayton } 26367cc0636SGreg Clayton 26467cc0636SGreg Clayton lldb::ScriptLanguage 26567cc0636SGreg Clayton Debugger::GetScriptLanguage() const 26667cc0636SGreg Clayton { 26767cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 268754a9369SGreg Clayton return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 26967cc0636SGreg Clayton } 27067cc0636SGreg Clayton 27167cc0636SGreg Clayton bool 27267cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 27367cc0636SGreg Clayton { 27467cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 27567cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 27667cc0636SGreg Clayton } 27767cc0636SGreg Clayton 27867cc0636SGreg Clayton uint32_t 27967cc0636SGreg Clayton Debugger::GetTerminalWidth () const 28067cc0636SGreg Clayton { 28167cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 282754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 28367cc0636SGreg Clayton } 28467cc0636SGreg Clayton 28567cc0636SGreg Clayton bool 28667cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width) 28767cc0636SGreg Clayton { 28867cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 28967cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 29067cc0636SGreg Clayton } 29167cc0636SGreg Clayton 29267cc0636SGreg Clayton bool 29367cc0636SGreg Clayton Debugger::GetUseExternalEditor () const 29467cc0636SGreg Clayton { 29567cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 296754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 29767cc0636SGreg Clayton } 29867cc0636SGreg Clayton 29967cc0636SGreg Clayton bool 30067cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b) 30167cc0636SGreg Clayton { 30267cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 30367cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 30467cc0636SGreg Clayton } 30567cc0636SGreg Clayton 306c3ce7f27SMichael Sartain bool 307c3ce7f27SMichael Sartain Debugger::GetUseColor () const 308c3ce7f27SMichael Sartain { 309c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 310c3ce7f27SMichael Sartain return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 311c3ce7f27SMichael Sartain } 312c3ce7f27SMichael Sartain 313c3ce7f27SMichael Sartain bool 314c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b) 315c3ce7f27SMichael Sartain { 316c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 317c3ce7f27SMichael Sartain bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 318c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 319c3ce7f27SMichael Sartain return ret; 320c3ce7f27SMichael Sartain } 321c3ce7f27SMichael Sartain 32267cc0636SGreg Clayton uint32_t 32367cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const 32467cc0636SGreg Clayton { 32567cc0636SGreg Clayton const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 326754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 32767cc0636SGreg Clayton } 32867cc0636SGreg Clayton 32967cc0636SGreg Clayton Debugger::StopDisassemblyType 33067cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const 33167cc0636SGreg Clayton { 33267cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 333754a9369SGreg Clayton return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 33467cc0636SGreg Clayton } 33567cc0636SGreg Clayton 33667cc0636SGreg Clayton uint32_t 33767cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const 33867cc0636SGreg Clayton { 33967cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 340754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 34167cc0636SGreg Clayton } 342e372b98dSGreg Clayton 343553fad5cSEnrico Granata bool 34490a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const 345553fad5cSEnrico Granata { 34690a8db30SEnrico Granata const uint32_t idx = ePropertyAutoOneLineSummaries; 347553fad5cSEnrico Granata return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); 348553fad5cSEnrico Granata 349553fad5cSEnrico Granata } 350553fad5cSEnrico Granata 3511b654882SGreg Clayton #pragma mark Debugger 3521b654882SGreg Clayton 35367cc0636SGreg Clayton //const DebuggerPropertiesSP & 35467cc0636SGreg Clayton //Debugger::GetSettings() const 35567cc0636SGreg Clayton //{ 35667cc0636SGreg Clayton // return m_properties_sp; 35767cc0636SGreg Clayton //} 35867cc0636SGreg Clayton // 35999d0faf2SGreg Clayton 3602f88aadfSCaroline Tice int 3612f88aadfSCaroline Tice Debugger::TestDebuggerRefCount () 3622f88aadfSCaroline Tice { 3632f88aadfSCaroline Tice return g_shared_debugger_refcount; 3642f88aadfSCaroline Tice } 3652f88aadfSCaroline Tice 36630fdc8d8SChris Lattner void 3675fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback) 36830fdc8d8SChris Lattner { 3695fb8f797SGreg Clayton g_load_plugin_callback = load_plugin_callback; 370c15f55e2SGreg Clayton if (g_shared_debugger_refcount++ == 0) 371dbe54508SGreg Clayton lldb_private::Initialize(); 37299d0faf2SGreg Clayton } 37330fdc8d8SChris Lattner 37430fdc8d8SChris Lattner void 37530fdc8d8SChris Lattner Debugger::Terminate () 37630fdc8d8SChris Lattner { 3776611103cSGreg Clayton if (g_shared_debugger_refcount > 0) 3786611103cSGreg Clayton { 37930fdc8d8SChris Lattner g_shared_debugger_refcount--; 38030fdc8d8SChris Lattner if (g_shared_debugger_refcount == 0) 38130fdc8d8SChris Lattner { 382dbe54508SGreg Clayton lldb_private::WillTerminate(); 383dbe54508SGreg Clayton lldb_private::Terminate(); 3846760a517SCaroline Tice 38599d0faf2SGreg Clayton // Clear our master list of debugger objects 38699d0faf2SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 38799d0faf2SGreg Clayton GetDebuggerList().clear(); 38830fdc8d8SChris Lattner } 3896760a517SCaroline Tice } 3906760a517SCaroline Tice } 39130fdc8d8SChris Lattner 39220bd37f7SCaroline Tice void 39320bd37f7SCaroline Tice Debugger::SettingsInitialize () 39420bd37f7SCaroline Tice { 3956920b52bSGreg Clayton Target::SettingsInitialize (); 39620bd37f7SCaroline Tice } 39720bd37f7SCaroline Tice 39820bd37f7SCaroline Tice void 39920bd37f7SCaroline Tice Debugger::SettingsTerminate () 40020bd37f7SCaroline Tice { 4016920b52bSGreg Clayton Target::SettingsTerminate (); 40220bd37f7SCaroline Tice } 40320bd37f7SCaroline Tice 40421dfcd9dSEnrico Granata bool 405e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error) 40621dfcd9dSEnrico Granata { 4075fb8f797SGreg Clayton if (g_load_plugin_callback) 408e743c782SEnrico Granata { 4095fb8f797SGreg Clayton lldb::DynamicLibrarySP dynlib_sp = g_load_plugin_callback (shared_from_this(), spec, error); 4105fb8f797SGreg Clayton if (dynlib_sp) 41121dfcd9dSEnrico Granata { 41221dfcd9dSEnrico Granata m_loaded_plugins.push_back(dynlib_sp); 41321dfcd9dSEnrico Granata return true; 41421dfcd9dSEnrico Granata } 4155fb8f797SGreg Clayton } 4165fb8f797SGreg Clayton else 4175fb8f797SGreg Clayton { 4185fb8f797SGreg Clayton // The g_load_plugin_callback is registered in SBDebugger::Initialize() 4195fb8f797SGreg Clayton // and if the public API layer isn't available (code is linking against 4205fb8f797SGreg Clayton // all of the internal LLDB static libraries), then we can't load plugins 4215fb8f797SGreg Clayton error.SetErrorString("Public API layer is not available"); 4225fb8f797SGreg Clayton } 42321dfcd9dSEnrico Granata return false; 42421dfcd9dSEnrico Granata } 42521dfcd9dSEnrico Granata 42621dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 42721dfcd9dSEnrico Granata LoadPluginCallback 42821dfcd9dSEnrico Granata ( 42921dfcd9dSEnrico Granata void *baton, 43021dfcd9dSEnrico Granata FileSpec::FileType file_type, 43121dfcd9dSEnrico Granata const FileSpec &file_spec 43221dfcd9dSEnrico Granata ) 43321dfcd9dSEnrico Granata { 43421dfcd9dSEnrico Granata Error error; 43521dfcd9dSEnrico Granata 43621dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 4373cf443ddSMichael Sartain static ConstString g_solibext("so"); 43821dfcd9dSEnrico Granata 43921dfcd9dSEnrico Granata if (!baton) 44021dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 44121dfcd9dSEnrico Granata 44221dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 44321dfcd9dSEnrico Granata 44421dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 44521dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 44621dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 44721dfcd9dSEnrico Granata // file type information. 44821dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 44921dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 45021dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 45121dfcd9dSEnrico Granata { 45221dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 45321dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 45421dfcd9dSEnrico Granata 4553cf443ddSMichael Sartain if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 4563cf443ddSMichael Sartain plugin_file_spec.GetFileNameExtension() != g_solibext) 4573cf443ddSMichael Sartain { 45821dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 4593cf443ddSMichael Sartain } 46021dfcd9dSEnrico Granata 461e743c782SEnrico Granata Error plugin_load_error; 462e743c782SEnrico Granata debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 46321dfcd9dSEnrico Granata 46421dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 46521dfcd9dSEnrico Granata } 46621dfcd9dSEnrico Granata 46721dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 46821dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 46921dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 47021dfcd9dSEnrico Granata { 47121dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 47221dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 47321dfcd9dSEnrico Granata // might be enurating a file system that doesn't have correct file type 47421dfcd9dSEnrico Granata // information. 47521dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 47621dfcd9dSEnrico Granata } 47721dfcd9dSEnrico Granata 47821dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 47921dfcd9dSEnrico Granata } 48021dfcd9dSEnrico Granata 48121dfcd9dSEnrico Granata void 48221dfcd9dSEnrico Granata Debugger::InstanceInitialize () 48321dfcd9dSEnrico Granata { 48421dfcd9dSEnrico Granata FileSpec dir_spec; 48521dfcd9dSEnrico Granata const bool find_directories = true; 48621dfcd9dSEnrico Granata const bool find_files = true; 48721dfcd9dSEnrico Granata const bool find_other = true; 48821dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 48921dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 49021dfcd9dSEnrico Granata { 49121dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 49221dfcd9dSEnrico Granata { 49321dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 49421dfcd9dSEnrico Granata find_directories, 49521dfcd9dSEnrico Granata find_files, 49621dfcd9dSEnrico Granata find_other, 49721dfcd9dSEnrico Granata LoadPluginCallback, 49821dfcd9dSEnrico Granata this); 49921dfcd9dSEnrico Granata } 50021dfcd9dSEnrico Granata } 50121dfcd9dSEnrico Granata 50221dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 50321dfcd9dSEnrico Granata { 50421dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 50521dfcd9dSEnrico Granata { 50621dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 50721dfcd9dSEnrico Granata find_directories, 50821dfcd9dSEnrico Granata find_files, 50921dfcd9dSEnrico Granata find_other, 51021dfcd9dSEnrico Granata LoadPluginCallback, 51121dfcd9dSEnrico Granata this); 51221dfcd9dSEnrico Granata } 51321dfcd9dSEnrico Granata } 514e8cd0c98SGreg Clayton 515e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 51621dfcd9dSEnrico Granata } 51721dfcd9dSEnrico Granata 5186611103cSGreg Clayton DebuggerSP 519228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 5206611103cSGreg Clayton { 521228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 522c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 5236611103cSGreg Clayton { 5246611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5256611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 5266611103cSGreg Clayton } 52721dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 5286611103cSGreg Clayton return debugger_sp; 5296611103cSGreg Clayton } 5306611103cSGreg Clayton 531e02657b1SCaroline Tice void 5324d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 533e02657b1SCaroline Tice { 534e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 535e02657b1SCaroline Tice return; 536e02657b1SCaroline Tice 5378314c525SJim Ingham debugger_sp->Clear(); 5388314c525SJim Ingham 539c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 540c15f55e2SGreg Clayton { 541e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 542e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 543e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 544e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 545e02657b1SCaroline Tice { 546e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 547e02657b1SCaroline Tice { 548e02657b1SCaroline Tice debugger_list.erase (pos); 549e02657b1SCaroline Tice return; 550e02657b1SCaroline Tice } 551e02657b1SCaroline Tice } 552e02657b1SCaroline Tice } 553c15f55e2SGreg Clayton } 554e02657b1SCaroline Tice 5554d122c40SGreg Clayton DebuggerSP 5563df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 5573df9a8dfSCaroline Tice { 5584d122c40SGreg Clayton DebuggerSP debugger_sp; 5596920b52bSGreg Clayton if (g_shared_debugger_refcount > 0) 5606920b52bSGreg Clayton { 5616920b52bSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5626920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5636920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5646920b52bSGreg Clayton 5656920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5666920b52bSGreg Clayton { 5676920b52bSGreg Clayton if ((*pos).get()->m_instance_name == instance_name) 5686920b52bSGreg Clayton { 5696920b52bSGreg Clayton debugger_sp = *pos; 5706920b52bSGreg Clayton break; 5716920b52bSGreg Clayton } 5726920b52bSGreg Clayton } 5736920b52bSGreg Clayton } 5743df9a8dfSCaroline Tice return debugger_sp; 5753df9a8dfSCaroline Tice } 5766611103cSGreg Clayton 5776611103cSGreg Clayton TargetSP 5786611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 5796611103cSGreg Clayton { 5804d122c40SGreg Clayton TargetSP target_sp; 581c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 582c15f55e2SGreg Clayton { 5836611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5846611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5856611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5866611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5876611103cSGreg Clayton { 5886611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 5896611103cSGreg Clayton if (target_sp) 5906611103cSGreg Clayton break; 5916611103cSGreg Clayton } 592c15f55e2SGreg Clayton } 5936611103cSGreg Clayton return target_sp; 5946611103cSGreg Clayton } 5956611103cSGreg Clayton 596e4e45924SGreg Clayton TargetSP 597e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 598e4e45924SGreg Clayton { 599e4e45924SGreg Clayton TargetSP target_sp; 600c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 601c15f55e2SGreg Clayton { 602e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 603e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 604e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 605e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 606e4e45924SGreg Clayton { 607e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 608e4e45924SGreg Clayton if (target_sp) 609e4e45924SGreg Clayton break; 610e4e45924SGreg Clayton } 611c15f55e2SGreg Clayton } 612e4e45924SGreg Clayton return target_sp; 613e4e45924SGreg Clayton } 614e4e45924SGreg Clayton 615228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 616ebc1bb27SCaroline Tice UserID (g_unique_id++), 61767cc0636SGreg Clayton Properties(OptionValuePropertiesSP(new OptionValueProperties())), 61844d93782SGreg Clayton m_input_file_sp (new StreamFile (stdin, false)), 61944d93782SGreg Clayton m_output_file_sp (new StreamFile (stdout, false)), 62044d93782SGreg Clayton m_error_file_sp (new StreamFile (stderr, false)), 621c5917d9aSJim Ingham m_terminal_state (), 6224bddaeb5SJim Ingham m_target_list (*this), 623ded470d3SGreg Clayton m_platform_list (), 62430fdc8d8SChris Lattner m_listener ("lldb.Debugger"), 6259585fbfcSGreg Clayton m_source_manager_ap(), 626e37d605eSJim Ingham m_source_file_cache(), 6276611103cSGreg Clayton m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 628d5a0a01bSCaroline Tice m_input_reader_stack (), 62944d93782SGreg Clayton m_instance_name (), 63044d93782SGreg Clayton m_loaded_plugins (), 63144d93782SGreg Clayton m_event_handler_thread (LLDB_INVALID_HOST_THREAD), 63244d93782SGreg Clayton m_io_handler_thread (LLDB_INVALID_HOST_THREAD), 63344d93782SGreg Clayton m_event_handler_thread_alive(false) 63430fdc8d8SChris Lattner { 63567cc0636SGreg Clayton char instance_cstr[256]; 63667cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 63767cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 638228063cdSJim Ingham if (log_callback) 639228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 6406611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 641ded470d3SGreg Clayton // Always add our default platform to the platform list 642ded470d3SGreg Clayton PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 643ded470d3SGreg Clayton assert (default_platform_sp.get()); 644ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 64567cc0636SGreg Clayton 646754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 64767cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 64867cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 64967cc0636SGreg Clayton true, 65067cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 651754a9369SGreg Clayton if (m_command_interpreter_ap.get()) 652754a9369SGreg Clayton { 653754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 654754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 655754a9369SGreg Clayton true, 656754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 657754a9369SGreg Clayton } 65867cc0636SGreg Clayton OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 65967cc0636SGreg Clayton term_width->SetMinimumValue(10); 66067cc0636SGreg Clayton term_width->SetMaximumValue(1024); 661c3ce7f27SMichael Sartain 662c3ce7f27SMichael Sartain // Turn off use-color if this is a dumb terminal. 663c3ce7f27SMichael Sartain const char *term = getenv ("TERM"); 664c3ce7f27SMichael Sartain if (term && !strcmp (term, "dumb")) 665c3ce7f27SMichael Sartain SetUseColor (false); 66630fdc8d8SChris Lattner } 66730fdc8d8SChris Lattner 66830fdc8d8SChris Lattner Debugger::~Debugger () 66930fdc8d8SChris Lattner { 6708314c525SJim Ingham Clear(); 6718314c525SJim Ingham } 6728314c525SJim Ingham 6738314c525SJim Ingham void 6748314c525SJim Ingham Debugger::Clear() 6758314c525SJim Ingham { 67644d93782SGreg Clayton ClearIOHandlers(); 67744d93782SGreg Clayton StopIOHandlerThread(); 67844d93782SGreg Clayton StopEventHandlerThread(); 6791ed54f50SGreg Clayton m_listener.Clear(); 6806611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 6816611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 6826611103cSGreg Clayton { 683ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 684ccbc08e6SGreg Clayton if (target_sp) 685ccbc08e6SGreg Clayton { 686ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 6876611103cSGreg Clayton if (process_sp) 6881fd07059SJim Ingham process_sp->Finalize(); 689ccbc08e6SGreg Clayton target_sp->Destroy(); 6906611103cSGreg Clayton } 69130fdc8d8SChris Lattner } 6924bddaeb5SJim Ingham BroadcasterManager::Clear (); 69330fdc8d8SChris Lattner 6940d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 6950d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 696c5917d9aSJim Ingham m_terminal_state.Clear(); 69744d93782SGreg Clayton if (m_input_file_sp) 69844d93782SGreg Clayton m_input_file_sp->GetFile().Close (); 6998314c525SJim Ingham } 70030fdc8d8SChris Lattner 70130fdc8d8SChris Lattner bool 702fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 703fc3f027dSGreg Clayton { 70444d93782SGreg Clayton // return m_input_comm.GetCloseOnEOF(); 70544d93782SGreg Clayton return false; 706fc3f027dSGreg Clayton } 707fc3f027dSGreg Clayton 708fc3f027dSGreg Clayton void 709fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 710fc3f027dSGreg Clayton { 71144d93782SGreg Clayton // m_input_comm.SetCloseOnEOF(b); 712fc3f027dSGreg Clayton } 713fc3f027dSGreg Clayton 714fc3f027dSGreg Clayton bool 71530fdc8d8SChris Lattner Debugger::GetAsyncExecution () 71630fdc8d8SChris Lattner { 7176611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 71830fdc8d8SChris Lattner } 71930fdc8d8SChris Lattner 72030fdc8d8SChris Lattner void 72130fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 72230fdc8d8SChris Lattner { 7236611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 72430fdc8d8SChris Lattner } 72530fdc8d8SChris Lattner 72630fdc8d8SChris Lattner 72730fdc8d8SChris Lattner void 72830fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 72930fdc8d8SChris Lattner { 73044d93782SGreg Clayton if (m_input_file_sp) 73144d93782SGreg Clayton m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership); 73244d93782SGreg Clayton else 73344d93782SGreg Clayton m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 73444d93782SGreg Clayton 73544d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 73651b1e2d2SGreg Clayton if (in_file.IsValid() == false) 73751b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 73830fdc8d8SChris Lattner 739c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 740c5917d9aSJim Ingham SaveInputTerminalState (); 74130fdc8d8SChris Lattner } 74230fdc8d8SChris Lattner 74330fdc8d8SChris Lattner void 74430fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 74530fdc8d8SChris Lattner { 74644d93782SGreg Clayton if (m_output_file_sp) 74744d93782SGreg Clayton m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership); 74844d93782SGreg Clayton else 74944d93782SGreg Clayton m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 75044d93782SGreg Clayton 75144d93782SGreg Clayton File &out_file = m_output_file_sp->GetFile(); 75251b1e2d2SGreg Clayton if (out_file.IsValid() == false) 75351b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 7542f88aadfSCaroline Tice 755b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 756b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 757b588726eSEnrico Granata const bool can_create = false; 758b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 759b588726eSEnrico Granata if (script_interpreter) 760b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 76130fdc8d8SChris Lattner } 76230fdc8d8SChris Lattner 76330fdc8d8SChris Lattner void 76430fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 76530fdc8d8SChris Lattner { 76644d93782SGreg Clayton if (m_error_file_sp) 76744d93782SGreg Clayton m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership); 76844d93782SGreg Clayton else 76944d93782SGreg Clayton m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 77044d93782SGreg Clayton 77144d93782SGreg Clayton File &err_file = m_error_file_sp->GetFile(); 77251b1e2d2SGreg Clayton if (err_file.IsValid() == false) 77351b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 77430fdc8d8SChris Lattner } 77530fdc8d8SChris Lattner 776c5917d9aSJim Ingham void 777c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 778c5917d9aSJim Ingham { 77944d93782SGreg Clayton if (m_input_file_sp) 78044d93782SGreg Clayton { 78144d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 782c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 783c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 784c5917d9aSJim Ingham } 78544d93782SGreg Clayton } 786c5917d9aSJim Ingham 787c5917d9aSJim Ingham void 788c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 789c5917d9aSJim Ingham { 790c5917d9aSJim Ingham m_terminal_state.Restore(); 791c5917d9aSJim Ingham } 792c5917d9aSJim Ingham 79330fdc8d8SChris Lattner ExecutionContext 7942976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 79530fdc8d8SChris Lattner { 79630fdc8d8SChris Lattner ExecutionContext exe_ctx; 797c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 798c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 79930fdc8d8SChris Lattner 80030fdc8d8SChris Lattner if (target_sp) 80130fdc8d8SChris Lattner { 802c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 803c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 804c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 80530fdc8d8SChris Lattner { 806c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 807c14ee32dSGreg Clayton if (thread_sp) 80830fdc8d8SChris Lattner { 809c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 810c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 811c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 812c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 81330fdc8d8SChris Lattner } 81430fdc8d8SChris Lattner } 81530fdc8d8SChris Lattner } 81630fdc8d8SChris Lattner return exe_ctx; 81730fdc8d8SChris Lattner } 81830fdc8d8SChris Lattner 81930fdc8d8SChris Lattner void 820efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 821efed6131SCaroline Tice { 82244d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 82344d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 824efed6131SCaroline Tice if (reader_sp) 82544d93782SGreg Clayton reader_sp->Interrupt(); 826efed6131SCaroline Tice } 827efed6131SCaroline Tice 828efed6131SCaroline Tice void 829efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 830efed6131SCaroline Tice { 83144d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 83244d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 833efed6131SCaroline Tice if (reader_sp) 83444d93782SGreg Clayton reader_sp->GotEOF(); 835efed6131SCaroline Tice } 836efed6131SCaroline Tice 837efed6131SCaroline Tice void 83844d93782SGreg Clayton Debugger::ClearIOHandlers () 8393d6086f6SCaroline Tice { 840b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 84144d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 842d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 8433d6086f6SCaroline Tice { 84444d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 8453d6086f6SCaroline Tice if (reader_sp) 8463d6086f6SCaroline Tice { 84744d93782SGreg Clayton m_input_reader_stack.Pop(); 8483d6086f6SCaroline Tice reader_sp->SetIsDone(true); 84944d93782SGreg Clayton reader_sp->Interrupt(); 8503d6086f6SCaroline Tice } 8513d6086f6SCaroline Tice } 8523d6086f6SCaroline Tice } 8533d6086f6SCaroline Tice 8543d6086f6SCaroline Tice void 85544d93782SGreg Clayton Debugger::ExecuteIOHanders() 856969ed3d1SCaroline Tice { 85744d93782SGreg Clayton 85844d93782SGreg Clayton while (1) 859969ed3d1SCaroline Tice { 86044d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 86130fdc8d8SChris Lattner if (!reader_sp) 86230fdc8d8SChris Lattner break; 86330fdc8d8SChris Lattner 86444d93782SGreg Clayton reader_sp->Activate(); 86544d93782SGreg Clayton reader_sp->Run(); 86644d93782SGreg Clayton reader_sp->Deactivate(); 86744d93782SGreg Clayton 86844d93782SGreg Clayton // Remove all input readers that are done from the top of the stack 86944d93782SGreg Clayton while (1) 87030fdc8d8SChris Lattner { 87144d93782SGreg Clayton IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); 87244d93782SGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 87344d93782SGreg Clayton m_input_reader_stack.Pop(); 87430fdc8d8SChris Lattner else 87530fdc8d8SChris Lattner break; 87630fdc8d8SChris Lattner } 87730fdc8d8SChris Lattner } 87844d93782SGreg Clayton ClearIOHandlers(); 87944d93782SGreg Clayton } 88030fdc8d8SChris Lattner 88144d93782SGreg Clayton bool 88244d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp) 88344d93782SGreg Clayton { 88444d93782SGreg Clayton return m_input_reader_stack.IsTop (reader_sp); 88544d93782SGreg Clayton } 88630fdc8d8SChris Lattner 88744d93782SGreg Clayton 88844d93782SGreg Clayton ConstString 88944d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch) 89044d93782SGreg Clayton { 89144d93782SGreg Clayton return m_input_reader_stack.GetTopIOHandlerControlSequence (ch); 89230fdc8d8SChris Lattner } 89330fdc8d8SChris Lattner 89430fdc8d8SChris Lattner void 89544d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp) 89644d93782SGreg Clayton { 89744d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 89844d93782SGreg Clayton PushIOHandler (reader_sp); 89944d93782SGreg Clayton reader_sp->Activate(); 90044d93782SGreg Clayton reader_sp->Run(); 90144d93782SGreg Clayton PopIOHandler (reader_sp); 90244d93782SGreg Clayton } 90344d93782SGreg Clayton 90444d93782SGreg Clayton void 90544d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err) 90644d93782SGreg Clayton { 90744d93782SGreg Clayton // Before an IOHandler runs, it must have in/out/err streams. 90844d93782SGreg Clayton // This function is called when one ore more of the streams 90944d93782SGreg Clayton // are NULL. We use the top input reader's in/out/err streams, 91044d93782SGreg Clayton // or fall back to the debugger file handles, or we fall back 91144d93782SGreg Clayton // onto stdin/stdout/stderr as a last resort. 91244d93782SGreg Clayton 91344d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 91444d93782SGreg Clayton IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 91544d93782SGreg Clayton // If no STDIN has been set, then set it appropriately 91644d93782SGreg Clayton if (!in) 91744d93782SGreg Clayton { 91844d93782SGreg Clayton if (top_reader_sp) 91944d93782SGreg Clayton in = top_reader_sp->GetInputStreamFile(); 92044d93782SGreg Clayton else 92144d93782SGreg Clayton in = GetInputFile(); 92244d93782SGreg Clayton 92344d93782SGreg Clayton // If there is nothing, use stdin 92444d93782SGreg Clayton if (!in) 92544d93782SGreg Clayton in = StreamFileSP(new StreamFile(stdin, false)); 92644d93782SGreg Clayton } 92744d93782SGreg Clayton // If no STDOUT has been set, then set it appropriately 92844d93782SGreg Clayton if (!out) 92944d93782SGreg Clayton { 93044d93782SGreg Clayton if (top_reader_sp) 93144d93782SGreg Clayton out = top_reader_sp->GetOutputStreamFile(); 93244d93782SGreg Clayton else 93344d93782SGreg Clayton out = GetOutputFile(); 93444d93782SGreg Clayton 93544d93782SGreg Clayton // If there is nothing, use stdout 93644d93782SGreg Clayton if (!out) 93744d93782SGreg Clayton out = StreamFileSP(new StreamFile(stdout, false)); 93844d93782SGreg Clayton } 93944d93782SGreg Clayton // If no STDERR has been set, then set it appropriately 94044d93782SGreg Clayton if (!err) 94144d93782SGreg Clayton { 94244d93782SGreg Clayton if (top_reader_sp) 94344d93782SGreg Clayton err = top_reader_sp->GetErrorStreamFile(); 94444d93782SGreg Clayton else 94544d93782SGreg Clayton err = GetErrorFile(); 94644d93782SGreg Clayton 94744d93782SGreg Clayton // If there is nothing, use stderr 94844d93782SGreg Clayton if (!err) 94944d93782SGreg Clayton err = StreamFileSP(new StreamFile(stdout, false)); 95044d93782SGreg Clayton 95144d93782SGreg Clayton } 95244d93782SGreg Clayton } 95344d93782SGreg Clayton 95444d93782SGreg Clayton void 95544d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp) 95630fdc8d8SChris Lattner { 95730fdc8d8SChris Lattner if (!reader_sp) 95830fdc8d8SChris Lattner return; 959b44880caSCaroline Tice 96044d93782SGreg Clayton // Got the current top input reader... 96144d93782SGreg Clayton IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 962b44880caSCaroline Tice 96344d93782SGreg Clayton // Push our new input reader 964d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 96544d93782SGreg Clayton 96644d93782SGreg Clayton // Interrupt the top input reader to it will exit its Run() function 96744d93782SGreg Clayton // and let this new input reader take over 96844d93782SGreg Clayton if (top_reader_sp) 96944d93782SGreg Clayton top_reader_sp->Deactivate(); 97030fdc8d8SChris Lattner } 97130fdc8d8SChris Lattner 97230fdc8d8SChris Lattner bool 97344d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp) 97430fdc8d8SChris Lattner { 97530fdc8d8SChris Lattner bool result = false; 97630fdc8d8SChris Lattner 97744d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 97844d93782SGreg Clayton 97930fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 98030fdc8d8SChris Lattner // read on the stack referesh its prompt and if there is one... 981d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 98230fdc8d8SChris Lattner { 98344d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 98430fdc8d8SChris Lattner 98530fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 98630fdc8d8SChris Lattner { 98744d93782SGreg Clayton reader_sp->Deactivate(); 988d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 98930fdc8d8SChris Lattner 990d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 99130fdc8d8SChris Lattner if (reader_sp) 99244d93782SGreg Clayton reader_sp->Activate(); 99344d93782SGreg Clayton 99444d93782SGreg Clayton result = true; 99530fdc8d8SChris Lattner } 99630fdc8d8SChris Lattner } 99730fdc8d8SChris Lattner return result; 99830fdc8d8SChris Lattner } 99930fdc8d8SChris Lattner 100030fdc8d8SChris Lattner bool 100144d93782SGreg Clayton Debugger::HideTopIOHandler() 100230fdc8d8SChris Lattner { 100344d93782SGreg Clayton Mutex::Locker locker; 100430fdc8d8SChris Lattner 100544d93782SGreg Clayton if (locker.TryLock(m_input_reader_stack.GetMutex())) 100630fdc8d8SChris Lattner { 100744d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 100844d93782SGreg Clayton if (reader_sp) 100944d93782SGreg Clayton reader_sp->Hide(); 101044d93782SGreg Clayton return true; 101130fdc8d8SChris Lattner } 101244d93782SGreg Clayton return false; 101330fdc8d8SChris Lattner } 101430fdc8d8SChris Lattner 101530fdc8d8SChris Lattner void 101644d93782SGreg Clayton Debugger::RefreshTopIOHandler() 101730fdc8d8SChris Lattner { 101844d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 101944d93782SGreg Clayton if (reader_sp) 102044d93782SGreg Clayton reader_sp->Refresh(); 102130fdc8d8SChris Lattner } 102244d93782SGreg Clayton 10236611103cSGreg Clayton 10245b52f0c7SJim Ingham StreamSP 10255b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 10265b52f0c7SJim Ingham { 10275b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10285b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 10295b52f0c7SJim Ingham } 10305b52f0c7SJim Ingham 10315b52f0c7SJim Ingham StreamSP 10325b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 10335b52f0c7SJim Ingham { 10345b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10355b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 10365b52f0c7SJim Ingham } 10375b52f0c7SJim Ingham 1038c7bece56SGreg Clayton size_t 1039061858ceSEnrico Granata Debugger::GetNumDebuggers() 1040061858ceSEnrico Granata { 1041c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1042c15f55e2SGreg Clayton { 1043061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1044061858ceSEnrico Granata return GetDebuggerList().size(); 1045061858ceSEnrico Granata } 1046c15f55e2SGreg Clayton return 0; 1047c15f55e2SGreg Clayton } 1048061858ceSEnrico Granata 1049061858ceSEnrico Granata lldb::DebuggerSP 1050c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1051061858ceSEnrico Granata { 1052061858ceSEnrico Granata DebuggerSP debugger_sp; 1053061858ceSEnrico Granata 1054c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1055c15f55e2SGreg Clayton { 1056061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1057061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1058061858ceSEnrico Granata 1059061858ceSEnrico Granata if (index < debugger_list.size()) 1060061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1061c15f55e2SGreg Clayton } 1062061858ceSEnrico Granata 1063061858ceSEnrico Granata return debugger_sp; 1064061858ceSEnrico Granata } 1065061858ceSEnrico Granata 1066ebc1bb27SCaroline Tice DebuggerSP 1067ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1068ebc1bb27SCaroline Tice { 10694d122c40SGreg Clayton DebuggerSP debugger_sp; 1070ebc1bb27SCaroline Tice 1071c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1072c15f55e2SGreg Clayton { 1073ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 1074ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1075ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1076ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1077ebc1bb27SCaroline Tice { 1078ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 1079ebc1bb27SCaroline Tice { 1080ebc1bb27SCaroline Tice debugger_sp = *pos; 1081ebc1bb27SCaroline Tice break; 1082ebc1bb27SCaroline Tice } 1083ebc1bb27SCaroline Tice } 1084c15f55e2SGreg Clayton } 1085ebc1bb27SCaroline Tice return debugger_sp; 1086ebc1bb27SCaroline Tice } 10873df9a8dfSCaroline Tice 10881b654882SGreg Clayton static void 1089b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame) 10901b654882SGreg Clayton { 10911b654882SGreg Clayton if (frame == NULL) 10921b654882SGreg Clayton return; 10931b654882SGreg Clayton 10941b654882SGreg Clayton StreamString s; 10951b654882SGreg Clayton const char *prompt_format = 10961b654882SGreg Clayton "{addr = '${addr}'\n}" 10971b654882SGreg Clayton "{process.id = '${process.id}'\n}" 10981b654882SGreg Clayton "{process.name = '${process.name}'\n}" 10991b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 11001b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 11011b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 11021b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 11031b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 11041b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 11051b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 11061b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 11071b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 11081b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 11091b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 11101b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 11111b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 11121b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 11131b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 11141b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 11151b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 11161b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 11171b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 11181b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 11191b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 11201b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 11211b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 11221b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 11231b654882SGreg Clayton "{function.id = '${function.id}'\n}" 11241b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1125ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 11261b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 11271b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 11281b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 11291b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 11301b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 11311b654882SGreg Clayton "{line.number = '${line.number}'\n}" 11321b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 11331b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 11341b654882SGreg Clayton ; 11351b654882SGreg Clayton 11361b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 11371b654882SGreg Clayton ExecutionContext exe_ctx; 11380603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 1139c3ce7f27SMichael Sartain if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 11401b654882SGreg Clayton { 11411b654882SGreg Clayton printf("%s\n", s.GetData()); 11421b654882SGreg Clayton } 11431b654882SGreg Clayton else 11441b654882SGreg Clayton { 11451b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 11461b654882SGreg Clayton } 11471b654882SGreg Clayton } 11481b654882SGreg Clayton 11499fc1944eSEnrico Granata static bool 11509fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin, 11519fc1944eSEnrico Granata const char* var_name_end, 11529fc1944eSEnrico Granata const char** var_name_final, 11539fc1944eSEnrico Granata const char** percent_position, 11544d122c40SGreg Clayton Format* custom_format, 11559fc1944eSEnrico Granata ValueObject::ValueObjectRepresentationStyle* val_obj_display) 11569fc1944eSEnrico Granata { 11575160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 11589fc1944eSEnrico Granata *percent_position = ::strchr(var_name_begin,'%'); 11599fc1944eSEnrico Granata if (!*percent_position || *percent_position > var_name_end) 1160e992a089SEnrico Granata { 1161e992a089SEnrico Granata if (log) 1162d228483dSEnrico Granata log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 11639fc1944eSEnrico Granata *var_name_final = var_name_end; 1164e992a089SEnrico Granata } 11659fc1944eSEnrico Granata else 11669fc1944eSEnrico Granata { 11679fc1944eSEnrico Granata *var_name_final = *percent_position; 116836aa5ae6SEnrico Granata std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1); 1169e992a089SEnrico Granata if (log) 117068ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str()); 117136aa5ae6SEnrico Granata if ( !FormatManager::GetFormatFromCString(format_name.c_str(), 11729fc1944eSEnrico Granata true, 11739fc1944eSEnrico Granata *custom_format) ) 11749fc1944eSEnrico Granata { 1175e992a089SEnrico Granata if (log) 117668ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str()); 117736aa5ae6SEnrico Granata 117836aa5ae6SEnrico Granata switch (format_name.front()) 117936aa5ae6SEnrico Granata { 118036aa5ae6SEnrico Granata case '@': // if this is an @ sign, print ObjC description 118186cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 118236aa5ae6SEnrico Granata break; 118336aa5ae6SEnrico Granata case 'V': // if this is a V, print the value using the default format 118486cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 118536aa5ae6SEnrico Granata break; 118636aa5ae6SEnrico Granata case 'L': // if this is an L, print the location of the value 118786cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 118836aa5ae6SEnrico Granata break; 118936aa5ae6SEnrico Granata case 'S': // if this is an S, print the summary after all 119086cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 119136aa5ae6SEnrico Granata break; 119236aa5ae6SEnrico Granata case '#': // if this is a '#', print the number of children 119386cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 119436aa5ae6SEnrico Granata break; 119536aa5ae6SEnrico Granata case 'T': // if this is a 'T', print the type 119686cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 119736aa5ae6SEnrico Granata break; 11982c75f11eSEnrico Granata case 'N': // if this is a 'N', print the name 11992c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleName; 12002c75f11eSEnrico Granata break; 12012c75f11eSEnrico Granata case '>': // if this is a '>', print the name 12022c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath; 12032c75f11eSEnrico Granata break; 120436aa5ae6SEnrico Granata default: 12055c42d8a8SJim Ingham if (log) 120636aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 120736aa5ae6SEnrico Granata break; 120836aa5ae6SEnrico Granata } 12099fc1944eSEnrico Granata } 12109fc1944eSEnrico Granata // a good custom format tells us to print the value using it 12119fc1944eSEnrico Granata else 1212e992a089SEnrico Granata { 1213e992a089SEnrico Granata if (log) 121468ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] will display value for this VO"); 121586cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1216e992a089SEnrico Granata } 12179fc1944eSEnrico Granata } 1218e992a089SEnrico Granata if (log) 121968ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1220e992a089SEnrico Granata *custom_format, 1221e992a089SEnrico Granata *val_obj_display); 12229fc1944eSEnrico Granata return true; 12239fc1944eSEnrico Granata } 12249fc1944eSEnrico Granata 12259fc1944eSEnrico Granata static bool 12269fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 12279fc1944eSEnrico Granata const char* var_name_end, 12289fc1944eSEnrico Granata const char* var_name_final, 12299fc1944eSEnrico Granata const char** open_bracket_position, 12309fc1944eSEnrico Granata const char** separator_position, 12319fc1944eSEnrico Granata const char** close_bracket_position, 12329fc1944eSEnrico Granata const char** var_name_final_if_array_range, 12339fc1944eSEnrico Granata int64_t* index_lower, 12349fc1944eSEnrico Granata int64_t* index_higher) 12359fc1944eSEnrico Granata { 12365160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12379fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 12389fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 12399fc1944eSEnrico Granata { 12409fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 12419fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 12429fc1944eSEnrico Granata // as usual, we assume that [] will come before % 12439fc1944eSEnrico Granata //printf("trying to expand a []\n"); 12449fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 12459fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 12469fc1944eSEnrico Granata { 1247e992a089SEnrico Granata if (log) 1248d228483dSEnrico Granata log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 12499fc1944eSEnrico Granata *index_lower = 0; 12509fc1944eSEnrico Granata } 12519fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 12529fc1944eSEnrico Granata { 12539fc1944eSEnrico Granata char *end = NULL; 12549fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12559fc1944eSEnrico Granata *index_higher = *index_lower; 1256e992a089SEnrico Granata if (log) 1257d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 12589fc1944eSEnrico Granata } 12599fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 12609fc1944eSEnrico Granata { 12619fc1944eSEnrico Granata char *end = NULL; 12629fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12639fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 1264e992a089SEnrico Granata if (log) 1265d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 12669fc1944eSEnrico Granata } 12679fc1944eSEnrico Granata else 1268e992a089SEnrico Granata { 1269e992a089SEnrico Granata if (log) 1270d228483dSEnrico Granata log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 12719fc1944eSEnrico Granata return false; 1272e992a089SEnrico Granata } 12739fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 12749fc1944eSEnrico Granata { 1275e992a089SEnrico Granata if (log) 1276d228483dSEnrico Granata log->Printf("[ScanBracketedRange] swapping indices"); 1277c7bece56SGreg Clayton int64_t temp = *index_lower; 12789fc1944eSEnrico Granata *index_lower = *index_higher; 12799fc1944eSEnrico Granata *index_higher = temp; 12809fc1944eSEnrico Granata } 12819fc1944eSEnrico Granata } 1282e992a089SEnrico Granata else if (log) 1283d228483dSEnrico Granata log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 12849fc1944eSEnrico Granata return true; 12859fc1944eSEnrico Granata } 12869fc1944eSEnrico Granata 12870769b2b1SMichael Sartain template <typename T> 12880769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name) 12890769b2b1SMichael Sartain { 12900769b2b1SMichael Sartain if (script_interpreter) 12910769b2b1SMichael Sartain { 12920769b2b1SMichael Sartain Error script_error; 12930769b2b1SMichael Sartain std::string script_output; 12940769b2b1SMichael Sartain 12950769b2b1SMichael Sartain if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success()) 12960769b2b1SMichael Sartain { 12970769b2b1SMichael Sartain s.Printf("%s", script_output.c_str()); 12980769b2b1SMichael Sartain return true; 12990769b2b1SMichael Sartain } 13000769b2b1SMichael Sartain else 13010769b2b1SMichael Sartain { 13020769b2b1SMichael Sartain s.Printf("<error: %s>",script_error.AsCString()); 13030769b2b1SMichael Sartain } 13040769b2b1SMichael Sartain } 13050769b2b1SMichael Sartain return false; 13060769b2b1SMichael Sartain } 13070769b2b1SMichael Sartain 13089fc1944eSEnrico Granata static ValueObjectSP 1309c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 1310c7bece56SGreg Clayton size_t index, 1311b57e4a1bSJason Molenda StackFrame* frame, 1312fc7a7f3bSEnrico Granata bool deref_pointer) 13139fc1944eSEnrico Granata { 13145160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1315fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1316599171adSEnrico Granata std::string ptr_deref_buffer(10,0); 1317599171adSEnrico Granata ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1318e992a089SEnrico Granata if (log) 1319599171adSEnrico Granata log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1320fc7a7f3bSEnrico Granata const char* first_unparsed; 1321fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1322fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1323fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 132486cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1325599171adSEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1326fc7a7f3bSEnrico Granata &first_unparsed, 1327fc7a7f3bSEnrico Granata &reason_to_stop, 1328fc7a7f3bSEnrico Granata &final_value_type, 1329fc7a7f3bSEnrico Granata options, 1330fc7a7f3bSEnrico Granata &what_next); 1331fc7a7f3bSEnrico Granata if (!item) 1332fc7a7f3bSEnrico Granata { 1333e992a089SEnrico Granata if (log) 1334d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1335e992a089SEnrico Granata " final_value_type %d", 1336fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1337fc7a7f3bSEnrico Granata } 13389fc1944eSEnrico Granata else 13399fc1944eSEnrico Granata { 1340e992a089SEnrico Granata if (log) 1341d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1342e992a089SEnrico Granata " final_value_type %d", 1343fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 13449fc1944eSEnrico Granata } 13459fc1944eSEnrico Granata return item; 13469fc1944eSEnrico Granata } 13479fc1944eSEnrico Granata 13480769b2b1SMichael Sartain static inline bool 13490769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var) 13500769b2b1SMichael Sartain { 13510769b2b1SMichael Sartain return (::strncmp (var_name_begin, var, strlen(var)) == 0); 13520769b2b1SMichael Sartain } 13530769b2b1SMichael Sartain 13540769b2b1SMichael Sartain static bool 13550769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format, 13560769b2b1SMichael Sartain const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr) 13570769b2b1SMichael Sartain { 13580769b2b1SMichael Sartain int var_len = strlen(var); 13590769b2b1SMichael Sartain if (::strncmp (var_name_begin, var, var_len) == 0) 13600769b2b1SMichael Sartain { 13610769b2b1SMichael Sartain var_name_begin += var_len; 13620769b2b1SMichael Sartain if (*var_name_begin == '}') 13630769b2b1SMichael Sartain { 13640769b2b1SMichael Sartain format = default_format; 13650769b2b1SMichael Sartain return true; 13660769b2b1SMichael Sartain } 13670769b2b1SMichael Sartain else if (*var_name_begin == '%') 13680769b2b1SMichael Sartain { 13690769b2b1SMichael Sartain // Allow format specifiers: x|X|u with optional width specifiers. 13700769b2b1SMichael Sartain // ${thread.id%x} ; hex 13710769b2b1SMichael Sartain // ${thread.id%X} ; uppercase hex 13720769b2b1SMichael Sartain // ${thread.id%u} ; unsigned decimal 13730769b2b1SMichael Sartain // ${thread.id%8.8X} ; width.precision + specifier 13740769b2b1SMichael Sartain // ${thread.id%tid} ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id) 13750769b2b1SMichael Sartain int dot_count = 0; 13760769b2b1SMichael Sartain const char *specifier = NULL; 13770769b2b1SMichael Sartain int width_precision_length = 0; 13780769b2b1SMichael Sartain const char *width_precision = ++var_name_begin; 13790769b2b1SMichael Sartain while (isdigit(*var_name_begin) || *var_name_begin == '.') 13800769b2b1SMichael Sartain { 13810769b2b1SMichael Sartain dot_count += (*var_name_begin == '.'); 13820769b2b1SMichael Sartain if (dot_count > 1) 13830769b2b1SMichael Sartain break; 13840769b2b1SMichael Sartain var_name_begin++; 13850769b2b1SMichael Sartain width_precision_length++; 13860769b2b1SMichael Sartain } 13870769b2b1SMichael Sartain 13880769b2b1SMichael Sartain if (IsToken (var_name_begin, "tid}")) 13890769b2b1SMichael Sartain { 13900769b2b1SMichael Sartain Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr); 13910769b2b1SMichael Sartain if (target) 13920769b2b1SMichael Sartain { 13930769b2b1SMichael Sartain ArchSpec arch (target->GetArchitecture ()); 13940769b2b1SMichael Sartain llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS; 13950769b2b1SMichael Sartain if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux)) 13960769b2b1SMichael Sartain specifier = PRIu64; 13970769b2b1SMichael Sartain } 13980769b2b1SMichael Sartain if (!specifier) 13990769b2b1SMichael Sartain { 14000769b2b1SMichael Sartain format = default_format; 14010769b2b1SMichael Sartain return true; 14020769b2b1SMichael Sartain } 14030769b2b1SMichael Sartain } 14040769b2b1SMichael Sartain else if (IsToken (var_name_begin, "x}")) 14050769b2b1SMichael Sartain specifier = PRIx64; 14060769b2b1SMichael Sartain else if (IsToken (var_name_begin, "X}")) 14070769b2b1SMichael Sartain specifier = PRIX64; 14080769b2b1SMichael Sartain else if (IsToken (var_name_begin, "u}")) 14090769b2b1SMichael Sartain specifier = PRIu64; 14100769b2b1SMichael Sartain 14110769b2b1SMichael Sartain if (specifier) 14120769b2b1SMichael Sartain { 14130769b2b1SMichael Sartain format = "%"; 14140769b2b1SMichael Sartain if (width_precision_length) 14150769b2b1SMichael Sartain format += std::string(width_precision, width_precision_length); 14160769b2b1SMichael Sartain format += specifier; 14170769b2b1SMichael Sartain return true; 14180769b2b1SMichael Sartain } 14190769b2b1SMichael Sartain } 14200769b2b1SMichael Sartain } 14210769b2b1SMichael Sartain return false; 14220769b2b1SMichael Sartain } 14230769b2b1SMichael Sartain 1424c3ce7f27SMichael Sartain static bool 1425c3ce7f27SMichael Sartain FormatPromptRecurse 14261b654882SGreg Clayton ( 14271b654882SGreg Clayton const char *format, 14281b654882SGreg Clayton const SymbolContext *sc, 14291b654882SGreg Clayton const ExecutionContext *exe_ctx, 14301b654882SGreg Clayton const Address *addr, 14311b654882SGreg Clayton Stream &s, 14324becb37eSEnrico Granata const char **end, 1433c482a192SEnrico Granata ValueObject* valobj 14341b654882SGreg Clayton ) 14351b654882SGreg Clayton { 1436c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 14371b654882SGreg Clayton bool success = true; 14381b654882SGreg Clayton const char *p; 14395160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1440c3ce7f27SMichael Sartain 14411b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 14421b654882SGreg Clayton { 1443c482a192SEnrico Granata if (realvalobj) 14444becb37eSEnrico Granata { 1445c482a192SEnrico Granata valobj = realvalobj; 1446c482a192SEnrico Granata realvalobj = NULL; 14474becb37eSEnrico Granata } 14481b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 14491b654882SGreg Clayton if (non_special_chars > 0) 14501b654882SGreg Clayton { 14511b654882SGreg Clayton if (success) 14521b654882SGreg Clayton s.Write (p, non_special_chars); 14531b654882SGreg Clayton p += non_special_chars; 14541b654882SGreg Clayton } 14551b654882SGreg Clayton 14561b654882SGreg Clayton if (*p == '\0') 14571b654882SGreg Clayton { 14581b654882SGreg Clayton break; 14591b654882SGreg Clayton } 14601b654882SGreg Clayton else if (*p == '{') 14611b654882SGreg Clayton { 14621b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 14631b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 14641b654882SGreg Clayton // a format that only prints out the function or symbol name if there 14651b654882SGreg Clayton // is one in the symbol context you can use: 14661b654882SGreg Clayton // "{function =${function.name}}" 14671b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 14681b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 14691b654882SGreg Clayton // will then be evaluated and only be output if there is a function 14701b654882SGreg Clayton // or symbol with a valid name. 14711b654882SGreg Clayton StreamString sub_strm; 14721b654882SGreg Clayton 14731b654882SGreg Clayton ++p; // Skip the '{' 14741b654882SGreg Clayton 1475c3ce7f27SMichael Sartain if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 14761b654882SGreg Clayton { 14771b654882SGreg Clayton // The stream had all it needed 14781b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 14791b654882SGreg Clayton } 14801b654882SGreg Clayton if (*p != '}') 14811b654882SGreg Clayton { 14821b654882SGreg Clayton success = false; 14831b654882SGreg Clayton break; 14841b654882SGreg Clayton } 14851b654882SGreg Clayton } 14861b654882SGreg Clayton else if (*p == '}') 14871b654882SGreg Clayton { 14881b654882SGreg Clayton // End of a enclosing scope 14891b654882SGreg Clayton break; 14901b654882SGreg Clayton } 14911b654882SGreg Clayton else if (*p == '$') 14921b654882SGreg Clayton { 14931b654882SGreg Clayton // We have a prompt variable to print 14941b654882SGreg Clayton ++p; 14951b654882SGreg Clayton if (*p == '{') 14961b654882SGreg Clayton { 14971b654882SGreg Clayton ++p; 14981b654882SGreg Clayton const char *var_name_begin = p; 14991b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 15001b654882SGreg Clayton 15011b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 15021b654882SGreg Clayton { 15031b654882SGreg Clayton // if we have already failed to parse, skip this variable 15041b654882SGreg Clayton if (success) 15051b654882SGreg Clayton { 15061b654882SGreg Clayton const char *cstr = NULL; 15070769b2b1SMichael Sartain std::string token_format; 15081b654882SGreg Clayton Address format_addr; 15091b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 15101b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 15111b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 15121b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 15131b654882SGreg Clayton FileSpec format_file_spec; 1514e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 15151b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 15169fc1944eSEnrico Granata bool do_deref_pointer = false; 151786cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 151886cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 15191b654882SGreg Clayton 15201b654882SGreg Clayton // Each variable must set success to true below... 15211b654882SGreg Clayton bool var_success = false; 15221b654882SGreg Clayton switch (var_name_begin[0]) 15231b654882SGreg Clayton { 15244becb37eSEnrico Granata case '*': 15256f3533fbSEnrico Granata case 'v': 15266f3533fbSEnrico Granata case 's': 15274becb37eSEnrico Granata { 1528c482a192SEnrico Granata if (!valobj) 152934132754SGreg Clayton break; 15306f3533fbSEnrico Granata 1531c3e320a7SEnrico Granata if (log) 1532d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1533c3e320a7SEnrico Granata 15346f3533fbSEnrico Granata // check for *var and *svar 15356f3533fbSEnrico Granata if (*var_name_begin == '*') 15366f3533fbSEnrico Granata { 15379fc1944eSEnrico Granata do_deref_pointer = true; 15389fc1944eSEnrico Granata var_name_begin++; 1539c3e320a7SEnrico Granata if (log) 154068ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin); 154168ae4117SEnrico Granata } 1542c3e320a7SEnrico Granata 15436f3533fbSEnrico Granata if (*var_name_begin == 's') 15444becb37eSEnrico Granata { 1545c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 154686cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 154786cc9829SEnrico Granata if (!valobj) 154886cc9829SEnrico Granata break; 15496f3533fbSEnrico Granata var_name_begin++; 1550c3e320a7SEnrico Granata if (log) 155168ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin); 155268ae4117SEnrico Granata } 1553c3e320a7SEnrico Granata 15546f3533fbSEnrico Granata // should be a 'v' by now 15556f3533fbSEnrico Granata if (*var_name_begin != 'v') 15566f3533fbSEnrico Granata break; 15576f3533fbSEnrico Granata 1558c3e320a7SEnrico Granata if (log) 155968ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin); 1560c3e320a7SEnrico Granata 1561fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 156286cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1563fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 15648c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 156586cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 156634132754SGreg Clayton ValueObject* target = NULL; 15674d122c40SGreg Clayton Format custom_format = eFormatInvalid; 156834132754SGreg Clayton const char* var_name_final = NULL; 15699fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 157034132754SGreg Clayton const char* close_bracket_position = NULL; 157134132754SGreg Clayton int64_t index_lower = -1; 157234132754SGreg Clayton int64_t index_higher = -1; 15739fc1944eSEnrico Granata bool is_array_range = false; 1574fc7a7f3bSEnrico Granata const char* first_unparsed; 157585933ed4SEnrico Granata bool was_plain_var = false; 157685933ed4SEnrico Granata bool was_var_format = false; 1577a777dc2aSEnrico Granata bool was_var_indexed = false; 1578fc7a7f3bSEnrico Granata 1579c482a192SEnrico Granata if (!valobj) break; 1580c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 15810769b2b1SMichael Sartain if (IsToken (var_name_begin, "var}")) 15820a3958e0SEnrico Granata { 158385933ed4SEnrico Granata was_plain_var = true; 1584c482a192SEnrico Granata target = valobj; 158586cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 15860a3958e0SEnrico Granata } 15870769b2b1SMichael Sartain else if (IsToken (var_name_begin,"var%")) 15889fc1944eSEnrico Granata { 158985933ed4SEnrico Granata was_var_format = true; 15909fc1944eSEnrico Granata // this is a variable with some custom format applied to it 15919fc1944eSEnrico Granata const char* percent_position; 1592c482a192SEnrico Granata target = valobj; 159386cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 15949fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 15959fc1944eSEnrico Granata var_name_end, 15969fc1944eSEnrico Granata &var_name_final, 15979fc1944eSEnrico Granata &percent_position, 15989fc1944eSEnrico Granata &custom_format, 15999fc1944eSEnrico Granata &val_obj_display); 16000a3958e0SEnrico Granata } 16019fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 16020769b2b1SMichael Sartain else if (IsToken (var_name_begin, "var")) 16039fc1944eSEnrico Granata { 16040769b2b1SMichael Sartain if (IsToken (var_name_begin, "var[")) 1605a777dc2aSEnrico Granata was_var_indexed = true; 16069fc1944eSEnrico Granata const char* percent_position; 16079fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 16089fc1944eSEnrico Granata var_name_end, 16099fc1944eSEnrico Granata &var_name_final, 16109fc1944eSEnrico Granata &percent_position, 16119fc1944eSEnrico Granata &custom_format, 16129fc1944eSEnrico Granata &val_obj_display); 16139fc1944eSEnrico Granata 16149fc1944eSEnrico Granata const char* open_bracket_position; 16159fc1944eSEnrico Granata const char* separator_position; 16169fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 16179fc1944eSEnrico Granata var_name_end, 16189fc1944eSEnrico Granata var_name_final, 16199fc1944eSEnrico Granata &open_bracket_position, 16209fc1944eSEnrico Granata &separator_position, 16219fc1944eSEnrico Granata &close_bracket_position, 16229fc1944eSEnrico Granata &var_name_final_if_array_range, 16239fc1944eSEnrico Granata &index_lower, 16249fc1944eSEnrico Granata &index_higher); 16259fc1944eSEnrico Granata 16269fc1944eSEnrico Granata Error error; 16279fc1944eSEnrico Granata 1628599171adSEnrico Granata std::string expr_path(var_name_final-var_name_begin-1,0); 1629599171adSEnrico Granata memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1630fc7a7f3bSEnrico Granata 1631e992a089SEnrico Granata if (log) 1632599171adSEnrico Granata log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1633fc7a7f3bSEnrico Granata 1634599171adSEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1635fc7a7f3bSEnrico Granata &first_unparsed, 1636fc7a7f3bSEnrico Granata &reason_to_stop, 1637fc7a7f3bSEnrico Granata &final_value_type, 1638fc7a7f3bSEnrico Granata options, 1639fc7a7f3bSEnrico Granata &what_next).get(); 1640fc7a7f3bSEnrico Granata 1641fc7a7f3bSEnrico Granata if (!target) 16429fc1944eSEnrico Granata { 1643e992a089SEnrico Granata if (log) 1644d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1645e992a089SEnrico Granata " final_value_type %d", 1646fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1647fc7a7f3bSEnrico Granata break; 16480a3958e0SEnrico Granata } 1649a7187d00SEnrico Granata else 1650fc7a7f3bSEnrico Granata { 1651e992a089SEnrico Granata if (log) 1652d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1653e992a089SEnrico Granata " final_value_type %d", 1654fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1655a7187d00SEnrico Granata } 16560a3958e0SEnrico Granata } 16570a3958e0SEnrico Granata else 16580a3958e0SEnrico Granata break; 16599fc1944eSEnrico Granata 166086cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 166186cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1662fc7a7f3bSEnrico Granata 166386cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1664fc7a7f3bSEnrico Granata 1665a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 16660a3958e0SEnrico Granata { 16679fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 16689fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 16699fc1944eSEnrico Granata // to get to the target ValueObject 16709fc1944eSEnrico Granata Error error; 16719fc1944eSEnrico Granata target = target->Dereference(error).get(); 1672dc940730SEnrico Granata if (error.Fail()) 1673dc940730SEnrico Granata { 1674dc940730SEnrico Granata if (log) 1675d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1676dc940730SEnrico Granata break; 1677dc940730SEnrico Granata } 16789fc1944eSEnrico Granata do_deref_pointer = false; 16790a3958e0SEnrico Granata } 16800a3958e0SEnrico Granata 1681a777dc2aSEnrico Granata // we do not want to use the summary for a bitfield of type T:n 1682a777dc2aSEnrico Granata // if we were originally dealing with just a T - that would get 1683a777dc2aSEnrico Granata // us into an endless recursion 1684a777dc2aSEnrico Granata if (target->IsBitfield() && was_var_indexed) 1685a777dc2aSEnrico Granata { 1686a777dc2aSEnrico Granata // TODO: check for a (T:n)-specific summary - we should still obey that 1687a777dc2aSEnrico Granata StreamString bitfield_name; 1688a777dc2aSEnrico Granata bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1689a777dc2aSEnrico Granata lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1690a777dc2aSEnrico Granata if (!DataVisualization::GetSummaryForType(type_sp)) 1691a777dc2aSEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1692a777dc2aSEnrico Granata } 1693a777dc2aSEnrico Granata 169485933ed4SEnrico Granata // TODO use flags for these 169557ee3067SGreg Clayton const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL); 169657ee3067SGreg Clayton bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0; 169757ee3067SGreg Clayton bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0; 169857ee3067SGreg Clayton bool is_aggregate = target->GetClangType().IsAggregateType(); 1699f4efecd9SEnrico Granata 170086cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1701f4efecd9SEnrico Granata { 170285933ed4SEnrico Granata StreamString str_temp; 1703e992a089SEnrico Granata if (log) 1704d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1705d64d0bc0SEnrico Granata 17065088c486SGreg Clayton if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1707d64d0bc0SEnrico Granata { 1708f4efecd9SEnrico Granata // try to use the special cases 170985933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 171085933ed4SEnrico Granata val_obj_display, 171185933ed4SEnrico Granata custom_format); 1712e992a089SEnrico Granata if (log) 1713d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1714d64d0bc0SEnrico Granata 1715d64d0bc0SEnrico Granata // should not happen 17165088c486SGreg Clayton if (var_success) 171785933ed4SEnrico Granata s << str_temp.GetData(); 1718d64d0bc0SEnrico Granata var_success = true; 1719d64d0bc0SEnrico Granata break; 1720d64d0bc0SEnrico Granata } 1721d64d0bc0SEnrico Granata else 1722d64d0bc0SEnrico Granata { 172388da35f8SEnrico Granata if (was_plain_var) // if ${var} 1724d64d0bc0SEnrico Granata { 1725d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1726d64d0bc0SEnrico Granata } 172788da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 172888da35f8SEnrico Granata { 172923f59509SGreg Clayton target->DumpPrintableRepresentation (s, 173088da35f8SEnrico Granata val_obj_display, 173186cc9829SEnrico Granata custom_format, 173286cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 173388da35f8SEnrico Granata } 1734d64d0bc0SEnrico Granata var_success = true; 1735d64d0bc0SEnrico Granata break; 1736d64d0bc0SEnrico Granata } 1737d64d0bc0SEnrico Granata } 1738d64d0bc0SEnrico Granata 1739d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1740d64d0bc0SEnrico Granata // type @ location message 1741d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1742d64d0bc0SEnrico Granata { 1743d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1744d64d0bc0SEnrico Granata var_success = true; 174585933ed4SEnrico Granata break; 174685933ed4SEnrico Granata } 174785933ed4SEnrico Granata 1748d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 174986cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 175085933ed4SEnrico Granata { 175185933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 175285933ed4SEnrico Granata var_success = true; 1753f4efecd9SEnrico Granata break; 1754f4efecd9SEnrico Granata } 1755f4efecd9SEnrico Granata 17569fc1944eSEnrico Granata if (!is_array_range) 1757e992a089SEnrico Granata { 1758e992a089SEnrico Granata if (log) 1759d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 17609fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1761e992a089SEnrico Granata } 17629fc1944eSEnrico Granata else 17639fc1944eSEnrico Granata { 1764e992a089SEnrico Granata if (log) 1765d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 17669fc1944eSEnrico Granata if (!is_array && !is_pointer) 17679fc1944eSEnrico Granata break; 1768e992a089SEnrico Granata if (log) 1769d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] handle as array"); 1770fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1771fc7a7f3bSEnrico Granata StreamString special_directions_writer; 17720a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 17730a3958e0SEnrico Granata { 1774fc7a7f3bSEnrico Granata ConstString additional_data; 1775fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1776fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1777fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1778fc7a7f3bSEnrico Granata additional_data.GetCString()); 1779fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 17800a3958e0SEnrico Granata } 17810a3958e0SEnrico Granata 17820a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 17830a3958e0SEnrico Granata s.PutChar('['); 17840a3958e0SEnrico Granata var_success = true; 17850a3958e0SEnrico Granata 17869fc1944eSEnrico Granata if (index_higher < 0) 1787c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 17880a3958e0SEnrico Granata 1789cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 179022c55d18SEnrico Granata 17910a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 17920a3958e0SEnrico Granata { 1793fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 17949fc1944eSEnrico Granata index_lower, 1795c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1796fc7a7f3bSEnrico Granata false).get(); 17970a3958e0SEnrico Granata 1798fc7a7f3bSEnrico Granata if (!item) 1799fc7a7f3bSEnrico Granata { 1800e992a089SEnrico Granata if (log) 1801d01b2953SDaniel Malea log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1802fc7a7f3bSEnrico Granata } 1803fc7a7f3bSEnrico Granata else 1804fc7a7f3bSEnrico Granata { 1805e992a089SEnrico Granata if (log) 1806d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1807fc7a7f3bSEnrico Granata } 1808fc7a7f3bSEnrico Granata 18090a3958e0SEnrico Granata if (!special_directions) 18109fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 18110a3958e0SEnrico Granata else 1812c3ce7f27SMichael Sartain var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item); 18130a3958e0SEnrico Granata 181422c55d18SEnrico Granata if (--max_num_children == 0) 181522c55d18SEnrico Granata { 181622c55d18SEnrico Granata s.PutCString(", ..."); 181722c55d18SEnrico Granata break; 181822c55d18SEnrico Granata } 181922c55d18SEnrico Granata 18200a3958e0SEnrico Granata if (index_lower < index_higher) 18210a3958e0SEnrico Granata s.PutChar(','); 18220a3958e0SEnrico Granata } 18230a3958e0SEnrico Granata s.PutChar(']'); 18244becb37eSEnrico Granata } 18254becb37eSEnrico Granata } 182634132754SGreg Clayton break; 18271b654882SGreg Clayton case 'a': 18280769b2b1SMichael Sartain if (IsToken (var_name_begin, "addr}")) 18291b654882SGreg Clayton { 18301b654882SGreg Clayton if (addr && addr->IsValid()) 18311b654882SGreg Clayton { 18321b654882SGreg Clayton var_success = true; 18331b654882SGreg Clayton format_addr = *addr; 18341b654882SGreg Clayton } 18351b654882SGreg Clayton } 18361b654882SGreg Clayton break; 18371b654882SGreg Clayton 18381b654882SGreg Clayton case 'p': 18390769b2b1SMichael Sartain if (IsToken (var_name_begin, "process.")) 18401b654882SGreg Clayton { 1841c14ee32dSGreg Clayton if (exe_ctx) 1842c14ee32dSGreg Clayton { 1843c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 1844c14ee32dSGreg Clayton if (process) 18451b654882SGreg Clayton { 18461b654882SGreg Clayton var_name_begin += ::strlen ("process."); 18470769b2b1SMichael Sartain if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc)) 18481b654882SGreg Clayton { 18490769b2b1SMichael Sartain s.Printf(token_format.c_str(), process->GetID()); 18501b654882SGreg Clayton var_success = true; 18511b654882SGreg Clayton } 18520769b2b1SMichael Sartain else if ((IsToken (var_name_begin, "name}")) || 18530769b2b1SMichael Sartain (IsToken (var_name_begin, "file.basename}")) || 18540769b2b1SMichael Sartain (IsToken (var_name_begin, "file.fullpath}"))) 18551b654882SGreg Clayton { 1856c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1857aa149cbdSGreg Clayton if (exe_module) 18581b654882SGreg Clayton { 18591b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 18601b654882SGreg Clayton { 1861aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 18629076c0ffSSean Callanan var_success = (bool)format_file_spec; 18631b654882SGreg Clayton } 18641b654882SGreg Clayton else 18651b654882SGreg Clayton { 1866aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 18679076c0ffSSean Callanan var_success = (bool)format_file_spec; 18681b654882SGreg Clayton } 18691b654882SGreg Clayton } 18701b654882SGreg Clayton } 18710769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 1872aad8e480SEnrico Granata { 1873aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 1874aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 1875aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 18760769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, process, script_name)) 1877aad8e480SEnrico Granata var_success = true; 1878aad8e480SEnrico Granata } 18791b654882SGreg Clayton } 18801b654882SGreg Clayton } 1881c14ee32dSGreg Clayton } 18821b654882SGreg Clayton break; 18831b654882SGreg Clayton 18841b654882SGreg Clayton case 't': 18850769b2b1SMichael Sartain if (IsToken (var_name_begin, "thread.")) 18861b654882SGreg Clayton { 1887c14ee32dSGreg Clayton if (exe_ctx) 1888c14ee32dSGreg Clayton { 1889c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 1890c14ee32dSGreg Clayton if (thread) 18911b654882SGreg Clayton { 18921b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 18930769b2b1SMichael Sartain if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 18941b654882SGreg Clayton { 18950769b2b1SMichael Sartain s.Printf(token_format.c_str(), thread->GetID()); 18961b654882SGreg Clayton var_success = true; 18971b654882SGreg Clayton } 18980769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 1899160c9d81SGreg Clayton { 19000769b2b1SMichael Sartain s.Printf(token_format.c_str(), thread->GetProtocolID()); 1901160c9d81SGreg Clayton var_success = true; 1902160c9d81SGreg Clayton } 19030769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc)) 19041b654882SGreg Clayton { 19050769b2b1SMichael Sartain s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID()); 19061b654882SGreg Clayton var_success = true; 19071b654882SGreg Clayton } 19080769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name}")) 19091b654882SGreg Clayton { 1910c14ee32dSGreg Clayton cstr = thread->GetName(); 19111b654882SGreg Clayton var_success = cstr && cstr[0]; 19121b654882SGreg Clayton if (var_success) 19131b654882SGreg Clayton s.PutCString(cstr); 19141b654882SGreg Clayton } 19150769b2b1SMichael Sartain else if (IsToken (var_name_begin, "queue}")) 19161b654882SGreg Clayton { 1917c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 19181b654882SGreg Clayton var_success = cstr && cstr[0]; 19191b654882SGreg Clayton if (var_success) 19201b654882SGreg Clayton s.PutCString(cstr); 19211b654882SGreg Clayton } 19220769b2b1SMichael Sartain else if (IsToken (var_name_begin, "stop-reason}")) 19231b654882SGreg Clayton { 1924c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 19255d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 19261b654882SGreg Clayton { 1927b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 19281b654882SGreg Clayton if (cstr && cstr[0]) 19291b654882SGreg Clayton { 19301b654882SGreg Clayton s.PutCString(cstr); 19311b654882SGreg Clayton var_success = true; 19321b654882SGreg Clayton } 19331b654882SGreg Clayton } 19341b654882SGreg Clayton } 19350769b2b1SMichael Sartain else if (IsToken (var_name_begin, "return-value}")) 193673ca05a2SJim Ingham { 193773ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 19385d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 193973ca05a2SJim Ingham { 194073ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 194173ca05a2SJim Ingham if (return_valobj_sp) 194273ca05a2SJim Ingham { 19434d93b8cdSEnrico Granata return_valobj_sp->Dump(s); 194473ca05a2SJim Ingham var_success = true; 194573ca05a2SJim Ingham } 194673ca05a2SJim Ingham } 194773ca05a2SJim Ingham } 19480769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 1949aad8e480SEnrico Granata { 1950aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 1951aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 1952aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 19530769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name)) 1954aad8e480SEnrico Granata var_success = true; 1955aad8e480SEnrico Granata } 1956aad8e480SEnrico Granata } 1957aad8e480SEnrico Granata } 195873ca05a2SJim Ingham } 19590769b2b1SMichael Sartain else if (IsToken (var_name_begin, "target.")) 19601b654882SGreg Clayton { 196167cc0636SGreg Clayton // TODO: hookup properties 196267cc0636SGreg Clayton // if (!target_properties_sp) 196367cc0636SGreg Clayton // { 196467cc0636SGreg Clayton // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 196567cc0636SGreg Clayton // if (target) 196667cc0636SGreg Clayton // target_properties_sp = target->GetProperties(); 196767cc0636SGreg Clayton // } 196867cc0636SGreg Clayton // 196967cc0636SGreg Clayton // if (target_properties_sp) 197067cc0636SGreg Clayton // { 197167cc0636SGreg Clayton // var_name_begin += ::strlen ("target."); 197267cc0636SGreg Clayton // const char *end_property = strchr(var_name_begin, '}'); 197367cc0636SGreg Clayton // if (end_property) 197467cc0636SGreg Clayton // { 197567cc0636SGreg Clayton // ConstString property_name(var_name_begin, end_property - var_name_begin); 197667cc0636SGreg Clayton // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 197767cc0636SGreg Clayton // if (!property_value.empty()) 197867cc0636SGreg Clayton // { 197967cc0636SGreg Clayton // s.PutCString (property_value.c_str()); 198067cc0636SGreg Clayton // var_success = true; 198167cc0636SGreg Clayton // } 198267cc0636SGreg Clayton // } 198367cc0636SGreg Clayton // } 19840603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 19850603aa9dSGreg Clayton if (target) 19861b654882SGreg Clayton { 19871b654882SGreg Clayton var_name_begin += ::strlen ("target."); 19880769b2b1SMichael Sartain if (IsToken (var_name_begin, "arch}")) 19891b654882SGreg Clayton { 19901b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 19911b654882SGreg Clayton if (arch.IsValid()) 19921b654882SGreg Clayton { 199364195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 19941b654882SGreg Clayton var_success = true; 19951b654882SGreg Clayton } 19961b654882SGreg Clayton } 19970769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 1998aad8e480SEnrico Granata { 1999aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2000aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2001aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 20020769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, target, script_name)) 2003aad8e480SEnrico Granata var_success = true; 2004aad8e480SEnrico Granata } 20051b654882SGreg Clayton } 20061b654882SGreg Clayton } 20071b654882SGreg Clayton break; 20081b654882SGreg Clayton 20091b654882SGreg Clayton 20101b654882SGreg Clayton case 'm': 20110769b2b1SMichael Sartain if (IsToken (var_name_begin, "module.")) 20121b654882SGreg Clayton { 20130603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 20141b654882SGreg Clayton { 20150603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 20161b654882SGreg Clayton var_name_begin += ::strlen ("module."); 20171b654882SGreg Clayton 20180769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 20191b654882SGreg Clayton { 20201b654882SGreg Clayton if (module->GetFileSpec()) 20211b654882SGreg Clayton { 20221b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20231b654882SGreg Clayton 20240769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 20251b654882SGreg Clayton { 20261b654882SGreg Clayton format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 20279076c0ffSSean Callanan var_success = (bool)format_file_spec; 20281b654882SGreg Clayton } 20290769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 20301b654882SGreg Clayton { 20311b654882SGreg Clayton format_file_spec = module->GetFileSpec(); 20329076c0ffSSean Callanan var_success = (bool)format_file_spec; 20331b654882SGreg Clayton } 20341b654882SGreg Clayton } 20351b654882SGreg Clayton } 20361b654882SGreg Clayton } 20371b654882SGreg Clayton } 20381b654882SGreg Clayton break; 20391b654882SGreg Clayton 20401b654882SGreg Clayton 20411b654882SGreg Clayton case 'f': 20420769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 20431b654882SGreg Clayton { 20441b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 20451b654882SGreg Clayton { 20461b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20471b654882SGreg Clayton 20480769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 20491b654882SGreg Clayton { 20501b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 20519076c0ffSSean Callanan var_success = (bool)format_file_spec; 20521b654882SGreg Clayton } 20530769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 20541b654882SGreg Clayton { 20551b654882SGreg Clayton format_file_spec = *sc->comp_unit; 20569076c0ffSSean Callanan var_success = (bool)format_file_spec; 20571b654882SGreg Clayton } 20581b654882SGreg Clayton } 20591b654882SGreg Clayton } 20600769b2b1SMichael Sartain else if (IsToken (var_name_begin, "frame.")) 20611b654882SGreg Clayton { 2062c14ee32dSGreg Clayton if (exe_ctx) 2063c14ee32dSGreg Clayton { 2064b57e4a1bSJason Molenda StackFrame *frame = exe_ctx->GetFramePtr(); 2065c14ee32dSGreg Clayton if (frame) 20661b654882SGreg Clayton { 20671b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 20680769b2b1SMichael Sartain if (IsToken (var_name_begin, "index}")) 20691b654882SGreg Clayton { 2070c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 20711b654882SGreg Clayton var_success = true; 20721b654882SGreg Clayton } 20730769b2b1SMichael Sartain else if (IsToken (var_name_begin, "pc}")) 20741b654882SGreg Clayton { 20751b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20761b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 20771b654882SGreg Clayton var_success = true; 20781b654882SGreg Clayton } 20790769b2b1SMichael Sartain else if (IsToken (var_name_begin, "sp}")) 20801b654882SGreg Clayton { 20811b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20821b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 20831b654882SGreg Clayton var_success = true; 20841b654882SGreg Clayton } 20850769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fp}")) 20861b654882SGreg Clayton { 20871b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20881b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 20891b654882SGreg Clayton var_success = true; 20901b654882SGreg Clayton } 20910769b2b1SMichael Sartain else if (IsToken (var_name_begin, "flags}")) 20921b654882SGreg Clayton { 20931b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20941b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 20951b654882SGreg Clayton var_success = true; 20961b654882SGreg Clayton } 20970769b2b1SMichael Sartain else if (IsToken (var_name_begin, "reg.")) 20981b654882SGreg Clayton { 2099c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 21001b654882SGreg Clayton if (reg_ctx) 21011b654882SGreg Clayton { 21021b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 21031b654882SGreg Clayton if (var_name_begin < var_name_end) 21041b654882SGreg Clayton { 21051b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 21061b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 21071b654882SGreg Clayton if (reg_info) 21081b654882SGreg Clayton var_success = true; 21091b654882SGreg Clayton } 21101b654882SGreg Clayton } 21111b654882SGreg Clayton } 21120769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 2113aad8e480SEnrico Granata { 2114aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2115aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2116aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 21170769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name)) 2118aad8e480SEnrico Granata var_success = true; 2119aad8e480SEnrico Granata } 2120aad8e480SEnrico Granata } 2121aad8e480SEnrico Granata } 21221b654882SGreg Clayton } 21230769b2b1SMichael Sartain else if (IsToken (var_name_begin, "function.")) 21241b654882SGreg Clayton { 21251b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 21261b654882SGreg Clayton { 21271b654882SGreg Clayton var_name_begin += ::strlen ("function."); 21280769b2b1SMichael Sartain if (IsToken (var_name_begin, "id}")) 21291b654882SGreg Clayton { 21301b654882SGreg Clayton if (sc->function) 2131d01b2953SDaniel Malea s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 21321b654882SGreg Clayton else 21331b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 21341b654882SGreg Clayton 21351b654882SGreg Clayton var_success = true; 21361b654882SGreg Clayton } 21370769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name}")) 21381b654882SGreg Clayton { 21391b654882SGreg Clayton if (sc->function) 21401b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21411b654882SGreg Clayton else if (sc->symbol) 21421b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 21431b654882SGreg Clayton if (cstr) 21441b654882SGreg Clayton { 21451b654882SGreg Clayton s.PutCString(cstr); 21460d9c9934SGreg Clayton 21470d9c9934SGreg Clayton if (sc->block) 21480d9c9934SGreg Clayton { 21490d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 21500d9c9934SGreg Clayton if (inline_block) 21510d9c9934SGreg Clayton { 21520d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 21530d9c9934SGreg Clayton if (inline_info) 21540d9c9934SGreg Clayton { 21550d9c9934SGreg Clayton s.PutCString(" [inlined] "); 21560d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 21570d9c9934SGreg Clayton } 21580d9c9934SGreg Clayton } 21590d9c9934SGreg Clayton } 21601b654882SGreg Clayton var_success = true; 21611b654882SGreg Clayton } 21621b654882SGreg Clayton } 21630769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name-with-args}")) 21646d3dbf51SGreg Clayton { 21656d3dbf51SGreg Clayton // Print the function name with arguments in it 21666d3dbf51SGreg Clayton 21676d3dbf51SGreg Clayton if (sc->function) 21686d3dbf51SGreg Clayton { 21696d3dbf51SGreg Clayton var_success = true; 21706d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 21716d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21726d3dbf51SGreg Clayton if (cstr) 21736d3dbf51SGreg Clayton { 21746d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 21756d3dbf51SGreg Clayton VariableListSP variable_list_sp; 21766d3dbf51SGreg Clayton bool get_function_vars = true; 21776d3dbf51SGreg Clayton if (sc->block) 21786d3dbf51SGreg Clayton { 21796d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 21806d3dbf51SGreg Clayton 21816d3dbf51SGreg Clayton if (inline_block) 21826d3dbf51SGreg Clayton { 21836d3dbf51SGreg Clayton get_function_vars = false; 21846d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 21856d3dbf51SGreg Clayton if (inline_info) 21866d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 21876d3dbf51SGreg Clayton } 21886d3dbf51SGreg Clayton } 21896d3dbf51SGreg Clayton 21906d3dbf51SGreg Clayton if (get_function_vars) 21916d3dbf51SGreg Clayton { 21926d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 21936d3dbf51SGreg Clayton } 21946d3dbf51SGreg Clayton 21956d3dbf51SGreg Clayton if (inline_info) 21966d3dbf51SGreg Clayton { 21976d3dbf51SGreg Clayton s.PutCString (cstr); 21986d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 21996d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 22006d3dbf51SGreg Clayton } 22016d3dbf51SGreg Clayton 22026d3dbf51SGreg Clayton VariableList args; 22036d3dbf51SGreg Clayton if (variable_list_sp) 2204cc7f9bf5SEnrico Granata variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 22056d3dbf51SGreg Clayton if (args.GetSize() > 0) 22066d3dbf51SGreg Clayton { 22076d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 22086d3dbf51SGreg Clayton const char *close_paren = NULL; 22096d3dbf51SGreg Clayton if (open_paren) 2210855958caSGreg Clayton { 22110769b2b1SMichael Sartain if (IsToken (open_paren, "(anonymous namespace)")) 2212855958caSGreg Clayton { 2213855958caSGreg Clayton open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2214855958caSGreg Clayton if (open_paren) 22156d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 2216855958caSGreg Clayton } 2217855958caSGreg Clayton else 2218855958caSGreg Clayton close_paren = strchr (open_paren, ')'); 2219855958caSGreg Clayton } 22206d3dbf51SGreg Clayton 22216d3dbf51SGreg Clayton if (open_paren) 22226d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 22236d3dbf51SGreg Clayton else 22246d3dbf51SGreg Clayton { 22256d3dbf51SGreg Clayton s.PutCString (cstr); 22266d3dbf51SGreg Clayton s.PutChar ('('); 22276d3dbf51SGreg Clayton } 22285b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 22296d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 22306d3dbf51SGreg Clayton { 22316d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 22326d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 22336d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 22346d3dbf51SGreg Clayton const char *var_value = var_value_sp->GetValueAsCString(); 22356d3dbf51SGreg Clayton if (arg_idx > 0) 22366d3dbf51SGreg Clayton s.PutCString (", "); 22373b188b17SGreg Clayton if (var_value_sp->GetError().Success()) 2238cc7f9bf5SEnrico Granata { 2239cc7f9bf5SEnrico Granata if (var_value) 22406d3dbf51SGreg Clayton s.Printf ("%s=%s", var_name, var_value); 22413b188b17SGreg Clayton else 2242cc7f9bf5SEnrico Granata s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2243cc7f9bf5SEnrico Granata } 2244cc7f9bf5SEnrico Granata else 22453b188b17SGreg Clayton s.Printf ("%s=<unavailable>", var_name); 22466d3dbf51SGreg Clayton } 22476d3dbf51SGreg Clayton 22486d3dbf51SGreg Clayton if (close_paren) 22496d3dbf51SGreg Clayton s.PutCString (close_paren); 22506d3dbf51SGreg Clayton else 22516d3dbf51SGreg Clayton s.PutChar(')'); 22526d3dbf51SGreg Clayton 22536d3dbf51SGreg Clayton } 22546d3dbf51SGreg Clayton else 22556d3dbf51SGreg Clayton { 22566d3dbf51SGreg Clayton s.PutCString(cstr); 22576d3dbf51SGreg Clayton } 22586d3dbf51SGreg Clayton } 22596d3dbf51SGreg Clayton } 22606d3dbf51SGreg Clayton else if (sc->symbol) 22616d3dbf51SGreg Clayton { 22626d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 22636d3dbf51SGreg Clayton if (cstr) 22646d3dbf51SGreg Clayton { 22656d3dbf51SGreg Clayton s.PutCString(cstr); 22666d3dbf51SGreg Clayton var_success = true; 22676d3dbf51SGreg Clayton } 22686d3dbf51SGreg Clayton } 22696d3dbf51SGreg Clayton } 22700769b2b1SMichael Sartain else if (IsToken (var_name_begin, "addr-offset}")) 22711b654882SGreg Clayton { 22721b654882SGreg Clayton var_success = addr != NULL; 22731b654882SGreg Clayton if (var_success) 22741b654882SGreg Clayton { 22751b654882SGreg Clayton format_addr = *addr; 22761b654882SGreg Clayton calculate_format_addr_function_offset = true; 22771b654882SGreg Clayton } 22781b654882SGreg Clayton } 22790769b2b1SMichael Sartain else if (IsToken (var_name_begin, "line-offset}")) 22801b654882SGreg Clayton { 22811b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 22821b654882SGreg Clayton if (var_success) 22831b654882SGreg Clayton { 22841b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 22851b654882SGreg Clayton calculate_format_addr_function_offset = true; 22861b654882SGreg Clayton } 22871b654882SGreg Clayton } 22880769b2b1SMichael Sartain else if (IsToken (var_name_begin, "pc-offset}")) 22891b654882SGreg Clayton { 2290b57e4a1bSJason Molenda StackFrame *frame = exe_ctx->GetFramePtr(); 2291c14ee32dSGreg Clayton var_success = frame != NULL; 22921b654882SGreg Clayton if (var_success) 22931b654882SGreg Clayton { 2294c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 22951b654882SGreg Clayton calculate_format_addr_function_offset = true; 22961b654882SGreg Clayton } 22971b654882SGreg Clayton } 22981b654882SGreg Clayton } 22991b654882SGreg Clayton } 23001b654882SGreg Clayton break; 23011b654882SGreg Clayton 23021b654882SGreg Clayton case 'l': 23030769b2b1SMichael Sartain if (IsToken (var_name_begin, "line.")) 23041b654882SGreg Clayton { 23051b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 23061b654882SGreg Clayton { 23071b654882SGreg Clayton var_name_begin += ::strlen ("line."); 23080769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 23091b654882SGreg Clayton { 23101b654882SGreg Clayton var_name_begin += ::strlen ("file."); 23111b654882SGreg Clayton 23120769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 23131b654882SGreg Clayton { 23141b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 23159076c0ffSSean Callanan var_success = (bool)format_file_spec; 23161b654882SGreg Clayton } 23170769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 23181b654882SGreg Clayton { 23191b654882SGreg Clayton format_file_spec = sc->line_entry.file; 23209076c0ffSSean Callanan var_success = (bool)format_file_spec; 23211b654882SGreg Clayton } 23221b654882SGreg Clayton } 23230769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc)) 23241b654882SGreg Clayton { 23251b654882SGreg Clayton var_success = true; 23260769b2b1SMichael Sartain s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line); 23271b654882SGreg Clayton } 23280769b2b1SMichael Sartain else if ((IsToken (var_name_begin, "start-addr}")) || 23290769b2b1SMichael Sartain (IsToken (var_name_begin, "end-addr}"))) 23301b654882SGreg Clayton { 23311b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 23321b654882SGreg Clayton if (var_success) 23331b654882SGreg Clayton { 23341b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23351b654882SGreg Clayton if (var_name_begin[0] == 'e') 23361b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 23371b654882SGreg Clayton } 23381b654882SGreg Clayton } 23391b654882SGreg Clayton } 23401b654882SGreg Clayton } 23411b654882SGreg Clayton break; 23421b654882SGreg Clayton } 23431b654882SGreg Clayton 23441b654882SGreg Clayton if (var_success) 23451b654882SGreg Clayton { 23461b654882SGreg Clayton // If format addr is valid, then we need to print an address 23471b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 23481b654882SGreg Clayton { 2349b57e4a1bSJason Molenda StackFrame *frame = exe_ctx->GetFramePtr(); 23501b654882SGreg Clayton // We have a register value to display... 23511b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 23521b654882SGreg Clayton { 2353c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23541b654882SGreg Clayton } 23551b654882SGreg Clayton else 23561b654882SGreg Clayton { 23571b654882SGreg Clayton if (reg_ctx == NULL) 2358c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 23591b654882SGreg Clayton 23601b654882SGreg Clayton if (reg_ctx) 23611b654882SGreg Clayton { 23621b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 23631b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 23641b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 23651b654882SGreg Clayton var_success = reg_info != NULL; 23661b654882SGreg Clayton } 23671b654882SGreg Clayton } 23681b654882SGreg Clayton } 23691b654882SGreg Clayton 23701b654882SGreg Clayton if (reg_info != NULL) 23711b654882SGreg Clayton { 23727349bd90SGreg Clayton RegisterValue reg_value; 23737349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 23747349bd90SGreg Clayton if (var_success) 23751b654882SGreg Clayton { 23769a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 23771b654882SGreg Clayton } 23781b654882SGreg Clayton } 23791b654882SGreg Clayton 23801b654882SGreg Clayton if (format_file_spec) 23811b654882SGreg Clayton { 23821b654882SGreg Clayton s << format_file_spec; 23831b654882SGreg Clayton } 23841b654882SGreg Clayton 23851b654882SGreg Clayton // If format addr is valid, then we need to print an address 23861b654882SGreg Clayton if (format_addr.IsValid()) 23871b654882SGreg Clayton { 23880603aa9dSGreg Clayton var_success = false; 23890603aa9dSGreg Clayton 23901b654882SGreg Clayton if (calculate_format_addr_function_offset) 23911b654882SGreg Clayton { 23921b654882SGreg Clayton Address func_addr; 23930603aa9dSGreg Clayton 23940603aa9dSGreg Clayton if (sc) 23950603aa9dSGreg Clayton { 23961b654882SGreg Clayton if (sc->function) 23970d9c9934SGreg Clayton { 23981b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 23990d9c9934SGreg Clayton if (sc->block) 24000d9c9934SGreg Clayton { 24010d9c9934SGreg Clayton // Check to make sure we aren't in an inline 24020d9c9934SGreg Clayton // function. If we are, use the inline block 24030d9c9934SGreg Clayton // range that contains "format_addr" since 24040d9c9934SGreg Clayton // blocks can be discontiguous. 24050d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 24060d9c9934SGreg Clayton AddressRange inline_range; 24070d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 24080d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 24090d9c9934SGreg Clayton } 24100d9c9934SGreg Clayton } 2411e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2412e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 24130603aa9dSGreg Clayton } 24141b654882SGreg Clayton 24150603aa9dSGreg Clayton if (func_addr.IsValid()) 24161b654882SGreg Clayton { 24171b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 24181b654882SGreg Clayton { 24191b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 24201b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 24211b654882SGreg Clayton if (addr_file_addr > func_file_addr) 2422d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 24231b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 2424d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 24250603aa9dSGreg Clayton var_success = true; 24261b654882SGreg Clayton } 24271b654882SGreg Clayton else 24280603aa9dSGreg Clayton { 24290603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24300603aa9dSGreg Clayton if (target) 24310603aa9dSGreg Clayton { 24320603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 24330603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 24340603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 2435d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 24360603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 2437d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 24380603aa9dSGreg Clayton var_success = true; 24390603aa9dSGreg Clayton } 24400603aa9dSGreg Clayton } 24411b654882SGreg Clayton } 24421b654882SGreg Clayton } 24431b654882SGreg Clayton else 24441b654882SGreg Clayton { 24450603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24461b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 24470603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 24480603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 24491b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 24501b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 24511b654882SGreg Clayton 24521b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 24530603aa9dSGreg Clayton { 2454514487e8SGreg Clayton int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 245535f1a0d5SGreg Clayton if (addr_width == 0) 245635f1a0d5SGreg Clayton addr_width = 16; 2457d01b2953SDaniel Malea s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 24580603aa9dSGreg Clayton var_success = true; 24590603aa9dSGreg Clayton } 24601b654882SGreg Clayton } 24611b654882SGreg Clayton } 24621b654882SGreg Clayton } 24631b654882SGreg Clayton 24641b654882SGreg Clayton if (var_success == false) 24651b654882SGreg Clayton success = false; 24661b654882SGreg Clayton } 24671b654882SGreg Clayton p = var_name_end; 24681b654882SGreg Clayton } 24691b654882SGreg Clayton else 24701b654882SGreg Clayton break; 24711b654882SGreg Clayton } 24721b654882SGreg Clayton else 24731b654882SGreg Clayton { 24741b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 24751b654882SGreg Clayton s.PutChar(*p); 24761b654882SGreg Clayton } 24771b654882SGreg Clayton } 24781b654882SGreg Clayton else if (*p == '\\') 24791b654882SGreg Clayton { 24801b654882SGreg Clayton ++p; // skip the slash 24811b654882SGreg Clayton switch (*p) 24821b654882SGreg Clayton { 24831b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 24841b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 24851b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 24861b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 24871b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 24881b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 24891b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 24901b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 24911b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 24921b654882SGreg Clayton case '0': 24931b654882SGreg Clayton // 1 to 3 octal chars 24941b654882SGreg Clayton { 24950603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 24960603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 24970603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 24980603aa9dSGreg Clayton 24990603aa9dSGreg Clayton int i; 25000603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 25010603aa9dSGreg Clayton oct_str[i] = p[i]; 25020603aa9dSGreg Clayton 25030603aa9dSGreg Clayton // We don't want to consume the last octal character since 25040603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 25050603aa9dSGreg Clayton // one less than i (even if i is zero) 25060603aa9dSGreg Clayton p += i - 1; 25070603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 25080603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 25091b654882SGreg Clayton { 2510c7bece56SGreg Clayton s.PutChar((char)octal_value); 25111b654882SGreg Clayton } 25121b654882SGreg Clayton } 25131b654882SGreg Clayton break; 25141b654882SGreg Clayton 25151b654882SGreg Clayton case 'x': 25161b654882SGreg Clayton // hex number in the format 25170603aa9dSGreg Clayton if (isxdigit(p[1])) 25181b654882SGreg Clayton { 25190603aa9dSGreg Clayton ++p; // Skip the 'x' 25201b654882SGreg Clayton 25210603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 25220603aa9dSGreg Clayton // NULL terminator 25231b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 25241b654882SGreg Clayton hex_str[0] = *p; 25250603aa9dSGreg Clayton if (isxdigit(p[1])) 25260603aa9dSGreg Clayton { 25270603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 25281b654882SGreg Clayton hex_str[1] = *p; 25290603aa9dSGreg Clayton } 25300603aa9dSGreg Clayton 25311b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 25320603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 2533c7bece56SGreg Clayton s.PutChar ((char)hex_value); 25341b654882SGreg Clayton } 25351b654882SGreg Clayton else 25361b654882SGreg Clayton { 25370603aa9dSGreg Clayton s.PutChar('x'); 25381b654882SGreg Clayton } 25391b654882SGreg Clayton break; 25401b654882SGreg Clayton 25411b654882SGreg Clayton default: 25420603aa9dSGreg Clayton // Just desensitize any other character by just printing what 25430603aa9dSGreg Clayton // came after the '\' 25440603aa9dSGreg Clayton s << *p; 25451b654882SGreg Clayton break; 25461b654882SGreg Clayton 25471b654882SGreg Clayton } 25481b654882SGreg Clayton 25491b654882SGreg Clayton } 25501b654882SGreg Clayton } 25511b654882SGreg Clayton if (end) 25521b654882SGreg Clayton *end = p; 25531b654882SGreg Clayton return success; 25541b654882SGreg Clayton } 25551b654882SGreg Clayton 2556c3ce7f27SMichael Sartain bool 2557c3ce7f27SMichael Sartain Debugger::FormatPrompt 2558c3ce7f27SMichael Sartain ( 2559c3ce7f27SMichael Sartain const char *format, 2560c3ce7f27SMichael Sartain const SymbolContext *sc, 2561c3ce7f27SMichael Sartain const ExecutionContext *exe_ctx, 2562c3ce7f27SMichael Sartain const Address *addr, 2563c3ce7f27SMichael Sartain Stream &s, 2564c3ce7f27SMichael Sartain ValueObject* valobj 2565c3ce7f27SMichael Sartain ) 2566c3ce7f27SMichael Sartain { 2567c3ce7f27SMichael Sartain bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true; 2568c3ce7f27SMichael Sartain std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color); 2569c3ce7f27SMichael Sartain if (format_str.length()) 2570c3ce7f27SMichael Sartain format = format_str.c_str(); 2571c3ce7f27SMichael Sartain return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj); 2572c3ce7f27SMichael Sartain } 2573c3ce7f27SMichael Sartain 2574228063cdSJim Ingham void 2575228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2576228063cdSJim Ingham { 25774f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 25784f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 25794f02b22dSJim Ingham // callback. 2580228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2581228063cdSJim Ingham } 2582228063cdSJim Ingham 2583228063cdSJim Ingham bool 2584228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2585228063cdSJim Ingham { 2586228063cdSJim Ingham Log::Callbacks log_callbacks; 2587228063cdSJim Ingham 2588228063cdSJim Ingham StreamSP log_stream_sp; 25899a028519SSean Callanan if (m_log_callback_stream_sp) 2590228063cdSJim Ingham { 2591228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2592228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2593228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2594228063cdSJim Ingham } 2595228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2596228063cdSJim Ingham { 259744d93782SGreg Clayton log_stream_sp = GetOutputFile(); 2598228063cdSJim Ingham } 2599228063cdSJim Ingham else 2600228063cdSJim Ingham { 2601228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2602c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 2603c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 2604c1b2ccfdSGreg Clayton if (!log_stream_sp) 2605228063cdSJim Ingham { 2606228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2607228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2608228063cdSJim Ingham } 2609228063cdSJim Ingham } 2610228063cdSJim Ingham assert (log_stream_sp.get()); 2611228063cdSJim Ingham 2612228063cdSJim Ingham if (log_options == 0) 2613228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2614228063cdSJim Ingham 261557abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 2616228063cdSJim Ingham { 2617228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2618228063cdSJim Ingham return true; 2619228063cdSJim Ingham } 2620228063cdSJim Ingham else 2621228063cdSJim Ingham { 2622228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2623228063cdSJim Ingham if (log_channel_sp) 2624228063cdSJim Ingham { 2625228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2626228063cdSJim Ingham { 2627228063cdSJim Ingham return true; 2628228063cdSJim Ingham } 2629228063cdSJim Ingham else 2630228063cdSJim Ingham { 2631228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2632228063cdSJim Ingham return false; 2633228063cdSJim Ingham } 2634228063cdSJim Ingham } 2635228063cdSJim Ingham else 2636228063cdSJim Ingham { 2637228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2638228063cdSJim Ingham return false; 2639228063cdSJim Ingham } 2640228063cdSJim Ingham } 2641228063cdSJim Ingham return false; 2642228063cdSJim Ingham } 2643228063cdSJim Ingham 26449585fbfcSGreg Clayton SourceManager & 26459585fbfcSGreg Clayton Debugger::GetSourceManager () 26469585fbfcSGreg Clayton { 26479585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 26489585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 26499585fbfcSGreg Clayton return *m_source_manager_ap; 26509585fbfcSGreg Clayton } 26519585fbfcSGreg Clayton 26529585fbfcSGreg Clayton 265344d93782SGreg Clayton 265444d93782SGreg Clayton // This function handles events that were broadcast by the process. 265544d93782SGreg Clayton void 265644d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp) 265744d93782SGreg Clayton { 265844d93782SGreg Clayton using namespace lldb; 265944d93782SGreg Clayton const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp); 266044d93782SGreg Clayton 266144d93782SGreg Clayton // if (event_type & eBreakpointEventTypeAdded 266244d93782SGreg Clayton // || event_type & eBreakpointEventTypeRemoved 266344d93782SGreg Clayton // || event_type & eBreakpointEventTypeEnabled 266444d93782SGreg Clayton // || event_type & eBreakpointEventTypeDisabled 266544d93782SGreg Clayton // || event_type & eBreakpointEventTypeCommandChanged 266644d93782SGreg Clayton // || event_type & eBreakpointEventTypeConditionChanged 266744d93782SGreg Clayton // || event_type & eBreakpointEventTypeIgnoreChanged 266844d93782SGreg Clayton // || event_type & eBreakpointEventTypeLocationsResolved) 266944d93782SGreg Clayton // { 267044d93782SGreg Clayton // // Don't do anything about these events, since the breakpoint commands already echo these actions. 267144d93782SGreg Clayton // } 267244d93782SGreg Clayton // 267344d93782SGreg Clayton if (event_type & eBreakpointEventTypeLocationsAdded) 267444d93782SGreg Clayton { 267544d93782SGreg Clayton uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp); 267644d93782SGreg Clayton if (num_new_locations > 0) 267744d93782SGreg Clayton { 267844d93782SGreg Clayton BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 267944d93782SGreg Clayton StreamFileSP output_sp (GetOutputFile()); 268044d93782SGreg Clayton if (output_sp) 268144d93782SGreg Clayton { 268244d93782SGreg Clayton output_sp->Printf("%d location%s added to breakpoint %d\n", 268344d93782SGreg Clayton num_new_locations, 268444d93782SGreg Clayton num_new_locations == 1 ? "" : "s", 268544d93782SGreg Clayton breakpoint->GetID()); 268644d93782SGreg Clayton RefreshTopIOHandler(); 268744d93782SGreg Clayton } 268844d93782SGreg Clayton } 268944d93782SGreg Clayton } 269044d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsRemoved) 269144d93782SGreg Clayton // { 269244d93782SGreg Clayton // // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 269344d93782SGreg Clayton // } 269444d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsResolved) 269544d93782SGreg Clayton // { 269644d93782SGreg Clayton // // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 269744d93782SGreg Clayton // } 269844d93782SGreg Clayton } 269944d93782SGreg Clayton 270044d93782SGreg Clayton size_t 270144d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream) 270244d93782SGreg Clayton { 270344d93782SGreg Clayton size_t total_bytes = 0; 270444d93782SGreg Clayton if (stream == NULL) 270544d93782SGreg Clayton stream = GetOutputFile().get(); 270644d93782SGreg Clayton 270744d93782SGreg Clayton if (stream) 270844d93782SGreg Clayton { 270944d93782SGreg Clayton // The process has stuff waiting for stdout; get it and write it out to the appropriate place. 271044d93782SGreg Clayton if (process == NULL) 271144d93782SGreg Clayton { 271244d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 271344d93782SGreg Clayton if (target_sp) 271444d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 271544d93782SGreg Clayton } 271644d93782SGreg Clayton if (process) 271744d93782SGreg Clayton { 271844d93782SGreg Clayton Error error; 271944d93782SGreg Clayton size_t len; 272044d93782SGreg Clayton char stdio_buffer[1024]; 272144d93782SGreg Clayton while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 272244d93782SGreg Clayton { 272344d93782SGreg Clayton stream->Write(stdio_buffer, len); 272444d93782SGreg Clayton total_bytes += len; 272544d93782SGreg Clayton } 272644d93782SGreg Clayton } 272744d93782SGreg Clayton stream->Flush(); 272844d93782SGreg Clayton } 272944d93782SGreg Clayton return total_bytes; 273044d93782SGreg Clayton } 273144d93782SGreg Clayton 273244d93782SGreg Clayton size_t 273344d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream) 273444d93782SGreg Clayton { 273544d93782SGreg Clayton size_t total_bytes = 0; 273644d93782SGreg Clayton if (stream == NULL) 273744d93782SGreg Clayton stream = GetOutputFile().get(); 273844d93782SGreg Clayton 273944d93782SGreg Clayton if (stream) 274044d93782SGreg Clayton { 274144d93782SGreg Clayton // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 274244d93782SGreg Clayton if (process == NULL) 274344d93782SGreg Clayton { 274444d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 274544d93782SGreg Clayton if (target_sp) 274644d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 274744d93782SGreg Clayton } 274844d93782SGreg Clayton if (process) 274944d93782SGreg Clayton { 275044d93782SGreg Clayton Error error; 275144d93782SGreg Clayton size_t len; 275244d93782SGreg Clayton char stdio_buffer[1024]; 275344d93782SGreg Clayton while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 275444d93782SGreg Clayton { 275544d93782SGreg Clayton stream->Write(stdio_buffer, len); 275644d93782SGreg Clayton total_bytes += len; 275744d93782SGreg Clayton } 275844d93782SGreg Clayton } 275944d93782SGreg Clayton stream->Flush(); 276044d93782SGreg Clayton } 276144d93782SGreg Clayton return total_bytes; 276244d93782SGreg Clayton } 276344d93782SGreg Clayton 276444d93782SGreg Clayton // This function handles events that were broadcast by the process. 276544d93782SGreg Clayton void 276644d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp) 276744d93782SGreg Clayton { 276844d93782SGreg Clayton using namespace lldb; 276944d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 277044d93782SGreg Clayton ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 277144d93782SGreg Clayton 277244d93782SGreg Clayton const bool gui_enabled = IsForwardingEvents(); 277344d93782SGreg Clayton bool top_io_handler_hid = false; 277444d93782SGreg Clayton if (gui_enabled == false) 277544d93782SGreg Clayton top_io_handler_hid = HideTopIOHandler(); 277644d93782SGreg Clayton 277744d93782SGreg Clayton assert (process_sp); 277844d93782SGreg Clayton 277944d93782SGreg Clayton if (event_type & Process::eBroadcastBitSTDOUT) 278044d93782SGreg Clayton { 278144d93782SGreg Clayton // The process has stdout available, get it and write it out to the 278244d93782SGreg Clayton // appropriate place. 278344d93782SGreg Clayton if (top_io_handler_hid) 278444d93782SGreg Clayton GetProcessSTDOUT (process_sp.get(), NULL); 278544d93782SGreg Clayton } 278644d93782SGreg Clayton else if (event_type & Process::eBroadcastBitSTDERR) 278744d93782SGreg Clayton { 278844d93782SGreg Clayton // The process has stderr available, get it and write it out to the 278944d93782SGreg Clayton // appropriate place. 279044d93782SGreg Clayton if (top_io_handler_hid) 279144d93782SGreg Clayton GetProcessSTDERR (process_sp.get(), NULL); 279244d93782SGreg Clayton } 279344d93782SGreg Clayton else if (event_type & Process::eBroadcastBitStateChanged) 279444d93782SGreg Clayton { 279544d93782SGreg Clayton // Drain all stout and stderr so we don't see any output come after 279644d93782SGreg Clayton // we print our prompts 279744d93782SGreg Clayton if (top_io_handler_hid) 279844d93782SGreg Clayton { 279944d93782SGreg Clayton StreamFileSP stream_sp (GetOutputFile()); 280044d93782SGreg Clayton GetProcessSTDOUT (process_sp.get(), stream_sp.get()); 280144d93782SGreg Clayton GetProcessSTDERR (process_sp.get(), NULL); 280244d93782SGreg Clayton // Something changed in the process; get the event and report the process's current status and location to 280344d93782SGreg Clayton // the user. 280444d93782SGreg Clayton StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get()); 280544d93782SGreg Clayton if (event_state == eStateInvalid) 280644d93782SGreg Clayton return; 280744d93782SGreg Clayton 280844d93782SGreg Clayton switch (event_state) 280944d93782SGreg Clayton { 281044d93782SGreg Clayton case eStateInvalid: 281144d93782SGreg Clayton case eStateUnloaded: 281244d93782SGreg Clayton case eStateConnected: 281344d93782SGreg Clayton case eStateAttaching: 281444d93782SGreg Clayton case eStateLaunching: 281544d93782SGreg Clayton case eStateStepping: 281644d93782SGreg Clayton case eStateDetached: 281744d93782SGreg Clayton { 281844d93782SGreg Clayton stream_sp->Printf("Process %" PRIu64 " %s\n", 281944d93782SGreg Clayton process_sp->GetID(), 282044d93782SGreg Clayton StateAsCString (event_state)); 282144d93782SGreg Clayton } 282244d93782SGreg Clayton break; 282344d93782SGreg Clayton 282444d93782SGreg Clayton case eStateRunning: 282544d93782SGreg Clayton // Don't be chatty when we run... 282644d93782SGreg Clayton break; 282744d93782SGreg Clayton 282844d93782SGreg Clayton case eStateExited: 282944d93782SGreg Clayton process_sp->GetStatus(*stream_sp); 283044d93782SGreg Clayton break; 283144d93782SGreg Clayton 283244d93782SGreg Clayton case eStateStopped: 283344d93782SGreg Clayton case eStateCrashed: 283444d93782SGreg Clayton case eStateSuspended: 283544d93782SGreg Clayton // Make sure the program hasn't been auto-restarted: 283644d93782SGreg Clayton if (Process::ProcessEventData::GetRestartedFromEvent (event_sp.get())) 283744d93782SGreg Clayton { 283844d93782SGreg Clayton size_t num_reasons = Process::ProcessEventData::GetNumRestartedReasons(event_sp.get()); 283944d93782SGreg Clayton if (num_reasons > 0) 284044d93782SGreg Clayton { 284144d93782SGreg Clayton // FIXME: Do we want to report this, or would that just be annoyingly chatty? 284244d93782SGreg Clayton if (num_reasons == 1) 284344d93782SGreg Clayton { 284444d93782SGreg Clayton const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), 0); 284544d93782SGreg Clayton stream_sp->Printf("Process %" PRIu64 " stopped and restarted: %s\n", 284644d93782SGreg Clayton process_sp->GetID(), 284744d93782SGreg Clayton reason ? reason : "<UNKNOWN REASON>"); 284844d93782SGreg Clayton } 284944d93782SGreg Clayton else 285044d93782SGreg Clayton { 285144d93782SGreg Clayton stream_sp->Printf("Process %" PRIu64 " stopped and restarted, reasons:\n", 285244d93782SGreg Clayton process_sp->GetID()); 285344d93782SGreg Clayton 285444d93782SGreg Clayton 285544d93782SGreg Clayton for (size_t i = 0; i < num_reasons; i++) 285644d93782SGreg Clayton { 285744d93782SGreg Clayton const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), i); 285844d93782SGreg Clayton stream_sp->Printf("\t%s\n", reason ? reason : "<UNKNOWN REASON>"); 285944d93782SGreg Clayton } 286044d93782SGreg Clayton } 286144d93782SGreg Clayton } 286244d93782SGreg Clayton } 286344d93782SGreg Clayton else 286444d93782SGreg Clayton { 286544d93782SGreg Clayton // Lock the thread list so it doesn't change on us 286644d93782SGreg Clayton ThreadList &thread_list = process_sp->GetThreadList(); 286744d93782SGreg Clayton Mutex::Locker locker (thread_list.GetMutex()); 286844d93782SGreg Clayton 286944d93782SGreg Clayton ThreadSP curr_thread (thread_list.GetSelectedThread()); 287044d93782SGreg Clayton ThreadSP thread; 287144d93782SGreg Clayton StopReason curr_thread_stop_reason = eStopReasonInvalid; 287244d93782SGreg Clayton if (curr_thread) 287344d93782SGreg Clayton curr_thread_stop_reason = curr_thread->GetStopReason(); 2874*c809cbcfSGreg Clayton if (!curr_thread || 2875*c809cbcfSGreg Clayton !curr_thread->IsValid() || 287644d93782SGreg Clayton curr_thread_stop_reason == eStopReasonInvalid || 287744d93782SGreg Clayton curr_thread_stop_reason == eStopReasonNone) 287844d93782SGreg Clayton { 287944d93782SGreg Clayton // Prefer a thread that has just completed its plan over another thread as current thread. 288044d93782SGreg Clayton ThreadSP plan_thread; 288144d93782SGreg Clayton ThreadSP other_thread; 288244d93782SGreg Clayton const size_t num_threads = thread_list.GetSize(); 288344d93782SGreg Clayton size_t i; 288444d93782SGreg Clayton for (i = 0; i < num_threads; ++i) 288544d93782SGreg Clayton { 288644d93782SGreg Clayton thread = thread_list.GetThreadAtIndex(i); 288744d93782SGreg Clayton StopReason thread_stop_reason = thread->GetStopReason(); 288844d93782SGreg Clayton switch (thread_stop_reason) 288944d93782SGreg Clayton { 289044d93782SGreg Clayton case eStopReasonInvalid: 289144d93782SGreg Clayton case eStopReasonNone: 289244d93782SGreg Clayton break; 289344d93782SGreg Clayton 289444d93782SGreg Clayton case eStopReasonTrace: 289544d93782SGreg Clayton case eStopReasonBreakpoint: 289644d93782SGreg Clayton case eStopReasonWatchpoint: 289744d93782SGreg Clayton case eStopReasonSignal: 289844d93782SGreg Clayton case eStopReasonException: 289944d93782SGreg Clayton case eStopReasonExec: 290044d93782SGreg Clayton case eStopReasonThreadExiting: 290144d93782SGreg Clayton if (!other_thread) 290244d93782SGreg Clayton other_thread = thread; 290344d93782SGreg Clayton break; 290444d93782SGreg Clayton case eStopReasonPlanComplete: 290544d93782SGreg Clayton if (!plan_thread) 290644d93782SGreg Clayton plan_thread = thread; 290744d93782SGreg Clayton break; 290844d93782SGreg Clayton } 290944d93782SGreg Clayton } 291044d93782SGreg Clayton if (plan_thread) 291144d93782SGreg Clayton thread_list.SetSelectedThreadByID (plan_thread->GetID()); 291244d93782SGreg Clayton else if (other_thread) 291344d93782SGreg Clayton thread_list.SetSelectedThreadByID (other_thread->GetID()); 291444d93782SGreg Clayton else 291544d93782SGreg Clayton { 291644d93782SGreg Clayton if (curr_thread->IsValid()) 291744d93782SGreg Clayton thread = curr_thread; 291844d93782SGreg Clayton else 291944d93782SGreg Clayton thread = thread_list.GetThreadAtIndex(0); 292044d93782SGreg Clayton 292144d93782SGreg Clayton if (thread) 292244d93782SGreg Clayton thread_list.SetSelectedThreadByID (thread->GetID()); 292344d93782SGreg Clayton } 292444d93782SGreg Clayton } 292544d93782SGreg Clayton 292644d93782SGreg Clayton if (GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget()) 292744d93782SGreg Clayton { 292844d93782SGreg Clayton const bool only_threads_with_stop_reason = true; 292944d93782SGreg Clayton const uint32_t start_frame = 0; 293044d93782SGreg Clayton const uint32_t num_frames = 1; 293144d93782SGreg Clayton const uint32_t num_frames_with_source = 1; 293244d93782SGreg Clayton process_sp->GetStatus(*stream_sp); 293344d93782SGreg Clayton process_sp->GetThreadStatus (*stream_sp, 293444d93782SGreg Clayton only_threads_with_stop_reason, 293544d93782SGreg Clayton start_frame, 293644d93782SGreg Clayton num_frames, 293744d93782SGreg Clayton num_frames_with_source); 293844d93782SGreg Clayton } 293944d93782SGreg Clayton else 294044d93782SGreg Clayton { 294144d93782SGreg Clayton uint32_t target_idx = GetTargetList().GetIndexOfTarget(process_sp->GetTarget().shared_from_this()); 294244d93782SGreg Clayton if (target_idx != UINT32_MAX) 294344d93782SGreg Clayton stream_sp->Printf ("Target %d: (", target_idx); 294444d93782SGreg Clayton else 294544d93782SGreg Clayton stream_sp->Printf ("Target <unknown index>: ("); 294644d93782SGreg Clayton process_sp->GetTarget().Dump (stream_sp.get(), eDescriptionLevelBrief); 294744d93782SGreg Clayton stream_sp->Printf (") stopped.\n"); 294844d93782SGreg Clayton } 294944d93782SGreg Clayton } 295044d93782SGreg Clayton break; 295144d93782SGreg Clayton } 295244d93782SGreg Clayton } 295344d93782SGreg Clayton } 295444d93782SGreg Clayton 295544d93782SGreg Clayton if (top_io_handler_hid) 295644d93782SGreg Clayton RefreshTopIOHandler(); 295744d93782SGreg Clayton } 295844d93782SGreg Clayton 295944d93782SGreg Clayton void 296044d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp) 296144d93782SGreg Clayton { 296244d93782SGreg Clayton // At present the only thread event we handle is the Frame Changed event, 296344d93782SGreg Clayton // and all we do for that is just reprint the thread status for that thread. 296444d93782SGreg Clayton using namespace lldb; 296544d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 296644d93782SGreg Clayton if (event_type == Thread::eBroadcastBitStackChanged || 296744d93782SGreg Clayton event_type == Thread::eBroadcastBitThreadSelected ) 296844d93782SGreg Clayton { 296944d93782SGreg Clayton ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get())); 297044d93782SGreg Clayton if (thread_sp) 297144d93782SGreg Clayton { 297244d93782SGreg Clayton HideTopIOHandler(); 297344d93782SGreg Clayton StreamFileSP stream_sp (GetOutputFile()); 297444d93782SGreg Clayton thread_sp->GetStatus(*stream_sp, 0, 1, 1); 297544d93782SGreg Clayton RefreshTopIOHandler(); 297644d93782SGreg Clayton } 297744d93782SGreg Clayton } 297844d93782SGreg Clayton } 297944d93782SGreg Clayton 298044d93782SGreg Clayton bool 298144d93782SGreg Clayton Debugger::IsForwardingEvents () 298244d93782SGreg Clayton { 298344d93782SGreg Clayton return (bool)m_forward_listener_sp; 298444d93782SGreg Clayton } 298544d93782SGreg Clayton 298644d93782SGreg Clayton void 298744d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp) 298844d93782SGreg Clayton { 298944d93782SGreg Clayton m_forward_listener_sp = listener_sp; 299044d93782SGreg Clayton } 299144d93782SGreg Clayton 299244d93782SGreg Clayton void 299344d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp) 299444d93782SGreg Clayton { 299544d93782SGreg Clayton m_forward_listener_sp.reset(); 299644d93782SGreg Clayton } 299744d93782SGreg Clayton 299844d93782SGreg Clayton 299944d93782SGreg Clayton void 300044d93782SGreg Clayton Debugger::DefaultEventHandler() 300144d93782SGreg Clayton { 300244d93782SGreg Clayton Listener& listener(GetListener()); 300344d93782SGreg Clayton ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 300444d93782SGreg Clayton ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 300544d93782SGreg Clayton ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 300644d93782SGreg Clayton BroadcastEventSpec target_event_spec (broadcaster_class_target, 300744d93782SGreg Clayton Target::eBroadcastBitBreakpointChanged); 300844d93782SGreg Clayton 300944d93782SGreg Clayton BroadcastEventSpec process_event_spec (broadcaster_class_process, 301044d93782SGreg Clayton Process::eBroadcastBitStateChanged | 301144d93782SGreg Clayton Process::eBroadcastBitSTDOUT | 301244d93782SGreg Clayton Process::eBroadcastBitSTDERR); 301344d93782SGreg Clayton 301444d93782SGreg Clayton BroadcastEventSpec thread_event_spec (broadcaster_class_thread, 301544d93782SGreg Clayton Thread::eBroadcastBitStackChanged | 301644d93782SGreg Clayton Thread::eBroadcastBitThreadSelected ); 301744d93782SGreg Clayton 301844d93782SGreg Clayton listener.StartListeningForEventSpec (*this, target_event_spec); 301944d93782SGreg Clayton listener.StartListeningForEventSpec (*this, process_event_spec); 302044d93782SGreg Clayton listener.StartListeningForEventSpec (*this, thread_event_spec); 302144d93782SGreg Clayton listener.StartListeningForEvents (m_command_interpreter_ap.get(), 302244d93782SGreg Clayton CommandInterpreter::eBroadcastBitQuitCommandReceived | 302344d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousOutputData | 302444d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousErrorData ); 302544d93782SGreg Clayton 302644d93782SGreg Clayton bool done = false; 302744d93782SGreg Clayton while (!done) 302844d93782SGreg Clayton { 302944d93782SGreg Clayton // Mutex::Locker locker; 303044d93782SGreg Clayton // if (locker.TryLock(m_input_reader_stack.GetMutex())) 303144d93782SGreg Clayton // { 303244d93782SGreg Clayton // if (m_input_reader_stack.IsEmpty()) 303344d93782SGreg Clayton // break; 303444d93782SGreg Clayton // } 303544d93782SGreg Clayton // 303644d93782SGreg Clayton EventSP event_sp; 303744d93782SGreg Clayton if (listener.WaitForEvent(NULL, event_sp)) 303844d93782SGreg Clayton { 303944d93782SGreg Clayton if (event_sp) 304044d93782SGreg Clayton { 304144d93782SGreg Clayton Broadcaster *broadcaster = event_sp->GetBroadcaster(); 304244d93782SGreg Clayton if (broadcaster) 304344d93782SGreg Clayton { 304444d93782SGreg Clayton uint32_t event_type = event_sp->GetType(); 304544d93782SGreg Clayton ConstString broadcaster_class (broadcaster->GetBroadcasterClass()); 304644d93782SGreg Clayton if (broadcaster_class == broadcaster_class_process) 304744d93782SGreg Clayton { 304844d93782SGreg Clayton HandleProcessEvent (event_sp); 304944d93782SGreg Clayton } 305044d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_target) 305144d93782SGreg Clayton { 305244d93782SGreg Clayton if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get())) 305344d93782SGreg Clayton { 305444d93782SGreg Clayton HandleBreakpointEvent (event_sp); 305544d93782SGreg Clayton } 305644d93782SGreg Clayton } 305744d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_thread) 305844d93782SGreg Clayton { 305944d93782SGreg Clayton HandleThreadEvent (event_sp); 306044d93782SGreg Clayton } 306144d93782SGreg Clayton else if (broadcaster == m_command_interpreter_ap.get()) 306244d93782SGreg Clayton { 306344d93782SGreg Clayton if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived) 306444d93782SGreg Clayton { 306544d93782SGreg Clayton done = true; 306644d93782SGreg Clayton } 306744d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData) 306844d93782SGreg Clayton { 306944d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 307044d93782SGreg Clayton if (data && data[0]) 307144d93782SGreg Clayton { 307244d93782SGreg Clayton StreamFileSP error_sp (GetErrorFile()); 307344d93782SGreg Clayton if (error_sp) 307444d93782SGreg Clayton { 307544d93782SGreg Clayton HideTopIOHandler(); 307644d93782SGreg Clayton error_sp->PutCString(data); 307744d93782SGreg Clayton error_sp->Flush(); 307844d93782SGreg Clayton RefreshTopIOHandler(); 307944d93782SGreg Clayton } 308044d93782SGreg Clayton } 308144d93782SGreg Clayton } 308244d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData) 308344d93782SGreg Clayton { 308444d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 308544d93782SGreg Clayton if (data && data[0]) 308644d93782SGreg Clayton { 308744d93782SGreg Clayton StreamFileSP output_sp (GetOutputFile()); 308844d93782SGreg Clayton if (output_sp) 308944d93782SGreg Clayton { 309044d93782SGreg Clayton HideTopIOHandler(); 309144d93782SGreg Clayton output_sp->PutCString(data); 309244d93782SGreg Clayton output_sp->Flush(); 309344d93782SGreg Clayton RefreshTopIOHandler(); 309444d93782SGreg Clayton } 309544d93782SGreg Clayton } 309644d93782SGreg Clayton } 309744d93782SGreg Clayton } 309844d93782SGreg Clayton } 309944d93782SGreg Clayton 310044d93782SGreg Clayton if (m_forward_listener_sp) 310144d93782SGreg Clayton m_forward_listener_sp->AddEvent(event_sp); 310244d93782SGreg Clayton } 310344d93782SGreg Clayton } 310444d93782SGreg Clayton } 310544d93782SGreg Clayton } 310644d93782SGreg Clayton 310744d93782SGreg Clayton lldb::thread_result_t 310844d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg) 310944d93782SGreg Clayton { 311044d93782SGreg Clayton ((Debugger *)arg)->DefaultEventHandler(); 311144d93782SGreg Clayton return NULL; 311244d93782SGreg Clayton } 311344d93782SGreg Clayton 311444d93782SGreg Clayton bool 311544d93782SGreg Clayton Debugger::StartEventHandlerThread() 311644d93782SGreg Clayton { 311744d93782SGreg Clayton if (!IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread)) 311844d93782SGreg Clayton m_event_handler_thread = Host::ThreadCreate("lldb.debugger.event-handler", EventHandlerThread, this, NULL); 311944d93782SGreg Clayton return IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread); 312044d93782SGreg Clayton } 312144d93782SGreg Clayton 312244d93782SGreg Clayton void 312344d93782SGreg Clayton Debugger::StopEventHandlerThread() 312444d93782SGreg Clayton { 312544d93782SGreg Clayton if (IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread)) 312644d93782SGreg Clayton { 312744d93782SGreg Clayton GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived); 312844d93782SGreg Clayton Host::ThreadJoin(m_event_handler_thread, NULL, NULL); 312944d93782SGreg Clayton m_event_handler_thread = LLDB_INVALID_HOST_THREAD; 313044d93782SGreg Clayton } 313144d93782SGreg Clayton } 313244d93782SGreg Clayton 313344d93782SGreg Clayton 313444d93782SGreg Clayton lldb::thread_result_t 313544d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg) 313644d93782SGreg Clayton { 313744d93782SGreg Clayton Debugger *debugger = (Debugger *)arg; 313844d93782SGreg Clayton debugger->ExecuteIOHanders(); 313944d93782SGreg Clayton debugger->StopEventHandlerThread(); 314044d93782SGreg Clayton return NULL; 314144d93782SGreg Clayton } 314244d93782SGreg Clayton 314344d93782SGreg Clayton bool 314444d93782SGreg Clayton Debugger::StartIOHandlerThread() 314544d93782SGreg Clayton { 314644d93782SGreg Clayton if (!IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread)) 314744d93782SGreg Clayton m_io_handler_thread = Host::ThreadCreate("lldb.debugger.io-handler", IOHandlerThread, this, NULL); 314844d93782SGreg Clayton return IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread); 314944d93782SGreg Clayton } 315044d93782SGreg Clayton 315144d93782SGreg Clayton void 315244d93782SGreg Clayton Debugger::StopIOHandlerThread() 315344d93782SGreg Clayton { 315444d93782SGreg Clayton if (IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread)) 315544d93782SGreg Clayton { 315644d93782SGreg Clayton if (m_input_file_sp) 315744d93782SGreg Clayton m_input_file_sp->GetFile().Close(); 315844d93782SGreg Clayton Host::ThreadJoin(m_io_handler_thread, NULL, NULL); 315944d93782SGreg Clayton m_io_handler_thread = LLDB_INVALID_HOST_THREAD; 316044d93782SGreg Clayton } 316144d93782SGreg Clayton } 316244d93782SGreg Clayton 316344d93782SGreg Clayton 3164