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 1221dfcd9dSEnrico Granata #include "lldb/API/SBDebugger.h" 1321dfcd9dSEnrico Granata 144a33d318SGreg Clayton #include "lldb/Core/Debugger.h" 154a33d318SGreg Clayton 164a33d318SGreg Clayton #include <map> 174a33d318SGreg Clayton 184becb37eSEnrico Granata #include "clang/AST/DeclCXX.h" 194becb37eSEnrico Granata #include "clang/AST/Type.h" 204becb37eSEnrico Granata 2130fdc8d8SChris Lattner #include "lldb/lldb-private.h" 2230fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h" 2330fdc8d8SChris Lattner #include "lldb/Core/InputReader.h" 241f746071SGreg Clayton #include "lldb/Core/Module.h" 25e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h" 267349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 2730fdc8d8SChris Lattner #include "lldb/Core/State.h" 285b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h" 29228063cdSJim Ingham #include "lldb/Core/StreamCallback.h" 301b654882SGreg Clayton #include "lldb/Core/StreamString.h" 3130fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 324becb37eSEnrico Granata #include "lldb/Core/ValueObject.h" 336d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 345548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 355548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h" 3621dfcd9dSEnrico Granata #include "lldb/Host/DynamicLibrary.h" 37a3406614SGreg Clayton #include "lldb/Host/Terminal.h" 386611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 3967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h" 4067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 411f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h" 421f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 431f746071SGreg Clayton #include "lldb/Symbol/Function.h" 441f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 456d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h" 4630fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 4730fdc8d8SChris Lattner #include "lldb/Target/Process.h" 481b654882SGreg Clayton #include "lldb/Target/RegisterContext.h" 491b654882SGreg Clayton #include "lldb/Target/StopInfo.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 10167cc0636SGreg Clayton #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 10267cc0636SGreg Clayton "{, ${frame.pc}}"\ 10367cc0636SGreg Clayton MODULE_WITH_FUNC\ 10467cc0636SGreg Clayton FILE_AND_LINE\ 10567cc0636SGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 10667cc0636SGreg Clayton "{\\nReturn value: ${thread.return-value}}"\ 10767cc0636SGreg Clayton "\\n" 10867cc0636SGreg Clayton 10967cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 11067cc0636SGreg Clayton MODULE_WITH_FUNC\ 11167cc0636SGreg Clayton FILE_AND_LINE\ 11267cc0636SGreg Clayton "\\n" 11367cc0636SGreg Clayton 11467cc0636SGreg Clayton 11567cc0636SGreg Clayton 116754a9369SGreg Clayton static PropertyDefinition 117754a9369SGreg Clayton g_properties[] = 11867cc0636SGreg Clayton { 11967cc0636SGreg Clayton { "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, 12067cc0636SGreg 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." }, 12167cc0636SGreg Clayton { "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, 1224c05410fSGreg Clayton { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 12367cc0636SGreg Clayton { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 12467cc0636SGreg Clayton { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, 12567cc0636SGreg 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." }, 12667cc0636SGreg 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." }, 12767cc0636SGreg 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." }, 12867cc0636SGreg Clayton { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, 12967cc0636SGreg Clayton { "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." }, 13067cc0636SGreg Clayton { "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." }, 131e8cd0c98SGreg Clayton 13267cc0636SGreg Clayton { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 13367cc0636SGreg Clayton }; 13467cc0636SGreg Clayton 13567cc0636SGreg Clayton enum 13667cc0636SGreg Clayton { 13767cc0636SGreg Clayton ePropertyAutoConfirm = 0, 13867cc0636SGreg Clayton ePropertyFrameFormat, 13967cc0636SGreg Clayton ePropertyNotiftVoid, 14067cc0636SGreg Clayton ePropertyPrompt, 14167cc0636SGreg Clayton ePropertyScriptLanguage, 14267cc0636SGreg Clayton ePropertyStopDisassemblyCount, 14367cc0636SGreg Clayton ePropertyStopDisassemblyDisplay, 14467cc0636SGreg Clayton ePropertyStopLineCountAfter, 14567cc0636SGreg Clayton ePropertyStopLineCountBefore, 14667cc0636SGreg Clayton ePropertyTerminalWidth, 14767cc0636SGreg Clayton ePropertyThreadFormat, 14867cc0636SGreg Clayton ePropertyUseExternalEditor 14967cc0636SGreg Clayton }; 15067cc0636SGreg Clayton 15167cc0636SGreg Clayton // 15267cc0636SGreg Clayton //const char * 15367cc0636SGreg Clayton //Debugger::GetFrameFormat() const 15467cc0636SGreg Clayton //{ 15567cc0636SGreg Clayton // return m_properties_sp->GetFrameFormat(); 15667cc0636SGreg Clayton //} 15767cc0636SGreg Clayton //const char * 15867cc0636SGreg Clayton //Debugger::GetThreadFormat() const 15967cc0636SGreg Clayton //{ 16067cc0636SGreg Clayton // return m_properties_sp->GetThreadFormat(); 16167cc0636SGreg Clayton //} 16267cc0636SGreg Clayton // 1634c05410fSGreg Clayton 1644c05410fSGreg Clayton 1654c05410fSGreg Clayton Error 1664c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 1674c05410fSGreg Clayton VarSetOperationType op, 1684c05410fSGreg Clayton const char *property_path, 1694c05410fSGreg Clayton const char *value) 1704c05410fSGreg Clayton { 1714c05410fSGreg Clayton Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 1724c05410fSGreg Clayton if (error.Success()) 1734c05410fSGreg Clayton { 1744c05410fSGreg Clayton if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 1754c05410fSGreg Clayton { 1764c05410fSGreg Clayton const char *new_prompt = GetPrompt(); 1774c05410fSGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 1784c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 1794c05410fSGreg Clayton } 1804c05410fSGreg Clayton } 1814c05410fSGreg Clayton return error; 1824c05410fSGreg Clayton } 1834c05410fSGreg Clayton 18467cc0636SGreg Clayton bool 18567cc0636SGreg Clayton Debugger::GetAutoConfirm () const 18667cc0636SGreg Clayton { 18767cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 188754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 18967cc0636SGreg Clayton } 19067cc0636SGreg Clayton 19167cc0636SGreg Clayton const char * 19267cc0636SGreg Clayton Debugger::GetFrameFormat() const 19367cc0636SGreg Clayton { 19467cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 195754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 19667cc0636SGreg Clayton } 19767cc0636SGreg Clayton 19867cc0636SGreg Clayton bool 19967cc0636SGreg Clayton Debugger::GetNotifyVoid () const 20067cc0636SGreg Clayton { 20167cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 202754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 20367cc0636SGreg Clayton } 20467cc0636SGreg Clayton 20567cc0636SGreg Clayton const char * 20667cc0636SGreg Clayton Debugger::GetPrompt() const 20767cc0636SGreg Clayton { 20867cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 209754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 21067cc0636SGreg Clayton } 21167cc0636SGreg Clayton 21267cc0636SGreg Clayton void 21367cc0636SGreg Clayton Debugger::SetPrompt(const char *p) 21467cc0636SGreg Clayton { 21567cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 21667cc0636SGreg Clayton m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 21767cc0636SGreg Clayton const char *new_prompt = GetPrompt(); 21867cc0636SGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));; 21967cc0636SGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 22067cc0636SGreg Clayton } 22167cc0636SGreg Clayton 22267cc0636SGreg Clayton const char * 22367cc0636SGreg Clayton Debugger::GetThreadFormat() const 22467cc0636SGreg Clayton { 22567cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 226754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 22767cc0636SGreg Clayton } 22867cc0636SGreg Clayton 22967cc0636SGreg Clayton lldb::ScriptLanguage 23067cc0636SGreg Clayton Debugger::GetScriptLanguage() const 23167cc0636SGreg Clayton { 23267cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 233754a9369SGreg Clayton return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 23467cc0636SGreg Clayton } 23567cc0636SGreg Clayton 23667cc0636SGreg Clayton bool 23767cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 23867cc0636SGreg Clayton { 23967cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 24067cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 24167cc0636SGreg Clayton } 24267cc0636SGreg Clayton 24367cc0636SGreg Clayton uint32_t 24467cc0636SGreg Clayton Debugger::GetTerminalWidth () const 24567cc0636SGreg Clayton { 24667cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 247754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 24867cc0636SGreg Clayton } 24967cc0636SGreg Clayton 25067cc0636SGreg Clayton bool 25167cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width) 25267cc0636SGreg Clayton { 25367cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 25467cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 25567cc0636SGreg Clayton } 25667cc0636SGreg Clayton 25767cc0636SGreg Clayton bool 25867cc0636SGreg Clayton Debugger::GetUseExternalEditor () const 25967cc0636SGreg Clayton { 26067cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 261754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 26267cc0636SGreg Clayton } 26367cc0636SGreg Clayton 26467cc0636SGreg Clayton bool 26567cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b) 26667cc0636SGreg Clayton { 26767cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 26867cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 26967cc0636SGreg Clayton } 27067cc0636SGreg Clayton 27167cc0636SGreg Clayton uint32_t 27267cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const 27367cc0636SGreg Clayton { 27467cc0636SGreg Clayton const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 275754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 27667cc0636SGreg Clayton } 27767cc0636SGreg Clayton 27867cc0636SGreg Clayton Debugger::StopDisassemblyType 27967cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const 28067cc0636SGreg Clayton { 28167cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 282754a9369SGreg Clayton return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 28367cc0636SGreg Clayton } 28467cc0636SGreg Clayton 28567cc0636SGreg Clayton uint32_t 28667cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const 28767cc0636SGreg Clayton { 28867cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 289754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 29067cc0636SGreg Clayton } 291e372b98dSGreg Clayton 2921b654882SGreg Clayton #pragma mark Debugger 2931b654882SGreg Clayton 29467cc0636SGreg Clayton //const DebuggerPropertiesSP & 29567cc0636SGreg Clayton //Debugger::GetSettings() const 29667cc0636SGreg Clayton //{ 29767cc0636SGreg Clayton // return m_properties_sp; 29867cc0636SGreg Clayton //} 29967cc0636SGreg Clayton // 30099d0faf2SGreg Clayton 3012f88aadfSCaroline Tice int 3022f88aadfSCaroline Tice Debugger::TestDebuggerRefCount () 3032f88aadfSCaroline Tice { 3042f88aadfSCaroline Tice return g_shared_debugger_refcount; 3052f88aadfSCaroline Tice } 3062f88aadfSCaroline Tice 30730fdc8d8SChris Lattner void 30830fdc8d8SChris Lattner Debugger::Initialize () 30930fdc8d8SChris Lattner { 310c15f55e2SGreg Clayton if (g_shared_debugger_refcount++ == 0) 311dbe54508SGreg Clayton lldb_private::Initialize(); 31299d0faf2SGreg Clayton } 31330fdc8d8SChris Lattner 31430fdc8d8SChris Lattner void 31530fdc8d8SChris Lattner Debugger::Terminate () 31630fdc8d8SChris Lattner { 3176611103cSGreg Clayton if (g_shared_debugger_refcount > 0) 3186611103cSGreg Clayton { 31930fdc8d8SChris Lattner g_shared_debugger_refcount--; 32030fdc8d8SChris Lattner if (g_shared_debugger_refcount == 0) 32130fdc8d8SChris Lattner { 322dbe54508SGreg Clayton lldb_private::WillTerminate(); 323dbe54508SGreg Clayton lldb_private::Terminate(); 3246760a517SCaroline Tice 32599d0faf2SGreg Clayton // Clear our master list of debugger objects 32699d0faf2SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 32799d0faf2SGreg Clayton GetDebuggerList().clear(); 32830fdc8d8SChris Lattner } 3296760a517SCaroline Tice } 3306760a517SCaroline Tice } 33130fdc8d8SChris Lattner 33220bd37f7SCaroline Tice void 33320bd37f7SCaroline Tice Debugger::SettingsInitialize () 33420bd37f7SCaroline Tice { 3356920b52bSGreg Clayton Target::SettingsInitialize (); 33620bd37f7SCaroline Tice } 33720bd37f7SCaroline Tice 33820bd37f7SCaroline Tice void 33920bd37f7SCaroline Tice Debugger::SettingsTerminate () 34020bd37f7SCaroline Tice { 3416920b52bSGreg Clayton Target::SettingsTerminate (); 34220bd37f7SCaroline Tice } 34320bd37f7SCaroline Tice 34421dfcd9dSEnrico Granata bool 34521dfcd9dSEnrico Granata Debugger::LoadPlugin (const FileSpec& spec) 34621dfcd9dSEnrico Granata { 34721dfcd9dSEnrico Granata lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec)); 34821dfcd9dSEnrico Granata lldb::DebuggerSP debugger_sp(shared_from_this()); 34921dfcd9dSEnrico Granata lldb::SBDebugger debugger_sb(debugger_sp); 35021dfcd9dSEnrico Granata // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays 35121dfcd9dSEnrico Granata LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); 35221dfcd9dSEnrico Granata if (!init_func) 35321dfcd9dSEnrico Granata return false; 35421dfcd9dSEnrico Granata if (init_func(debugger_sb)) 35521dfcd9dSEnrico Granata { 35621dfcd9dSEnrico Granata m_loaded_plugins.push_back(dynlib_sp); 35721dfcd9dSEnrico Granata return true; 35821dfcd9dSEnrico Granata } 35921dfcd9dSEnrico Granata return false; 36021dfcd9dSEnrico Granata } 36121dfcd9dSEnrico Granata 36221dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 36321dfcd9dSEnrico Granata LoadPluginCallback 36421dfcd9dSEnrico Granata ( 36521dfcd9dSEnrico Granata void *baton, 36621dfcd9dSEnrico Granata FileSpec::FileType file_type, 36721dfcd9dSEnrico Granata const FileSpec &file_spec 36821dfcd9dSEnrico Granata ) 36921dfcd9dSEnrico Granata { 37021dfcd9dSEnrico Granata Error error; 37121dfcd9dSEnrico Granata 37221dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 37321dfcd9dSEnrico Granata 37421dfcd9dSEnrico Granata if (!baton) 37521dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 37621dfcd9dSEnrico Granata 37721dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 37821dfcd9dSEnrico Granata 37921dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 38021dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 38121dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 38221dfcd9dSEnrico Granata // file type information. 38321dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 38421dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 38521dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 38621dfcd9dSEnrico Granata { 38721dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 38821dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 38921dfcd9dSEnrico Granata 39021dfcd9dSEnrico Granata if (plugin_file_spec.GetFileNameExtension() != g_dylibext) 39121dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 39221dfcd9dSEnrico Granata 39321dfcd9dSEnrico Granata debugger->LoadPlugin (plugin_file_spec); 39421dfcd9dSEnrico Granata 39521dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 39621dfcd9dSEnrico Granata } 39721dfcd9dSEnrico Granata 39821dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 39921dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 40021dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 40121dfcd9dSEnrico Granata { 40221dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 40321dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 40421dfcd9dSEnrico Granata // might be enurating a file system that doesn't have correct file type 40521dfcd9dSEnrico Granata // information. 40621dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 40721dfcd9dSEnrico Granata } 40821dfcd9dSEnrico Granata 40921dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 41021dfcd9dSEnrico Granata } 41121dfcd9dSEnrico Granata 41221dfcd9dSEnrico Granata void 41321dfcd9dSEnrico Granata Debugger::InstanceInitialize () 41421dfcd9dSEnrico Granata { 41521dfcd9dSEnrico Granata FileSpec dir_spec; 41621dfcd9dSEnrico Granata const bool find_directories = true; 41721dfcd9dSEnrico Granata const bool find_files = true; 41821dfcd9dSEnrico Granata const bool find_other = true; 41921dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 42021dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 42121dfcd9dSEnrico Granata { 42221dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 42321dfcd9dSEnrico Granata { 42421dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 42521dfcd9dSEnrico Granata find_directories, 42621dfcd9dSEnrico Granata find_files, 42721dfcd9dSEnrico Granata find_other, 42821dfcd9dSEnrico Granata LoadPluginCallback, 42921dfcd9dSEnrico Granata this); 43021dfcd9dSEnrico Granata } 43121dfcd9dSEnrico Granata } 43221dfcd9dSEnrico Granata 43321dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 43421dfcd9dSEnrico Granata { 43521dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 43621dfcd9dSEnrico Granata { 43721dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 43821dfcd9dSEnrico Granata find_directories, 43921dfcd9dSEnrico Granata find_files, 44021dfcd9dSEnrico Granata find_other, 44121dfcd9dSEnrico Granata LoadPluginCallback, 44221dfcd9dSEnrico Granata this); 44321dfcd9dSEnrico Granata } 44421dfcd9dSEnrico Granata } 445e8cd0c98SGreg Clayton 446e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 44721dfcd9dSEnrico Granata } 44821dfcd9dSEnrico Granata 4496611103cSGreg Clayton DebuggerSP 450228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 4516611103cSGreg Clayton { 452228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 453c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 4546611103cSGreg Clayton { 4556611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 4566611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 4576611103cSGreg Clayton } 45821dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 4596611103cSGreg Clayton return debugger_sp; 4606611103cSGreg Clayton } 4616611103cSGreg Clayton 462e02657b1SCaroline Tice void 4634d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 464e02657b1SCaroline Tice { 465e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 466e02657b1SCaroline Tice return; 467e02657b1SCaroline Tice 4688314c525SJim Ingham debugger_sp->Clear(); 4698314c525SJim Ingham 470c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 471c15f55e2SGreg Clayton { 472e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 473e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 474e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 475e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 476e02657b1SCaroline Tice { 477e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 478e02657b1SCaroline Tice { 479e02657b1SCaroline Tice debugger_list.erase (pos); 480e02657b1SCaroline Tice return; 481e02657b1SCaroline Tice } 482e02657b1SCaroline Tice } 483e02657b1SCaroline Tice } 484c15f55e2SGreg Clayton } 485e02657b1SCaroline Tice 4864d122c40SGreg Clayton DebuggerSP 4873df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 4883df9a8dfSCaroline Tice { 4894d122c40SGreg Clayton DebuggerSP debugger_sp; 4906920b52bSGreg Clayton if (g_shared_debugger_refcount > 0) 4916920b52bSGreg Clayton { 4926920b52bSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 4936920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 4946920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 4956920b52bSGreg Clayton 4966920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 4976920b52bSGreg Clayton { 4986920b52bSGreg Clayton if ((*pos).get()->m_instance_name == instance_name) 4996920b52bSGreg Clayton { 5006920b52bSGreg Clayton debugger_sp = *pos; 5016920b52bSGreg Clayton break; 5026920b52bSGreg Clayton } 5036920b52bSGreg Clayton } 5046920b52bSGreg Clayton } 5053df9a8dfSCaroline Tice return debugger_sp; 5063df9a8dfSCaroline Tice } 5076611103cSGreg Clayton 5086611103cSGreg Clayton TargetSP 5096611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 5106611103cSGreg Clayton { 5114d122c40SGreg Clayton TargetSP target_sp; 512c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 513c15f55e2SGreg Clayton { 5146611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5156611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5166611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5176611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5186611103cSGreg Clayton { 5196611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 5206611103cSGreg Clayton if (target_sp) 5216611103cSGreg Clayton break; 5226611103cSGreg Clayton } 523c15f55e2SGreg Clayton } 5246611103cSGreg Clayton return target_sp; 5256611103cSGreg Clayton } 5266611103cSGreg Clayton 527e4e45924SGreg Clayton TargetSP 528e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 529e4e45924SGreg Clayton { 530e4e45924SGreg Clayton TargetSP target_sp; 531c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 532c15f55e2SGreg Clayton { 533e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 534e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 535e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 536e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 537e4e45924SGreg Clayton { 538e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 539e4e45924SGreg Clayton if (target_sp) 540e4e45924SGreg Clayton break; 541e4e45924SGreg Clayton } 542c15f55e2SGreg Clayton } 543e4e45924SGreg Clayton return target_sp; 544e4e45924SGreg Clayton } 545e4e45924SGreg Clayton 546228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 547ebc1bb27SCaroline Tice UserID (g_unique_id++), 54867cc0636SGreg Clayton Properties(OptionValuePropertiesSP(new OptionValueProperties())), 549d46c87a1SGreg Clayton m_input_comm("debugger.input"), 55030fdc8d8SChris Lattner m_input_file (), 55130fdc8d8SChris Lattner m_output_file (), 55230fdc8d8SChris Lattner m_error_file (), 553c5917d9aSJim Ingham m_terminal_state (), 5544bddaeb5SJim Ingham m_target_list (*this), 555ded470d3SGreg Clayton m_platform_list (), 55630fdc8d8SChris Lattner m_listener ("lldb.Debugger"), 5579585fbfcSGreg Clayton m_source_manager_ap(), 558e37d605eSJim Ingham m_source_file_cache(), 5596611103cSGreg Clayton m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 560d5a0a01bSCaroline Tice m_input_reader_stack (), 56167cc0636SGreg Clayton m_input_reader_data (), 56267cc0636SGreg Clayton m_instance_name() 56330fdc8d8SChris Lattner { 56467cc0636SGreg Clayton char instance_cstr[256]; 56567cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 56667cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 567228063cdSJim Ingham if (log_callback) 568228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 5696611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 570ded470d3SGreg Clayton // Always add our default platform to the platform list 571ded470d3SGreg Clayton PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 572ded470d3SGreg Clayton assert (default_platform_sp.get()); 573ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 57467cc0636SGreg Clayton 575754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 57667cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 57767cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 57867cc0636SGreg Clayton true, 57967cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 580754a9369SGreg Clayton if (m_command_interpreter_ap.get()) 581754a9369SGreg Clayton { 582754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 583754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 584754a9369SGreg Clayton true, 585754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 586754a9369SGreg Clayton } 58767cc0636SGreg Clayton OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 58867cc0636SGreg Clayton term_width->SetMinimumValue(10); 58967cc0636SGreg Clayton term_width->SetMaximumValue(1024); 59030fdc8d8SChris Lattner } 59130fdc8d8SChris Lattner 59230fdc8d8SChris Lattner Debugger::~Debugger () 59330fdc8d8SChris Lattner { 5948314c525SJim Ingham Clear(); 5958314c525SJim Ingham } 5968314c525SJim Ingham 5978314c525SJim Ingham void 5988314c525SJim Ingham Debugger::Clear() 5998314c525SJim Ingham { 6003d6086f6SCaroline Tice CleanUpInputReaders(); 6011ed54f50SGreg Clayton m_listener.Clear(); 6026611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 6036611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 6046611103cSGreg Clayton { 605ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 606ccbc08e6SGreg Clayton if (target_sp) 607ccbc08e6SGreg Clayton { 608ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 6096611103cSGreg Clayton if (process_sp) 6101fd07059SJim Ingham process_sp->Finalize(); 611ccbc08e6SGreg Clayton target_sp->Destroy(); 6126611103cSGreg Clayton } 61330fdc8d8SChris Lattner } 6144bddaeb5SJim Ingham BroadcasterManager::Clear (); 61530fdc8d8SChris Lattner 6160d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 6170d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 618c5917d9aSJim Ingham m_terminal_state.Clear(); 6190d69a3a4SGreg Clayton GetInputFile().Close (); 6200d69a3a4SGreg Clayton // Now that we have closed m_input_file, we can now tell our input communication 6210d69a3a4SGreg Clayton // class to close down. Its read thread should quickly exit after we close 6220d69a3a4SGreg Clayton // the input file handle above. 6230d69a3a4SGreg Clayton m_input_comm.Clear (); 6248314c525SJim Ingham } 62530fdc8d8SChris Lattner 62630fdc8d8SChris Lattner bool 627fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 628fc3f027dSGreg Clayton { 629fc3f027dSGreg Clayton return m_input_comm.GetCloseOnEOF(); 630fc3f027dSGreg Clayton } 631fc3f027dSGreg Clayton 632fc3f027dSGreg Clayton void 633fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 634fc3f027dSGreg Clayton { 635fc3f027dSGreg Clayton m_input_comm.SetCloseOnEOF(b); 636fc3f027dSGreg Clayton } 637fc3f027dSGreg Clayton 638fc3f027dSGreg Clayton bool 63930fdc8d8SChris Lattner Debugger::GetAsyncExecution () 64030fdc8d8SChris Lattner { 6416611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 64230fdc8d8SChris Lattner } 64330fdc8d8SChris Lattner 64430fdc8d8SChris Lattner void 64530fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 64630fdc8d8SChris Lattner { 6476611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 64830fdc8d8SChris Lattner } 64930fdc8d8SChris Lattner 65030fdc8d8SChris Lattner 65130fdc8d8SChris Lattner void 65230fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 65330fdc8d8SChris Lattner { 65451b1e2d2SGreg Clayton File &in_file = GetInputFile(); 65551b1e2d2SGreg Clayton in_file.SetStream (fh, tranfer_ownership); 65651b1e2d2SGreg Clayton if (in_file.IsValid() == false) 65751b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 65830fdc8d8SChris Lattner 65930fdc8d8SChris Lattner // Disconnect from any old connection if we had one 66030fdc8d8SChris Lattner m_input_comm.Disconnect (); 66132720b51SGreg Clayton // Pass false as the second argument to ConnectionFileDescriptor below because 66232720b51SGreg Clayton // our "in_file" above will already take ownership if requested and we don't 66332720b51SGreg Clayton // want to objects trying to own and close a file descriptor. 66432720b51SGreg Clayton m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false)); 66530fdc8d8SChris Lattner m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); 66630fdc8d8SChris Lattner 667c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 668c5917d9aSJim Ingham SaveInputTerminalState (); 669c5917d9aSJim Ingham 67030fdc8d8SChris Lattner Error error; 67130fdc8d8SChris Lattner if (m_input_comm.StartReadThread (&error) == false) 67230fdc8d8SChris Lattner { 67351b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 67451b1e2d2SGreg Clayton 67551b1e2d2SGreg Clayton err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); 67630fdc8d8SChris Lattner exit(1); 67730fdc8d8SChris Lattner } 67830fdc8d8SChris Lattner } 67930fdc8d8SChris Lattner 68030fdc8d8SChris Lattner void 68130fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 68230fdc8d8SChris Lattner { 68351b1e2d2SGreg Clayton File &out_file = GetOutputFile(); 68451b1e2d2SGreg Clayton out_file.SetStream (fh, tranfer_ownership); 68551b1e2d2SGreg Clayton if (out_file.IsValid() == false) 68651b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 6872f88aadfSCaroline Tice 688b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 689b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 690b588726eSEnrico Granata const bool can_create = false; 691b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 692b588726eSEnrico Granata if (script_interpreter) 693b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 69430fdc8d8SChris Lattner } 69530fdc8d8SChris Lattner 69630fdc8d8SChris Lattner void 69730fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 69830fdc8d8SChris Lattner { 69951b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 70051b1e2d2SGreg Clayton err_file.SetStream (fh, tranfer_ownership); 70151b1e2d2SGreg Clayton if (err_file.IsValid() == false) 70251b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 70330fdc8d8SChris Lattner } 70430fdc8d8SChris Lattner 705c5917d9aSJim Ingham void 706c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 707c5917d9aSJim Ingham { 708c5917d9aSJim Ingham File &in_file = GetInputFile(); 709c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 710c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 711c5917d9aSJim Ingham } 712c5917d9aSJim Ingham 713c5917d9aSJim Ingham void 714c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 715c5917d9aSJim Ingham { 716c5917d9aSJim Ingham m_terminal_state.Restore(); 717c5917d9aSJim Ingham } 718c5917d9aSJim Ingham 71930fdc8d8SChris Lattner ExecutionContext 7202976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 72130fdc8d8SChris Lattner { 72230fdc8d8SChris Lattner ExecutionContext exe_ctx; 723c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 724c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 72530fdc8d8SChris Lattner 72630fdc8d8SChris Lattner if (target_sp) 72730fdc8d8SChris Lattner { 728c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 729c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 730c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 73130fdc8d8SChris Lattner { 732c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 733c14ee32dSGreg Clayton if (thread_sp) 73430fdc8d8SChris Lattner { 735c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 736c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 737c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 738c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 73930fdc8d8SChris Lattner } 74030fdc8d8SChris Lattner } 74130fdc8d8SChris Lattner } 74230fdc8d8SChris Lattner return exe_ctx; 74330fdc8d8SChris Lattner 74430fdc8d8SChris Lattner } 74530fdc8d8SChris Lattner 746b44880caSCaroline Tice InputReaderSP 747b44880caSCaroline Tice Debugger::GetCurrentInputReader () 748b44880caSCaroline Tice { 749b44880caSCaroline Tice InputReaderSP reader_sp; 750b44880caSCaroline Tice 751d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 752b44880caSCaroline Tice { 753b44880caSCaroline Tice // Clear any finished readers from the stack 754b44880caSCaroline Tice while (CheckIfTopInputReaderIsDone()) ; 755b44880caSCaroline Tice 756d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 757d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 758b44880caSCaroline Tice } 759b44880caSCaroline Tice 760b44880caSCaroline Tice return reader_sp; 761b44880caSCaroline Tice } 762b44880caSCaroline Tice 76330fdc8d8SChris Lattner void 76430fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len) 76530fdc8d8SChris Lattner { 766efed6131SCaroline Tice if (bytes_len > 0) 76730fdc8d8SChris Lattner ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len); 768efed6131SCaroline Tice else 769efed6131SCaroline Tice ((Debugger *)baton)->DispatchInputEndOfFile (); 77030fdc8d8SChris Lattner } 77130fdc8d8SChris Lattner 77230fdc8d8SChris Lattner 77330fdc8d8SChris Lattner void 77430fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len) 77530fdc8d8SChris Lattner { 776efed6131SCaroline Tice if (bytes == NULL || bytes_len == 0) 777efed6131SCaroline Tice return; 77830fdc8d8SChris Lattner 77930fdc8d8SChris Lattner WriteToDefaultReader (bytes, bytes_len); 78030fdc8d8SChris Lattner } 78130fdc8d8SChris Lattner 78230fdc8d8SChris Lattner void 783efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 784efed6131SCaroline Tice { 785efed6131SCaroline Tice m_input_reader_data.clear(); 786efed6131SCaroline Tice 787b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 788efed6131SCaroline Tice if (reader_sp) 789b44880caSCaroline Tice { 790efed6131SCaroline Tice reader_sp->Notify (eInputReaderInterrupt); 791efed6131SCaroline Tice 792b44880caSCaroline Tice // If notifying the reader of the interrupt finished the reader, we should pop it off the stack. 793efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 794efed6131SCaroline Tice } 795efed6131SCaroline Tice } 796efed6131SCaroline Tice 797efed6131SCaroline Tice void 798efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 799efed6131SCaroline Tice { 800efed6131SCaroline Tice m_input_reader_data.clear(); 801efed6131SCaroline Tice 802b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 803efed6131SCaroline Tice if (reader_sp) 804b44880caSCaroline Tice { 805efed6131SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 806efed6131SCaroline Tice 807b44880caSCaroline Tice // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack. 808efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 809efed6131SCaroline Tice } 810efed6131SCaroline Tice } 811efed6131SCaroline Tice 812efed6131SCaroline Tice void 8133d6086f6SCaroline Tice Debugger::CleanUpInputReaders () 8143d6086f6SCaroline Tice { 8153d6086f6SCaroline Tice m_input_reader_data.clear(); 8163d6086f6SCaroline Tice 817b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 818d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 8193d6086f6SCaroline Tice { 820b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 8213d6086f6SCaroline Tice if (reader_sp) 8223d6086f6SCaroline Tice { 8233d6086f6SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 8243d6086f6SCaroline Tice reader_sp->SetIsDone (true); 8253d6086f6SCaroline Tice } 8263d6086f6SCaroline Tice } 8273d6086f6SCaroline Tice } 8283d6086f6SCaroline Tice 8293d6086f6SCaroline Tice void 830969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification) 831969ed3d1SCaroline Tice { 832969ed3d1SCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader()); 833969ed3d1SCaroline Tice if (reader_sp) 834969ed3d1SCaroline Tice { 835969ed3d1SCaroline Tice reader_sp->Notify (notification); 836969ed3d1SCaroline Tice 837969ed3d1SCaroline Tice // Flush out any input readers that are done. 838969ed3d1SCaroline Tice while (CheckIfTopInputReaderIsDone ()) 839969ed3d1SCaroline Tice /* Do nothing. */; 840969ed3d1SCaroline Tice } 841969ed3d1SCaroline Tice } 842969ed3d1SCaroline Tice 8439088b068SCaroline Tice bool 8444d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp) 8459088b068SCaroline Tice { 8469088b068SCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader()); 8479088b068SCaroline Tice 848d61c10bcSCaroline Tice return (reader_sp.get() == top_reader_sp.get()); 8499088b068SCaroline Tice } 8509088b068SCaroline Tice 8519088b068SCaroline Tice 852969ed3d1SCaroline Tice void 85330fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) 85430fdc8d8SChris Lattner { 85530fdc8d8SChris Lattner if (bytes && bytes_len) 85630fdc8d8SChris Lattner m_input_reader_data.append (bytes, bytes_len); 85730fdc8d8SChris Lattner 85830fdc8d8SChris Lattner if (m_input_reader_data.empty()) 85930fdc8d8SChris Lattner return; 86030fdc8d8SChris Lattner 861d5a0a01bSCaroline Tice while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty()) 86230fdc8d8SChris Lattner { 86330fdc8d8SChris Lattner // Get the input reader from the top of the stack 864b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 86530fdc8d8SChris Lattner if (!reader_sp) 86630fdc8d8SChris Lattner break; 86730fdc8d8SChris Lattner 868471b31ceSGreg Clayton size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 86930fdc8d8SChris Lattner m_input_reader_data.size()); 87030fdc8d8SChris Lattner if (bytes_handled) 87130fdc8d8SChris Lattner { 87230fdc8d8SChris Lattner m_input_reader_data.erase (0, bytes_handled); 87330fdc8d8SChris Lattner } 87430fdc8d8SChris Lattner else 87530fdc8d8SChris Lattner { 87630fdc8d8SChris Lattner // No bytes were handled, we might not have reached our 87730fdc8d8SChris Lattner // granularity, just return and wait for more data 87830fdc8d8SChris Lattner break; 87930fdc8d8SChris Lattner } 88030fdc8d8SChris Lattner } 88130fdc8d8SChris Lattner 882b44880caSCaroline Tice // Flush out any input readers that are done. 88330fdc8d8SChris Lattner while (CheckIfTopInputReaderIsDone ()) 88430fdc8d8SChris Lattner /* Do nothing. */; 88530fdc8d8SChris Lattner 88630fdc8d8SChris Lattner } 88730fdc8d8SChris Lattner 88830fdc8d8SChris Lattner void 88930fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp) 89030fdc8d8SChris Lattner { 89130fdc8d8SChris Lattner if (!reader_sp) 89230fdc8d8SChris Lattner return; 893b44880caSCaroline Tice 89430fdc8d8SChris Lattner // Deactivate the old top reader 895b44880caSCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader ()); 896b44880caSCaroline Tice 89730fdc8d8SChris Lattner if (top_reader_sp) 89830fdc8d8SChris Lattner top_reader_sp->Notify (eInputReaderDeactivate); 899b44880caSCaroline Tice 900d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 90130fdc8d8SChris Lattner reader_sp->Notify (eInputReaderActivate); 90230fdc8d8SChris Lattner ActivateInputReader (reader_sp); 90330fdc8d8SChris Lattner } 90430fdc8d8SChris Lattner 90530fdc8d8SChris Lattner bool 9064d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp) 90730fdc8d8SChris Lattner { 90830fdc8d8SChris Lattner bool result = false; 90930fdc8d8SChris Lattner 91030fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 91130fdc8d8SChris Lattner // read on the stack referesh its prompt and if there is one... 912d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 91330fdc8d8SChris Lattner { 914b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 915d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 91630fdc8d8SChris Lattner 91730fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 91830fdc8d8SChris Lattner { 919d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 92030fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDeactivate); 92130fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDone); 92230fdc8d8SChris Lattner result = true; 92330fdc8d8SChris Lattner 924d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 92530fdc8d8SChris Lattner { 926d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 92730fdc8d8SChris Lattner if (reader_sp) 92830fdc8d8SChris Lattner { 92930fdc8d8SChris Lattner ActivateInputReader (reader_sp); 93030fdc8d8SChris Lattner reader_sp->Notify (eInputReaderReactivate); 93130fdc8d8SChris Lattner } 93230fdc8d8SChris Lattner } 93330fdc8d8SChris Lattner } 93430fdc8d8SChris Lattner } 93530fdc8d8SChris Lattner return result; 93630fdc8d8SChris Lattner } 93730fdc8d8SChris Lattner 93830fdc8d8SChris Lattner bool 93930fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone () 94030fdc8d8SChris Lattner { 94130fdc8d8SChris Lattner bool result = false; 942d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 94330fdc8d8SChris Lattner { 944b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 945d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 94630fdc8d8SChris Lattner 94730fdc8d8SChris Lattner if (reader_sp && reader_sp->IsDone()) 94830fdc8d8SChris Lattner { 94930fdc8d8SChris Lattner result = true; 95030fdc8d8SChris Lattner PopInputReader (reader_sp); 95130fdc8d8SChris Lattner } 95230fdc8d8SChris Lattner } 95330fdc8d8SChris Lattner return result; 95430fdc8d8SChris Lattner } 95530fdc8d8SChris Lattner 95630fdc8d8SChris Lattner void 95730fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 95830fdc8d8SChris Lattner { 95951b1e2d2SGreg Clayton int input_fd = m_input_file.GetFile().GetDescriptor(); 96030fdc8d8SChris Lattner 96151b1e2d2SGreg Clayton if (input_fd >= 0) 96230fdc8d8SChris Lattner { 96351b1e2d2SGreg Clayton Terminal tty(input_fd); 964a3406614SGreg Clayton 965a3406614SGreg Clayton tty.SetEcho(reader_sp->GetEcho()); 96630fdc8d8SChris Lattner 96730fdc8d8SChris Lattner switch (reader_sp->GetGranularity()) 96830fdc8d8SChris Lattner { 96930fdc8d8SChris Lattner case eInputReaderGranularityByte: 97030fdc8d8SChris Lattner case eInputReaderGranularityWord: 971a3406614SGreg Clayton tty.SetCanonical (false); 97230fdc8d8SChris Lattner break; 97330fdc8d8SChris Lattner 97430fdc8d8SChris Lattner case eInputReaderGranularityLine: 97530fdc8d8SChris Lattner case eInputReaderGranularityAll: 976a3406614SGreg Clayton tty.SetCanonical (true); 97730fdc8d8SChris Lattner break; 97830fdc8d8SChris Lattner 97930fdc8d8SChris Lattner default: 98030fdc8d8SChris Lattner break; 98130fdc8d8SChris Lattner } 98230fdc8d8SChris Lattner } 98330fdc8d8SChris Lattner } 9846611103cSGreg Clayton 9855b52f0c7SJim Ingham StreamSP 9865b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 9875b52f0c7SJim Ingham { 9885b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 9895b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 9905b52f0c7SJim Ingham } 9915b52f0c7SJim Ingham 9925b52f0c7SJim Ingham StreamSP 9935b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 9945b52f0c7SJim Ingham { 9955b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 9965b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 9975b52f0c7SJim Ingham } 9985b52f0c7SJim Ingham 999c7bece56SGreg Clayton size_t 1000061858ceSEnrico Granata Debugger::GetNumDebuggers() 1001061858ceSEnrico Granata { 1002c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1003c15f55e2SGreg Clayton { 1004061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1005061858ceSEnrico Granata return GetDebuggerList().size(); 1006061858ceSEnrico Granata } 1007c15f55e2SGreg Clayton return 0; 1008c15f55e2SGreg Clayton } 1009061858ceSEnrico Granata 1010061858ceSEnrico Granata lldb::DebuggerSP 1011c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1012061858ceSEnrico Granata { 1013061858ceSEnrico Granata DebuggerSP debugger_sp; 1014061858ceSEnrico Granata 1015c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1016c15f55e2SGreg Clayton { 1017061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1018061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1019061858ceSEnrico Granata 1020061858ceSEnrico Granata if (index < debugger_list.size()) 1021061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1022c15f55e2SGreg Clayton } 1023061858ceSEnrico Granata 1024061858ceSEnrico Granata return debugger_sp; 1025061858ceSEnrico Granata } 1026061858ceSEnrico Granata 1027ebc1bb27SCaroline Tice DebuggerSP 1028ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1029ebc1bb27SCaroline Tice { 10304d122c40SGreg Clayton DebuggerSP debugger_sp; 1031ebc1bb27SCaroline Tice 1032c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1033c15f55e2SGreg Clayton { 1034ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 1035ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1036ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1037ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1038ebc1bb27SCaroline Tice { 1039ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 1040ebc1bb27SCaroline Tice { 1041ebc1bb27SCaroline Tice debugger_sp = *pos; 1042ebc1bb27SCaroline Tice break; 1043ebc1bb27SCaroline Tice } 1044ebc1bb27SCaroline Tice } 1045c15f55e2SGreg Clayton } 1046ebc1bb27SCaroline Tice return debugger_sp; 1047ebc1bb27SCaroline Tice } 10483df9a8dfSCaroline Tice 10491b654882SGreg Clayton static void 10501b654882SGreg Clayton TestPromptFormats (StackFrame *frame) 10511b654882SGreg Clayton { 10521b654882SGreg Clayton if (frame == NULL) 10531b654882SGreg Clayton return; 10541b654882SGreg Clayton 10551b654882SGreg Clayton StreamString s; 10561b654882SGreg Clayton const char *prompt_format = 10571b654882SGreg Clayton "{addr = '${addr}'\n}" 10581b654882SGreg Clayton "{process.id = '${process.id}'\n}" 10591b654882SGreg Clayton "{process.name = '${process.name}'\n}" 10601b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 10611b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 10621b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 10631b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 10641b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 10651b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 10661b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 10671b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 10681b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 10691b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 10701b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 10711b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 10721b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 10731b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 10741b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 10751b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 10761b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 10771b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 10781b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 10791b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 10801b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 10811b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 10821b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 10831b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 10841b654882SGreg Clayton "{function.id = '${function.id}'\n}" 10851b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1086ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 10871b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 10881b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 10891b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 10901b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 10911b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 10921b654882SGreg Clayton "{line.number = '${line.number}'\n}" 10931b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 10941b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 10951b654882SGreg Clayton ; 10961b654882SGreg Clayton 10971b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 10981b654882SGreg Clayton ExecutionContext exe_ctx; 10990603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 11001b654882SGreg Clayton const char *end = NULL; 11011b654882SGreg Clayton if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end)) 11021b654882SGreg Clayton { 11031b654882SGreg Clayton printf("%s\n", s.GetData()); 11041b654882SGreg Clayton } 11051b654882SGreg Clayton else 11061b654882SGreg Clayton { 11071b654882SGreg Clayton printf ("error: at '%s'\n", end); 11081b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 11091b654882SGreg Clayton } 11101b654882SGreg Clayton } 11111b654882SGreg Clayton 11129fc1944eSEnrico Granata static bool 11139fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin, 11149fc1944eSEnrico Granata const char* var_name_end, 11159fc1944eSEnrico Granata const char** var_name_final, 11169fc1944eSEnrico Granata const char** percent_position, 11174d122c40SGreg Clayton Format* custom_format, 11189fc1944eSEnrico Granata ValueObject::ValueObjectRepresentationStyle* val_obj_display) 11199fc1944eSEnrico Granata { 1120e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 11219fc1944eSEnrico Granata *percent_position = ::strchr(var_name_begin,'%'); 11229fc1944eSEnrico Granata if (!*percent_position || *percent_position > var_name_end) 1123e992a089SEnrico Granata { 1124e992a089SEnrico Granata if (log) 1125d228483dSEnrico Granata log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 11269fc1944eSEnrico Granata *var_name_final = var_name_end; 1127e992a089SEnrico Granata } 11289fc1944eSEnrico Granata else 11299fc1944eSEnrico Granata { 11309fc1944eSEnrico Granata *var_name_final = *percent_position; 11319fc1944eSEnrico Granata char* format_name = new char[var_name_end-*var_name_final]; format_name[var_name_end-*var_name_final-1] = '\0'; 11329fc1944eSEnrico Granata memcpy(format_name, *var_name_final+1, var_name_end-*var_name_final-1); 1133e992a089SEnrico Granata if (log) 1134d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] parsing %s as a format descriptor", format_name); 11359fc1944eSEnrico Granata if ( !FormatManager::GetFormatFromCString(format_name, 11369fc1944eSEnrico Granata true, 11379fc1944eSEnrico Granata *custom_format) ) 11389fc1944eSEnrico Granata { 1139e992a089SEnrico Granata if (log) 1140d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] %s is an unknown format", format_name); 11419fc1944eSEnrico Granata // if this is an @ sign, print ObjC description 11429fc1944eSEnrico Granata if (*format_name == '@') 114386cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 11449fc1944eSEnrico Granata // if this is a V, print the value using the default format 1145e992a089SEnrico Granata else if (*format_name == 'V') 114686cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1147d55546b2SEnrico Granata // if this is an L, print the location of the value 1148e992a089SEnrico Granata else if (*format_name == 'L') 114986cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 1150d55546b2SEnrico Granata // if this is an S, print the summary after all 1151e992a089SEnrico Granata else if (*format_name == 'S') 115286cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 11535dfd49ccSEnrico Granata else if (*format_name == '#') 115486cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 1155d64d0bc0SEnrico Granata else if (*format_name == 'T') 115686cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 1157e992a089SEnrico Granata else if (log) 1158d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name); 11599fc1944eSEnrico Granata } 11609fc1944eSEnrico Granata // a good custom format tells us to print the value using it 11619fc1944eSEnrico Granata else 1162e992a089SEnrico Granata { 1163e992a089SEnrico Granata if (log) 1164d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] will display value for this VO"); 116586cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1166e992a089SEnrico Granata } 11679fc1944eSEnrico Granata delete format_name; 11689fc1944eSEnrico Granata } 1169e992a089SEnrico Granata if (log) 1170d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1171e992a089SEnrico Granata *custom_format, 1172e992a089SEnrico Granata *val_obj_display); 11739fc1944eSEnrico Granata return true; 11749fc1944eSEnrico Granata } 11759fc1944eSEnrico Granata 11769fc1944eSEnrico Granata static bool 11779fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 11789fc1944eSEnrico Granata const char* var_name_end, 11799fc1944eSEnrico Granata const char* var_name_final, 11809fc1944eSEnrico Granata const char** open_bracket_position, 11819fc1944eSEnrico Granata const char** separator_position, 11829fc1944eSEnrico Granata const char** close_bracket_position, 11839fc1944eSEnrico Granata const char** var_name_final_if_array_range, 11849fc1944eSEnrico Granata int64_t* index_lower, 11859fc1944eSEnrico Granata int64_t* index_higher) 11869fc1944eSEnrico Granata { 1187e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 11889fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 11899fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 11909fc1944eSEnrico Granata { 11919fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 11929fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 11939fc1944eSEnrico Granata // as usual, we assume that [] will come before % 11949fc1944eSEnrico Granata //printf("trying to expand a []\n"); 11959fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 11969fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 11979fc1944eSEnrico Granata { 1198e992a089SEnrico Granata if (log) 1199d228483dSEnrico Granata log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 12009fc1944eSEnrico Granata *index_lower = 0; 12019fc1944eSEnrico Granata } 12029fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 12039fc1944eSEnrico Granata { 12049fc1944eSEnrico Granata char *end = NULL; 12059fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12069fc1944eSEnrico Granata *index_higher = *index_lower; 1207e992a089SEnrico Granata if (log) 1208d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 12099fc1944eSEnrico Granata } 12109fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 12119fc1944eSEnrico Granata { 12129fc1944eSEnrico Granata char *end = NULL; 12139fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12149fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 1215e992a089SEnrico Granata if (log) 1216d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 12179fc1944eSEnrico Granata } 12189fc1944eSEnrico Granata else 1219e992a089SEnrico Granata { 1220e992a089SEnrico Granata if (log) 1221d228483dSEnrico Granata log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 12229fc1944eSEnrico Granata return false; 1223e992a089SEnrico Granata } 12249fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 12259fc1944eSEnrico Granata { 1226e992a089SEnrico Granata if (log) 1227d228483dSEnrico Granata log->Printf("[ScanBracketedRange] swapping indices"); 1228c7bece56SGreg Clayton int64_t temp = *index_lower; 12299fc1944eSEnrico Granata *index_lower = *index_higher; 12309fc1944eSEnrico Granata *index_higher = temp; 12319fc1944eSEnrico Granata } 12329fc1944eSEnrico Granata } 1233e992a089SEnrico Granata else if (log) 1234d228483dSEnrico Granata log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 12359fc1944eSEnrico Granata return true; 12369fc1944eSEnrico Granata } 12379fc1944eSEnrico Granata 12389fc1944eSEnrico Granata static ValueObjectSP 1239c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 1240c7bece56SGreg Clayton size_t index, 12419fc1944eSEnrico Granata StackFrame* frame, 1242fc7a7f3bSEnrico Granata bool deref_pointer) 12439fc1944eSEnrico Granata { 1244e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1245fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1246599171adSEnrico Granata std::string ptr_deref_buffer(10,0); 1247599171adSEnrico Granata ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1248e992a089SEnrico Granata if (log) 1249599171adSEnrico Granata log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1250fc7a7f3bSEnrico Granata const char* first_unparsed; 1251fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1252fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1253fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 125486cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1255599171adSEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1256fc7a7f3bSEnrico Granata &first_unparsed, 1257fc7a7f3bSEnrico Granata &reason_to_stop, 1258fc7a7f3bSEnrico Granata &final_value_type, 1259fc7a7f3bSEnrico Granata options, 1260fc7a7f3bSEnrico Granata &what_next); 1261fc7a7f3bSEnrico Granata if (!item) 1262fc7a7f3bSEnrico Granata { 1263e992a089SEnrico Granata if (log) 1264d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1265e992a089SEnrico Granata " final_value_type %d", 1266fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1267fc7a7f3bSEnrico Granata } 12689fc1944eSEnrico Granata else 12699fc1944eSEnrico Granata { 1270e992a089SEnrico Granata if (log) 1271d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1272e992a089SEnrico Granata " final_value_type %d", 1273fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 12749fc1944eSEnrico Granata } 12759fc1944eSEnrico Granata return item; 12769fc1944eSEnrico Granata } 12779fc1944eSEnrico Granata 12781b654882SGreg Clayton bool 12791b654882SGreg Clayton Debugger::FormatPrompt 12801b654882SGreg Clayton ( 12811b654882SGreg Clayton const char *format, 12821b654882SGreg Clayton const SymbolContext *sc, 12831b654882SGreg Clayton const ExecutionContext *exe_ctx, 12841b654882SGreg Clayton const Address *addr, 12851b654882SGreg Clayton Stream &s, 12864becb37eSEnrico Granata const char **end, 1287c482a192SEnrico Granata ValueObject* valobj 12881b654882SGreg Clayton ) 12891b654882SGreg Clayton { 1290c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 12911b654882SGreg Clayton bool success = true; 12921b654882SGreg Clayton const char *p; 1293e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12941b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 12951b654882SGreg Clayton { 1296c482a192SEnrico Granata if (realvalobj) 12974becb37eSEnrico Granata { 1298c482a192SEnrico Granata valobj = realvalobj; 1299c482a192SEnrico Granata realvalobj = NULL; 13004becb37eSEnrico Granata } 13011b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 13021b654882SGreg Clayton if (non_special_chars > 0) 13031b654882SGreg Clayton { 13041b654882SGreg Clayton if (success) 13051b654882SGreg Clayton s.Write (p, non_special_chars); 13061b654882SGreg Clayton p += non_special_chars; 13071b654882SGreg Clayton } 13081b654882SGreg Clayton 13091b654882SGreg Clayton if (*p == '\0') 13101b654882SGreg Clayton { 13111b654882SGreg Clayton break; 13121b654882SGreg Clayton } 13131b654882SGreg Clayton else if (*p == '{') 13141b654882SGreg Clayton { 13151b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 13161b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 13171b654882SGreg Clayton // a format that only prints out the function or symbol name if there 13181b654882SGreg Clayton // is one in the symbol context you can use: 13191b654882SGreg Clayton // "{function =${function.name}}" 13201b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 13211b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 13221b654882SGreg Clayton // will then be evaluated and only be output if there is a function 13231b654882SGreg Clayton // or symbol with a valid name. 13241b654882SGreg Clayton StreamString sub_strm; 13251b654882SGreg Clayton 13261b654882SGreg Clayton ++p; // Skip the '{' 13271b654882SGreg Clayton 1328c482a192SEnrico Granata if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 13291b654882SGreg Clayton { 13301b654882SGreg Clayton // The stream had all it needed 13311b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 13321b654882SGreg Clayton } 13331b654882SGreg Clayton if (*p != '}') 13341b654882SGreg Clayton { 13351b654882SGreg Clayton success = false; 13361b654882SGreg Clayton break; 13371b654882SGreg Clayton } 13381b654882SGreg Clayton } 13391b654882SGreg Clayton else if (*p == '}') 13401b654882SGreg Clayton { 13411b654882SGreg Clayton // End of a enclosing scope 13421b654882SGreg Clayton break; 13431b654882SGreg Clayton } 13441b654882SGreg Clayton else if (*p == '$') 13451b654882SGreg Clayton { 13461b654882SGreg Clayton // We have a prompt variable to print 13471b654882SGreg Clayton ++p; 13481b654882SGreg Clayton if (*p == '{') 13491b654882SGreg Clayton { 13501b654882SGreg Clayton ++p; 13511b654882SGreg Clayton const char *var_name_begin = p; 13521b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 13531b654882SGreg Clayton 13541b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 13551b654882SGreg Clayton { 13561b654882SGreg Clayton // if we have already failed to parse, skip this variable 13571b654882SGreg Clayton if (success) 13581b654882SGreg Clayton { 13591b654882SGreg Clayton const char *cstr = NULL; 13601b654882SGreg Clayton Address format_addr; 13611b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 13621b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 13631b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 13641b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 13651b654882SGreg Clayton FileSpec format_file_spec; 1366e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 13671b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 13689fc1944eSEnrico Granata bool do_deref_pointer = false; 136986cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 137086cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 13711b654882SGreg Clayton 13721b654882SGreg Clayton // Each variable must set success to true below... 13731b654882SGreg Clayton bool var_success = false; 13741b654882SGreg Clayton switch (var_name_begin[0]) 13751b654882SGreg Clayton { 13764becb37eSEnrico Granata case '*': 13776f3533fbSEnrico Granata case 'v': 13786f3533fbSEnrico Granata case 's': 13794becb37eSEnrico Granata { 1380c482a192SEnrico Granata if (!valobj) 138134132754SGreg Clayton break; 13826f3533fbSEnrico Granata 1383c3e320a7SEnrico Granata if (log) 1384d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1385c3e320a7SEnrico Granata 13866f3533fbSEnrico Granata // check for *var and *svar 13876f3533fbSEnrico Granata if (*var_name_begin == '*') 13886f3533fbSEnrico Granata { 13899fc1944eSEnrico Granata do_deref_pointer = true; 13909fc1944eSEnrico Granata var_name_begin++; 13919fc1944eSEnrico Granata } 1392c3e320a7SEnrico Granata 1393c3e320a7SEnrico Granata if (log) 1394d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1395c3e320a7SEnrico Granata 13966f3533fbSEnrico Granata if (*var_name_begin == 's') 13974becb37eSEnrico Granata { 1398c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 139986cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 140086cc9829SEnrico Granata if (!valobj) 140186cc9829SEnrico Granata break; 14026f3533fbSEnrico Granata var_name_begin++; 14036f3533fbSEnrico Granata } 14046f3533fbSEnrico Granata 1405c3e320a7SEnrico Granata if (log) 1406d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1407c3e320a7SEnrico Granata 14086f3533fbSEnrico Granata // should be a 'v' by now 14096f3533fbSEnrico Granata if (*var_name_begin != 'v') 14106f3533fbSEnrico Granata break; 14116f3533fbSEnrico Granata 1412c3e320a7SEnrico Granata if (log) 1413d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1414c3e320a7SEnrico Granata 1415fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 141686cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1417fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 14188c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 141986cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 142034132754SGreg Clayton ValueObject* target = NULL; 14214d122c40SGreg Clayton Format custom_format = eFormatInvalid; 142234132754SGreg Clayton const char* var_name_final = NULL; 14239fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 142434132754SGreg Clayton const char* close_bracket_position = NULL; 142534132754SGreg Clayton int64_t index_lower = -1; 142634132754SGreg Clayton int64_t index_higher = -1; 14279fc1944eSEnrico Granata bool is_array_range = false; 1428fc7a7f3bSEnrico Granata const char* first_unparsed; 142985933ed4SEnrico Granata bool was_plain_var = false; 143085933ed4SEnrico Granata bool was_var_format = false; 1431a777dc2aSEnrico Granata bool was_var_indexed = false; 1432fc7a7f3bSEnrico Granata 1433c482a192SEnrico Granata if (!valobj) break; 1434c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 14359fc1944eSEnrico Granata if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) 14360a3958e0SEnrico Granata { 143785933ed4SEnrico Granata was_plain_var = true; 1438c482a192SEnrico Granata target = valobj; 143986cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 14400a3958e0SEnrico Granata } 14419fc1944eSEnrico Granata else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) 14429fc1944eSEnrico Granata { 144385933ed4SEnrico Granata was_var_format = true; 14449fc1944eSEnrico Granata // this is a variable with some custom format applied to it 14459fc1944eSEnrico Granata const char* percent_position; 1446c482a192SEnrico Granata target = valobj; 144786cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 14489fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 14499fc1944eSEnrico Granata var_name_end, 14509fc1944eSEnrico Granata &var_name_final, 14519fc1944eSEnrico Granata &percent_position, 14529fc1944eSEnrico Granata &custom_format, 14539fc1944eSEnrico Granata &val_obj_display); 14540a3958e0SEnrico Granata } 14559fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 14569fc1944eSEnrico Granata else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) 14579fc1944eSEnrico Granata { 1458a777dc2aSEnrico Granata if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0) 1459a777dc2aSEnrico Granata was_var_indexed = true; 14609fc1944eSEnrico Granata const char* percent_position; 14619fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 14629fc1944eSEnrico Granata var_name_end, 14639fc1944eSEnrico Granata &var_name_final, 14649fc1944eSEnrico Granata &percent_position, 14659fc1944eSEnrico Granata &custom_format, 14669fc1944eSEnrico Granata &val_obj_display); 14679fc1944eSEnrico Granata 14689fc1944eSEnrico Granata const char* open_bracket_position; 14699fc1944eSEnrico Granata const char* separator_position; 14709fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 14719fc1944eSEnrico Granata var_name_end, 14729fc1944eSEnrico Granata var_name_final, 14739fc1944eSEnrico Granata &open_bracket_position, 14749fc1944eSEnrico Granata &separator_position, 14759fc1944eSEnrico Granata &close_bracket_position, 14769fc1944eSEnrico Granata &var_name_final_if_array_range, 14779fc1944eSEnrico Granata &index_lower, 14789fc1944eSEnrico Granata &index_higher); 14799fc1944eSEnrico Granata 14809fc1944eSEnrico Granata Error error; 14819fc1944eSEnrico Granata 1482599171adSEnrico Granata std::string expr_path(var_name_final-var_name_begin-1,0); 1483599171adSEnrico Granata memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1484fc7a7f3bSEnrico Granata 1485e992a089SEnrico Granata if (log) 1486599171adSEnrico Granata log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1487fc7a7f3bSEnrico Granata 1488599171adSEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1489fc7a7f3bSEnrico Granata &first_unparsed, 1490fc7a7f3bSEnrico Granata &reason_to_stop, 1491fc7a7f3bSEnrico Granata &final_value_type, 1492fc7a7f3bSEnrico Granata options, 1493fc7a7f3bSEnrico Granata &what_next).get(); 1494fc7a7f3bSEnrico Granata 1495fc7a7f3bSEnrico Granata if (!target) 14969fc1944eSEnrico Granata { 1497e992a089SEnrico Granata if (log) 1498d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1499e992a089SEnrico Granata " final_value_type %d", 1500fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1501fc7a7f3bSEnrico Granata break; 15020a3958e0SEnrico Granata } 1503a7187d00SEnrico Granata else 1504fc7a7f3bSEnrico Granata { 1505e992a089SEnrico Granata if (log) 1506d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1507e992a089SEnrico Granata " final_value_type %d", 1508fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1509a7187d00SEnrico Granata } 15100a3958e0SEnrico Granata } 15110a3958e0SEnrico Granata else 15120a3958e0SEnrico Granata break; 15139fc1944eSEnrico Granata 151486cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 151586cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1516fc7a7f3bSEnrico Granata 151786cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1518fc7a7f3bSEnrico Granata 1519a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 15200a3958e0SEnrico Granata { 15219fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 15229fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 15239fc1944eSEnrico Granata // to get to the target ValueObject 15249fc1944eSEnrico Granata Error error; 15259fc1944eSEnrico Granata target = target->Dereference(error).get(); 1526dc940730SEnrico Granata if (error.Fail()) 1527dc940730SEnrico Granata { 1528dc940730SEnrico Granata if (log) 1529d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1530dc940730SEnrico Granata break; 1531dc940730SEnrico Granata } 15329fc1944eSEnrico Granata do_deref_pointer = false; 15330a3958e0SEnrico Granata } 15340a3958e0SEnrico Granata 1535a777dc2aSEnrico Granata // <rdar://problem/11338654> 1536a777dc2aSEnrico Granata // we do not want to use the summary for a bitfield of type T:n 1537a777dc2aSEnrico Granata // if we were originally dealing with just a T - that would get 1538a777dc2aSEnrico Granata // us into an endless recursion 1539a777dc2aSEnrico Granata if (target->IsBitfield() && was_var_indexed) 1540a777dc2aSEnrico Granata { 1541a777dc2aSEnrico Granata // TODO: check for a (T:n)-specific summary - we should still obey that 1542a777dc2aSEnrico Granata StreamString bitfield_name; 1543a777dc2aSEnrico Granata bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1544a777dc2aSEnrico Granata lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1545a777dc2aSEnrico Granata if (!DataVisualization::GetSummaryForType(type_sp)) 1546a777dc2aSEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1547a777dc2aSEnrico Granata } 1548a777dc2aSEnrico Granata 154985933ed4SEnrico Granata // TODO use flags for these 15504ef877f5SGreg Clayton bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL); 1551f4efecd9SEnrico Granata bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); 155285933ed4SEnrico Granata bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType()); 1553f4efecd9SEnrico Granata 155486cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1555f4efecd9SEnrico Granata { 155685933ed4SEnrico Granata StreamString str_temp; 1557e992a089SEnrico Granata if (log) 1558d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1559d64d0bc0SEnrico Granata 15605088c486SGreg Clayton if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1561d64d0bc0SEnrico Granata { 1562f4efecd9SEnrico Granata // try to use the special cases 156385933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 156485933ed4SEnrico Granata val_obj_display, 156585933ed4SEnrico Granata custom_format); 1566e992a089SEnrico Granata if (log) 1567d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1568d64d0bc0SEnrico Granata 1569d64d0bc0SEnrico Granata // should not happen 15705088c486SGreg Clayton if (var_success) 157185933ed4SEnrico Granata s << str_temp.GetData(); 1572d64d0bc0SEnrico Granata var_success = true; 1573d64d0bc0SEnrico Granata break; 1574d64d0bc0SEnrico Granata } 1575d64d0bc0SEnrico Granata else 1576d64d0bc0SEnrico Granata { 157788da35f8SEnrico Granata if (was_plain_var) // if ${var} 1578d64d0bc0SEnrico Granata { 1579d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1580d64d0bc0SEnrico Granata } 158188da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 158288da35f8SEnrico Granata { 158323f59509SGreg Clayton target->DumpPrintableRepresentation (s, 158488da35f8SEnrico Granata val_obj_display, 158586cc9829SEnrico Granata custom_format, 158686cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 158788da35f8SEnrico Granata } 1588d64d0bc0SEnrico Granata var_success = true; 1589d64d0bc0SEnrico Granata break; 1590d64d0bc0SEnrico Granata } 1591d64d0bc0SEnrico Granata } 1592d64d0bc0SEnrico Granata 1593d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1594d64d0bc0SEnrico Granata // type @ location message 1595d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1596d64d0bc0SEnrico Granata { 1597d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1598d64d0bc0SEnrico Granata var_success = true; 159985933ed4SEnrico Granata break; 160085933ed4SEnrico Granata } 160185933ed4SEnrico Granata 1602d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 160386cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 160485933ed4SEnrico Granata { 160585933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 160685933ed4SEnrico Granata var_success = true; 1607f4efecd9SEnrico Granata break; 1608f4efecd9SEnrico Granata } 1609f4efecd9SEnrico Granata 16109fc1944eSEnrico Granata if (!is_array_range) 1611e992a089SEnrico Granata { 1612e992a089SEnrico Granata if (log) 1613d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 16149fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1615e992a089SEnrico Granata } 16169fc1944eSEnrico Granata else 16179fc1944eSEnrico Granata { 1618e992a089SEnrico Granata if (log) 1619d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 16209fc1944eSEnrico Granata if (!is_array && !is_pointer) 16219fc1944eSEnrico Granata break; 1622e992a089SEnrico Granata if (log) 1623d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] handle as array"); 1624fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1625fc7a7f3bSEnrico Granata StreamString special_directions_writer; 16260a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 16270a3958e0SEnrico Granata { 1628fc7a7f3bSEnrico Granata ConstString additional_data; 1629fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1630fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1631fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1632fc7a7f3bSEnrico Granata additional_data.GetCString()); 1633fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 16340a3958e0SEnrico Granata } 16350a3958e0SEnrico Granata 16360a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 16370a3958e0SEnrico Granata s.PutChar('['); 16380a3958e0SEnrico Granata var_success = true; 16390a3958e0SEnrico Granata 16409fc1944eSEnrico Granata if (index_higher < 0) 1641c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 16420a3958e0SEnrico Granata 1643cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 164422c55d18SEnrico Granata 16450a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 16460a3958e0SEnrico Granata { 1647fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 16489fc1944eSEnrico Granata index_lower, 1649c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1650fc7a7f3bSEnrico Granata false).get(); 16510a3958e0SEnrico Granata 1652fc7a7f3bSEnrico Granata if (!item) 1653fc7a7f3bSEnrico Granata { 1654e992a089SEnrico Granata if (log) 1655d01b2953SDaniel Malea log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1656fc7a7f3bSEnrico Granata } 1657fc7a7f3bSEnrico Granata else 1658fc7a7f3bSEnrico Granata { 1659e992a089SEnrico Granata if (log) 1660d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1661fc7a7f3bSEnrico Granata } 1662fc7a7f3bSEnrico Granata 16630a3958e0SEnrico Granata if (!special_directions) 16649fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 16650a3958e0SEnrico Granata else 16660a3958e0SEnrico Granata var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); 16670a3958e0SEnrico Granata 166822c55d18SEnrico Granata if (--max_num_children == 0) 166922c55d18SEnrico Granata { 167022c55d18SEnrico Granata s.PutCString(", ..."); 167122c55d18SEnrico Granata break; 167222c55d18SEnrico Granata } 167322c55d18SEnrico Granata 16740a3958e0SEnrico Granata if (index_lower < index_higher) 16750a3958e0SEnrico Granata s.PutChar(','); 16760a3958e0SEnrico Granata } 16770a3958e0SEnrico Granata s.PutChar(']'); 16784becb37eSEnrico Granata } 16794becb37eSEnrico Granata } 168034132754SGreg Clayton break; 16811b654882SGreg Clayton case 'a': 16821b654882SGreg Clayton if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 16831b654882SGreg Clayton { 16841b654882SGreg Clayton if (addr && addr->IsValid()) 16851b654882SGreg Clayton { 16861b654882SGreg Clayton var_success = true; 16871b654882SGreg Clayton format_addr = *addr; 16881b654882SGreg Clayton } 16891b654882SGreg Clayton } 16905a31471eSGreg Clayton else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0) 16915a31471eSGreg Clayton { 16925a31471eSGreg Clayton var_success = true; 16935a31471eSGreg Clayton var_name_begin += strlen("ansi."); // Skip the "ansi." 16945a31471eSGreg Clayton if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0) 16955a31471eSGreg Clayton { 16965a31471eSGreg Clayton var_name_begin += strlen("fg."); // Skip the "fg." 16975a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 16985a31471eSGreg Clayton { 16995a31471eSGreg Clayton s.Printf ("%s%s%s", 17005a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17015a31471eSGreg Clayton lldb_utility::ansi::k_fg_black, 17025a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17035a31471eSGreg Clayton } 17045a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 17055a31471eSGreg Clayton { 17065a31471eSGreg Clayton s.Printf ("%s%s%s", 17075a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17085a31471eSGreg Clayton lldb_utility::ansi::k_fg_red, 17095a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17105a31471eSGreg Clayton } 17115a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 17125a31471eSGreg Clayton { 17135a31471eSGreg Clayton s.Printf ("%s%s%s", 17145a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17155a31471eSGreg Clayton lldb_utility::ansi::k_fg_green, 17165a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17175a31471eSGreg Clayton } 17185a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 17195a31471eSGreg Clayton { 17205a31471eSGreg Clayton s.Printf ("%s%s%s", 17215a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17225a31471eSGreg Clayton lldb_utility::ansi::k_fg_yellow, 17235a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17245a31471eSGreg Clayton } 17255a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 17265a31471eSGreg Clayton { 17275a31471eSGreg Clayton s.Printf ("%s%s%s", 17285a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17295a31471eSGreg Clayton lldb_utility::ansi::k_fg_blue, 17305a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17315a31471eSGreg Clayton } 17325a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 17335a31471eSGreg Clayton { 17345a31471eSGreg Clayton s.Printf ("%s%s%s", 17355a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17365a31471eSGreg Clayton lldb_utility::ansi::k_fg_purple, 17375a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17385a31471eSGreg Clayton } 17395a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 17405a31471eSGreg Clayton { 17415a31471eSGreg Clayton s.Printf ("%s%s%s", 17425a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17435a31471eSGreg Clayton lldb_utility::ansi::k_fg_cyan, 17445a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17455a31471eSGreg Clayton } 17465a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 17475a31471eSGreg Clayton { 17485a31471eSGreg Clayton s.Printf ("%s%s%s", 17495a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17505a31471eSGreg Clayton lldb_utility::ansi::k_fg_white, 17515a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17525a31471eSGreg Clayton } 17535a31471eSGreg Clayton else 17545a31471eSGreg Clayton { 17555a31471eSGreg Clayton var_success = false; 17565a31471eSGreg Clayton } 17575a31471eSGreg Clayton } 17585a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0) 17595a31471eSGreg Clayton { 17605a31471eSGreg Clayton var_name_begin += strlen("bg."); // Skip the "bg." 17615a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 17625a31471eSGreg Clayton { 17635a31471eSGreg Clayton s.Printf ("%s%s%s", 17645a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17655a31471eSGreg Clayton lldb_utility::ansi::k_bg_black, 17665a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17675a31471eSGreg Clayton } 17685a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 17695a31471eSGreg Clayton { 17705a31471eSGreg Clayton s.Printf ("%s%s%s", 17715a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17725a31471eSGreg Clayton lldb_utility::ansi::k_bg_red, 17735a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17745a31471eSGreg Clayton } 17755a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 17765a31471eSGreg Clayton { 17775a31471eSGreg Clayton s.Printf ("%s%s%s", 17785a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17795a31471eSGreg Clayton lldb_utility::ansi::k_bg_green, 17805a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17815a31471eSGreg Clayton } 17825a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 17835a31471eSGreg Clayton { 17845a31471eSGreg Clayton s.Printf ("%s%s%s", 17855a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17865a31471eSGreg Clayton lldb_utility::ansi::k_bg_yellow, 17875a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17885a31471eSGreg Clayton } 17895a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 17905a31471eSGreg Clayton { 17915a31471eSGreg Clayton s.Printf ("%s%s%s", 17925a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17935a31471eSGreg Clayton lldb_utility::ansi::k_bg_blue, 17945a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17955a31471eSGreg Clayton } 17965a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 17975a31471eSGreg Clayton { 17985a31471eSGreg Clayton s.Printf ("%s%s%s", 17995a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18005a31471eSGreg Clayton lldb_utility::ansi::k_bg_purple, 18015a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18025a31471eSGreg Clayton } 18035a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 18045a31471eSGreg Clayton { 18055a31471eSGreg Clayton s.Printf ("%s%s%s", 18065a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18075a31471eSGreg Clayton lldb_utility::ansi::k_bg_cyan, 18085a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18095a31471eSGreg Clayton } 18105a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 18115a31471eSGreg Clayton { 18125a31471eSGreg Clayton s.Printf ("%s%s%s", 18135a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18145a31471eSGreg Clayton lldb_utility::ansi::k_bg_white, 18155a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18165a31471eSGreg Clayton } 18175a31471eSGreg Clayton else 18185a31471eSGreg Clayton { 18195a31471eSGreg Clayton var_success = false; 18205a31471eSGreg Clayton } 18215a31471eSGreg Clayton } 18225a31471eSGreg Clayton else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0) 18235a31471eSGreg Clayton { 18245a31471eSGreg Clayton s.Printf ("%s%s%s", 18255a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18265a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_normal, 18275a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18285a31471eSGreg Clayton } 18295a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0) 18305a31471eSGreg Clayton { 18315a31471eSGreg Clayton s.Printf ("%s%s%s", 18325a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18335a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_bold, 18345a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18355a31471eSGreg Clayton } 18365a31471eSGreg Clayton else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0) 18375a31471eSGreg Clayton { 18385a31471eSGreg Clayton s.Printf ("%s%s%s", 18395a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18405a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_faint, 18415a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18425a31471eSGreg Clayton } 18435a31471eSGreg Clayton else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0) 18445a31471eSGreg Clayton { 18455a31471eSGreg Clayton s.Printf ("%s%s%s", 18465a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18475a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_italic, 18485a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18495a31471eSGreg Clayton } 18505a31471eSGreg Clayton else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0) 18515a31471eSGreg Clayton { 18525a31471eSGreg Clayton s.Printf ("%s%s%s", 18535a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18545a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_underline, 18555a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18565a31471eSGreg Clayton } 18575a31471eSGreg Clayton else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0) 18585a31471eSGreg Clayton { 18595a31471eSGreg Clayton s.Printf ("%s%s%s", 18605a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18615a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_slow_blink, 18625a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18635a31471eSGreg Clayton } 18645a31471eSGreg Clayton else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0) 18655a31471eSGreg Clayton { 18665a31471eSGreg Clayton s.Printf ("%s%s%s", 18675a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18685a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_fast_blink, 18695a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18705a31471eSGreg Clayton } 18715a31471eSGreg Clayton else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0) 18725a31471eSGreg Clayton { 18735a31471eSGreg Clayton s.Printf ("%s%s%s", 18745a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18755a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_negative, 18765a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18775a31471eSGreg Clayton } 18785a31471eSGreg Clayton else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0) 18795a31471eSGreg Clayton { 18805a31471eSGreg Clayton s.Printf ("%s%s%s", 18815a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18825a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_conceal, 18835a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18845a31471eSGreg Clayton 18855a31471eSGreg Clayton } 18865a31471eSGreg Clayton else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0) 18875a31471eSGreg Clayton { 18885a31471eSGreg Clayton s.Printf ("%s%s%s", 18895a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18905a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_crossed_out, 18915a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18925a31471eSGreg Clayton } 18935a31471eSGreg Clayton else 18945a31471eSGreg Clayton { 18955a31471eSGreg Clayton var_success = false; 18965a31471eSGreg Clayton } 18975a31471eSGreg Clayton } 18981b654882SGreg Clayton break; 18991b654882SGreg Clayton 19001b654882SGreg Clayton case 'p': 19011b654882SGreg Clayton if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 19021b654882SGreg Clayton { 1903c14ee32dSGreg Clayton if (exe_ctx) 1904c14ee32dSGreg Clayton { 1905c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 1906c14ee32dSGreg Clayton if (process) 19071b654882SGreg Clayton { 19081b654882SGreg Clayton var_name_begin += ::strlen ("process."); 19091b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 19101b654882SGreg Clayton { 1911d01b2953SDaniel Malea s.Printf("%" PRIu64, process->GetID()); 19121b654882SGreg Clayton var_success = true; 19131b654882SGreg Clayton } 19141b654882SGreg Clayton else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 19151b654882SGreg Clayton (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 19161b654882SGreg Clayton (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 19171b654882SGreg Clayton { 1918c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1919aa149cbdSGreg Clayton if (exe_module) 19201b654882SGreg Clayton { 19211b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 19221b654882SGreg Clayton { 1923aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 19241b654882SGreg Clayton var_success = format_file_spec; 19251b654882SGreg Clayton } 19261b654882SGreg Clayton else 19271b654882SGreg Clayton { 1928aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 19291b654882SGreg Clayton var_success = format_file_spec; 19301b654882SGreg Clayton } 19311b654882SGreg Clayton } 19321b654882SGreg Clayton } 19331b654882SGreg Clayton } 19341b654882SGreg Clayton } 1935c14ee32dSGreg Clayton } 19361b654882SGreg Clayton break; 19371b654882SGreg Clayton 19381b654882SGreg Clayton case 't': 19391b654882SGreg Clayton if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 19401b654882SGreg Clayton { 1941c14ee32dSGreg Clayton if (exe_ctx) 1942c14ee32dSGreg Clayton { 1943c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 1944c14ee32dSGreg Clayton if (thread) 19451b654882SGreg Clayton { 19461b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 19471b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 19481b654882SGreg Clayton { 1949d01b2953SDaniel Malea s.Printf("0x%4.4" PRIx64, thread->GetID()); 19501b654882SGreg Clayton var_success = true; 19511b654882SGreg Clayton } 19521b654882SGreg Clayton else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 19531b654882SGreg Clayton { 1954c14ee32dSGreg Clayton s.Printf("%u", thread->GetIndexID()); 19551b654882SGreg Clayton var_success = true; 19561b654882SGreg Clayton } 19571b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 19581b654882SGreg Clayton { 1959c14ee32dSGreg Clayton cstr = thread->GetName(); 19601b654882SGreg Clayton var_success = cstr && cstr[0]; 19611b654882SGreg Clayton if (var_success) 19621b654882SGreg Clayton s.PutCString(cstr); 19631b654882SGreg Clayton } 19641b654882SGreg Clayton else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 19651b654882SGreg Clayton { 1966c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 19671b654882SGreg Clayton var_success = cstr && cstr[0]; 19681b654882SGreg Clayton if (var_success) 19691b654882SGreg Clayton s.PutCString(cstr); 19701b654882SGreg Clayton } 19711b654882SGreg Clayton else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 19721b654882SGreg Clayton { 1973c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 19745d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 19751b654882SGreg Clayton { 1976b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 19771b654882SGreg Clayton if (cstr && cstr[0]) 19781b654882SGreg Clayton { 19791b654882SGreg Clayton s.PutCString(cstr); 19801b654882SGreg Clayton var_success = true; 19811b654882SGreg Clayton } 19821b654882SGreg Clayton } 19831b654882SGreg Clayton } 198473ca05a2SJim Ingham else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0) 198573ca05a2SJim Ingham { 198673ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 19875d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 198873ca05a2SJim Ingham { 198973ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 199073ca05a2SJim Ingham if (return_valobj_sp) 199173ca05a2SJim Ingham { 1992ef651600SJim Ingham ValueObject::DumpValueObjectOptions dump_options; 1993ef651600SJim Ingham ValueObject::DumpValueObject (s, return_valobj_sp.get(), dump_options); 199473ca05a2SJim Ingham var_success = true; 199573ca05a2SJim Ingham } 199673ca05a2SJim Ingham } 199773ca05a2SJim Ingham } 199873ca05a2SJim Ingham } 19991b654882SGreg Clayton } 20001b654882SGreg Clayton } 20011b654882SGreg Clayton else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 20021b654882SGreg Clayton { 200367cc0636SGreg Clayton // TODO: hookup properties 200467cc0636SGreg Clayton // if (!target_properties_sp) 200567cc0636SGreg Clayton // { 200667cc0636SGreg Clayton // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 200767cc0636SGreg Clayton // if (target) 200867cc0636SGreg Clayton // target_properties_sp = target->GetProperties(); 200967cc0636SGreg Clayton // } 201067cc0636SGreg Clayton // 201167cc0636SGreg Clayton // if (target_properties_sp) 201267cc0636SGreg Clayton // { 201367cc0636SGreg Clayton // var_name_begin += ::strlen ("target."); 201467cc0636SGreg Clayton // const char *end_property = strchr(var_name_begin, '}'); 201567cc0636SGreg Clayton // if (end_property) 201667cc0636SGreg Clayton // { 201767cc0636SGreg Clayton // ConstString property_name(var_name_begin, end_property - var_name_begin); 201867cc0636SGreg Clayton // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 201967cc0636SGreg Clayton // if (!property_value.empty()) 202067cc0636SGreg Clayton // { 202167cc0636SGreg Clayton // s.PutCString (property_value.c_str()); 202267cc0636SGreg Clayton // var_success = true; 202367cc0636SGreg Clayton // } 202467cc0636SGreg Clayton // } 202567cc0636SGreg Clayton // } 20260603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 20270603aa9dSGreg Clayton if (target) 20281b654882SGreg Clayton { 20291b654882SGreg Clayton var_name_begin += ::strlen ("target."); 20301b654882SGreg Clayton if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 20311b654882SGreg Clayton { 20321b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 20331b654882SGreg Clayton if (arch.IsValid()) 20341b654882SGreg Clayton { 203564195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 20361b654882SGreg Clayton var_success = true; 20371b654882SGreg Clayton } 20381b654882SGreg Clayton } 20391b654882SGreg Clayton } 20401b654882SGreg Clayton } 20411b654882SGreg Clayton break; 20421b654882SGreg Clayton 20431b654882SGreg Clayton 20441b654882SGreg Clayton case 'm': 20451b654882SGreg Clayton if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 20461b654882SGreg Clayton { 20470603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 20481b654882SGreg Clayton { 20490603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 20501b654882SGreg Clayton var_name_begin += ::strlen ("module."); 20511b654882SGreg Clayton 20521b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 20531b654882SGreg Clayton { 20541b654882SGreg Clayton if (module->GetFileSpec()) 20551b654882SGreg Clayton { 20561b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20571b654882SGreg Clayton 20581b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 20591b654882SGreg Clayton { 20601b654882SGreg Clayton format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 20611b654882SGreg Clayton var_success = format_file_spec; 20621b654882SGreg Clayton } 20631b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 20641b654882SGreg Clayton { 20651b654882SGreg Clayton format_file_spec = module->GetFileSpec(); 20661b654882SGreg Clayton var_success = format_file_spec; 20671b654882SGreg Clayton } 20681b654882SGreg Clayton } 20691b654882SGreg Clayton } 20701b654882SGreg Clayton } 20711b654882SGreg Clayton } 20721b654882SGreg Clayton break; 20731b654882SGreg Clayton 20741b654882SGreg Clayton 20751b654882SGreg Clayton case 'f': 20761b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 20771b654882SGreg Clayton { 20781b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 20791b654882SGreg Clayton { 20801b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20811b654882SGreg Clayton 20821b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 20831b654882SGreg Clayton { 20841b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 20851b654882SGreg Clayton var_success = format_file_spec; 20861b654882SGreg Clayton } 20871b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 20881b654882SGreg Clayton { 20891b654882SGreg Clayton format_file_spec = *sc->comp_unit; 20901b654882SGreg Clayton var_success = format_file_spec; 20911b654882SGreg Clayton } 20921b654882SGreg Clayton } 20931b654882SGreg Clayton } 20941b654882SGreg Clayton else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 20951b654882SGreg Clayton { 2096c14ee32dSGreg Clayton if (exe_ctx) 2097c14ee32dSGreg Clayton { 2098c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2099c14ee32dSGreg Clayton if (frame) 21001b654882SGreg Clayton { 21011b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 21021b654882SGreg Clayton if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 21031b654882SGreg Clayton { 2104c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 21051b654882SGreg Clayton var_success = true; 21061b654882SGreg Clayton } 21071b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 21081b654882SGreg Clayton { 21091b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21101b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 21111b654882SGreg Clayton var_success = true; 21121b654882SGreg Clayton } 21131b654882SGreg Clayton else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 21141b654882SGreg Clayton { 21151b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21161b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 21171b654882SGreg Clayton var_success = true; 21181b654882SGreg Clayton } 21191b654882SGreg Clayton else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 21201b654882SGreg Clayton { 21211b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21221b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 21231b654882SGreg Clayton var_success = true; 21241b654882SGreg Clayton } 21251b654882SGreg Clayton else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 21261b654882SGreg Clayton { 21271b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21281b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 21291b654882SGreg Clayton var_success = true; 21301b654882SGreg Clayton } 21311b654882SGreg Clayton else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 21321b654882SGreg Clayton { 2133c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 21341b654882SGreg Clayton if (reg_ctx) 21351b654882SGreg Clayton { 21361b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 21371b654882SGreg Clayton if (var_name_begin < var_name_end) 21381b654882SGreg Clayton { 21391b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 21401b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 21411b654882SGreg Clayton if (reg_info) 21421b654882SGreg Clayton var_success = true; 21431b654882SGreg Clayton } 21441b654882SGreg Clayton } 21451b654882SGreg Clayton } 21461b654882SGreg Clayton } 21471b654882SGreg Clayton } 2148c14ee32dSGreg Clayton } 21491b654882SGreg Clayton else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 21501b654882SGreg Clayton { 21511b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 21521b654882SGreg Clayton { 21531b654882SGreg Clayton var_name_begin += ::strlen ("function."); 21541b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 21551b654882SGreg Clayton { 21561b654882SGreg Clayton if (sc->function) 2157d01b2953SDaniel Malea s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 21581b654882SGreg Clayton else 21591b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 21601b654882SGreg Clayton 21611b654882SGreg Clayton var_success = true; 21621b654882SGreg Clayton } 21631b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 21641b654882SGreg Clayton { 21651b654882SGreg Clayton if (sc->function) 21661b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21671b654882SGreg Clayton else if (sc->symbol) 21681b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 21691b654882SGreg Clayton if (cstr) 21701b654882SGreg Clayton { 21711b654882SGreg Clayton s.PutCString(cstr); 21720d9c9934SGreg Clayton 21730d9c9934SGreg Clayton if (sc->block) 21740d9c9934SGreg Clayton { 21750d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 21760d9c9934SGreg Clayton if (inline_block) 21770d9c9934SGreg Clayton { 21780d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 21790d9c9934SGreg Clayton if (inline_info) 21800d9c9934SGreg Clayton { 21810d9c9934SGreg Clayton s.PutCString(" [inlined] "); 21820d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 21830d9c9934SGreg Clayton } 21840d9c9934SGreg Clayton } 21850d9c9934SGreg Clayton } 21861b654882SGreg Clayton var_success = true; 21871b654882SGreg Clayton } 21881b654882SGreg Clayton } 21896d3dbf51SGreg Clayton else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0) 21906d3dbf51SGreg Clayton { 21916d3dbf51SGreg Clayton // Print the function name with arguments in it 21926d3dbf51SGreg Clayton 21936d3dbf51SGreg Clayton if (sc->function) 21946d3dbf51SGreg Clayton { 21956d3dbf51SGreg Clayton var_success = true; 21966d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 21976d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21986d3dbf51SGreg Clayton if (cstr) 21996d3dbf51SGreg Clayton { 22006d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 22016d3dbf51SGreg Clayton VariableListSP variable_list_sp; 22026d3dbf51SGreg Clayton bool get_function_vars = true; 22036d3dbf51SGreg Clayton if (sc->block) 22046d3dbf51SGreg Clayton { 22056d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 22066d3dbf51SGreg Clayton 22076d3dbf51SGreg Clayton if (inline_block) 22086d3dbf51SGreg Clayton { 22096d3dbf51SGreg Clayton get_function_vars = false; 22106d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 22116d3dbf51SGreg Clayton if (inline_info) 22126d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 22136d3dbf51SGreg Clayton } 22146d3dbf51SGreg Clayton } 22156d3dbf51SGreg Clayton 22166d3dbf51SGreg Clayton if (get_function_vars) 22176d3dbf51SGreg Clayton { 22186d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 22196d3dbf51SGreg Clayton } 22206d3dbf51SGreg Clayton 22216d3dbf51SGreg Clayton if (inline_info) 22226d3dbf51SGreg Clayton { 22236d3dbf51SGreg Clayton s.PutCString (cstr); 22246d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 22256d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 22266d3dbf51SGreg Clayton } 22276d3dbf51SGreg Clayton 22286d3dbf51SGreg Clayton VariableList args; 22296d3dbf51SGreg Clayton if (variable_list_sp) 22306d3dbf51SGreg Clayton { 22316d3dbf51SGreg Clayton const size_t num_variables = variable_list_sp->GetSize(); 22326d3dbf51SGreg Clayton for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) 22336d3dbf51SGreg Clayton { 22346d3dbf51SGreg Clayton VariableSP var_sp (variable_list_sp->GetVariableAtIndex(var_idx)); 22356d3dbf51SGreg Clayton if (var_sp->GetScope() == eValueTypeVariableArgument) 22366d3dbf51SGreg Clayton args.AddVariable (var_sp); 22376d3dbf51SGreg Clayton } 22386d3dbf51SGreg Clayton 22396d3dbf51SGreg Clayton } 22406d3dbf51SGreg Clayton if (args.GetSize() > 0) 22416d3dbf51SGreg Clayton { 22426d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 22436d3dbf51SGreg Clayton const char *close_paren = NULL; 22446d3dbf51SGreg Clayton if (open_paren) 2245*855958caSGreg Clayton { 2246*855958caSGreg Clayton if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0) 2247*855958caSGreg Clayton { 2248*855958caSGreg Clayton open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2249*855958caSGreg Clayton if (open_paren) 22506d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 2251*855958caSGreg Clayton } 2252*855958caSGreg Clayton else 2253*855958caSGreg Clayton close_paren = strchr (open_paren, ')'); 2254*855958caSGreg Clayton } 22556d3dbf51SGreg Clayton 22566d3dbf51SGreg Clayton if (open_paren) 22576d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 22586d3dbf51SGreg Clayton else 22596d3dbf51SGreg Clayton { 22606d3dbf51SGreg Clayton s.PutCString (cstr); 22616d3dbf51SGreg Clayton s.PutChar ('('); 22626d3dbf51SGreg Clayton } 22635b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 22646d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 22656d3dbf51SGreg Clayton { 22666d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 22676d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 22686d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 22696d3dbf51SGreg Clayton const char *var_value = var_value_sp->GetValueAsCString(); 22706d3dbf51SGreg Clayton if (arg_idx > 0) 22716d3dbf51SGreg Clayton s.PutCString (", "); 22723b188b17SGreg Clayton if (var_value_sp->GetError().Success()) 22736d3dbf51SGreg Clayton s.Printf ("%s=%s", var_name, var_value); 22743b188b17SGreg Clayton else 22753b188b17SGreg Clayton s.Printf ("%s=<unavailable>", var_name); 22766d3dbf51SGreg Clayton } 22776d3dbf51SGreg Clayton 22786d3dbf51SGreg Clayton if (close_paren) 22796d3dbf51SGreg Clayton s.PutCString (close_paren); 22806d3dbf51SGreg Clayton else 22816d3dbf51SGreg Clayton s.PutChar(')'); 22826d3dbf51SGreg Clayton 22836d3dbf51SGreg Clayton } 22846d3dbf51SGreg Clayton else 22856d3dbf51SGreg Clayton { 22866d3dbf51SGreg Clayton s.PutCString(cstr); 22876d3dbf51SGreg Clayton } 22886d3dbf51SGreg Clayton } 22896d3dbf51SGreg Clayton } 22906d3dbf51SGreg Clayton else if (sc->symbol) 22916d3dbf51SGreg Clayton { 22926d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 22936d3dbf51SGreg Clayton if (cstr) 22946d3dbf51SGreg Clayton { 22956d3dbf51SGreg Clayton s.PutCString(cstr); 22966d3dbf51SGreg Clayton var_success = true; 22976d3dbf51SGreg Clayton } 22986d3dbf51SGreg Clayton } 22996d3dbf51SGreg Clayton } 23001b654882SGreg Clayton else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 23011b654882SGreg Clayton { 23021b654882SGreg Clayton var_success = addr != NULL; 23031b654882SGreg Clayton if (var_success) 23041b654882SGreg Clayton { 23051b654882SGreg Clayton format_addr = *addr; 23061b654882SGreg Clayton calculate_format_addr_function_offset = true; 23071b654882SGreg Clayton } 23081b654882SGreg Clayton } 23091b654882SGreg Clayton else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 23101b654882SGreg Clayton { 23111b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 23121b654882SGreg Clayton if (var_success) 23131b654882SGreg Clayton { 23141b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23151b654882SGreg Clayton calculate_format_addr_function_offset = true; 23161b654882SGreg Clayton } 23171b654882SGreg Clayton } 23181b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 23191b654882SGreg Clayton { 2320c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2321c14ee32dSGreg Clayton var_success = frame != NULL; 23221b654882SGreg Clayton if (var_success) 23231b654882SGreg Clayton { 2324c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23251b654882SGreg Clayton calculate_format_addr_function_offset = true; 23261b654882SGreg Clayton } 23271b654882SGreg Clayton } 23281b654882SGreg Clayton } 23291b654882SGreg Clayton } 23301b654882SGreg Clayton break; 23311b654882SGreg Clayton 23321b654882SGreg Clayton case 'l': 23331b654882SGreg Clayton if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 23341b654882SGreg Clayton { 23351b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 23361b654882SGreg Clayton { 23371b654882SGreg Clayton var_name_begin += ::strlen ("line."); 23381b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 23391b654882SGreg Clayton { 23401b654882SGreg Clayton var_name_begin += ::strlen ("file."); 23411b654882SGreg Clayton 23421b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 23431b654882SGreg Clayton { 23441b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 23451b654882SGreg Clayton var_success = format_file_spec; 23461b654882SGreg Clayton } 23471b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 23481b654882SGreg Clayton { 23491b654882SGreg Clayton format_file_spec = sc->line_entry.file; 23501b654882SGreg Clayton var_success = format_file_spec; 23511b654882SGreg Clayton } 23521b654882SGreg Clayton } 23531b654882SGreg Clayton else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 23541b654882SGreg Clayton { 23551b654882SGreg Clayton var_success = true; 23561b654882SGreg Clayton s.Printf("%u", sc->line_entry.line); 23571b654882SGreg Clayton } 23581b654882SGreg Clayton else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 23591b654882SGreg Clayton (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 23601b654882SGreg Clayton { 23611b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 23621b654882SGreg Clayton if (var_success) 23631b654882SGreg Clayton { 23641b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23651b654882SGreg Clayton if (var_name_begin[0] == 'e') 23661b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 23671b654882SGreg Clayton } 23681b654882SGreg Clayton } 23691b654882SGreg Clayton } 23701b654882SGreg Clayton } 23711b654882SGreg Clayton break; 23721b654882SGreg Clayton } 23731b654882SGreg Clayton 23741b654882SGreg Clayton if (var_success) 23751b654882SGreg Clayton { 23761b654882SGreg Clayton // If format addr is valid, then we need to print an address 23771b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 23781b654882SGreg Clayton { 2379c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 23801b654882SGreg Clayton // We have a register value to display... 23811b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 23821b654882SGreg Clayton { 2383c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23841b654882SGreg Clayton } 23851b654882SGreg Clayton else 23861b654882SGreg Clayton { 23871b654882SGreg Clayton if (reg_ctx == NULL) 2388c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 23891b654882SGreg Clayton 23901b654882SGreg Clayton if (reg_ctx) 23911b654882SGreg Clayton { 23921b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 23931b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 23941b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 23951b654882SGreg Clayton var_success = reg_info != NULL; 23961b654882SGreg Clayton } 23971b654882SGreg Clayton } 23981b654882SGreg Clayton } 23991b654882SGreg Clayton 24001b654882SGreg Clayton if (reg_info != NULL) 24011b654882SGreg Clayton { 24027349bd90SGreg Clayton RegisterValue reg_value; 24037349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 24047349bd90SGreg Clayton if (var_success) 24051b654882SGreg Clayton { 24069a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 24071b654882SGreg Clayton } 24081b654882SGreg Clayton } 24091b654882SGreg Clayton 24101b654882SGreg Clayton if (format_file_spec) 24111b654882SGreg Clayton { 24121b654882SGreg Clayton s << format_file_spec; 24131b654882SGreg Clayton } 24141b654882SGreg Clayton 24151b654882SGreg Clayton // If format addr is valid, then we need to print an address 24161b654882SGreg Clayton if (format_addr.IsValid()) 24171b654882SGreg Clayton { 24180603aa9dSGreg Clayton var_success = false; 24190603aa9dSGreg Clayton 24201b654882SGreg Clayton if (calculate_format_addr_function_offset) 24211b654882SGreg Clayton { 24221b654882SGreg Clayton Address func_addr; 24230603aa9dSGreg Clayton 24240603aa9dSGreg Clayton if (sc) 24250603aa9dSGreg Clayton { 24261b654882SGreg Clayton if (sc->function) 24270d9c9934SGreg Clayton { 24281b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 24290d9c9934SGreg Clayton if (sc->block) 24300d9c9934SGreg Clayton { 24310d9c9934SGreg Clayton // Check to make sure we aren't in an inline 24320d9c9934SGreg Clayton // function. If we are, use the inline block 24330d9c9934SGreg Clayton // range that contains "format_addr" since 24340d9c9934SGreg Clayton // blocks can be discontiguous. 24350d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 24360d9c9934SGreg Clayton AddressRange inline_range; 24370d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 24380d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 24390d9c9934SGreg Clayton } 24400d9c9934SGreg Clayton } 2441e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2442e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 24430603aa9dSGreg Clayton } 24441b654882SGreg Clayton 24450603aa9dSGreg Clayton if (func_addr.IsValid()) 24461b654882SGreg Clayton { 24471b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 24481b654882SGreg Clayton { 24491b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 24501b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 24511b654882SGreg Clayton if (addr_file_addr > func_file_addr) 2452d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 24531b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 2454d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 24550603aa9dSGreg Clayton var_success = true; 24561b654882SGreg Clayton } 24571b654882SGreg Clayton else 24580603aa9dSGreg Clayton { 24590603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24600603aa9dSGreg Clayton if (target) 24610603aa9dSGreg Clayton { 24620603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 24630603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 24640603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 2465d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 24660603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 2467d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 24680603aa9dSGreg Clayton var_success = true; 24690603aa9dSGreg Clayton } 24700603aa9dSGreg Clayton } 24711b654882SGreg Clayton } 24721b654882SGreg Clayton } 24731b654882SGreg Clayton else 24741b654882SGreg Clayton { 24750603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24761b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 24770603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 24780603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 24791b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 24801b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 24811b654882SGreg Clayton 24821b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 24830603aa9dSGreg Clayton { 2484514487e8SGreg Clayton int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 248535f1a0d5SGreg Clayton if (addr_width == 0) 248635f1a0d5SGreg Clayton addr_width = 16; 2487d01b2953SDaniel Malea s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 24880603aa9dSGreg Clayton var_success = true; 24890603aa9dSGreg Clayton } 24901b654882SGreg Clayton } 24911b654882SGreg Clayton } 24921b654882SGreg Clayton } 24931b654882SGreg Clayton 24941b654882SGreg Clayton if (var_success == false) 24951b654882SGreg Clayton success = false; 24961b654882SGreg Clayton } 24971b654882SGreg Clayton p = var_name_end; 24981b654882SGreg Clayton } 24991b654882SGreg Clayton else 25001b654882SGreg Clayton break; 25011b654882SGreg Clayton } 25021b654882SGreg Clayton else 25031b654882SGreg Clayton { 25041b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 25051b654882SGreg Clayton s.PutChar(*p); 25061b654882SGreg Clayton } 25071b654882SGreg Clayton } 25081b654882SGreg Clayton else if (*p == '\\') 25091b654882SGreg Clayton { 25101b654882SGreg Clayton ++p; // skip the slash 25111b654882SGreg Clayton switch (*p) 25121b654882SGreg Clayton { 25131b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 25141b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 25151b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 25161b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 25171b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 25181b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 25191b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 25201b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 25211b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 25221b654882SGreg Clayton case '0': 25231b654882SGreg Clayton // 1 to 3 octal chars 25241b654882SGreg Clayton { 25250603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 25260603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 25270603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 25280603aa9dSGreg Clayton 25290603aa9dSGreg Clayton int i; 25300603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 25310603aa9dSGreg Clayton oct_str[i] = p[i]; 25320603aa9dSGreg Clayton 25330603aa9dSGreg Clayton // We don't want to consume the last octal character since 25340603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 25350603aa9dSGreg Clayton // one less than i (even if i is zero) 25360603aa9dSGreg Clayton p += i - 1; 25370603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 25380603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 25391b654882SGreg Clayton { 2540c7bece56SGreg Clayton s.PutChar((char)octal_value); 25411b654882SGreg Clayton } 25421b654882SGreg Clayton } 25431b654882SGreg Clayton break; 25441b654882SGreg Clayton 25451b654882SGreg Clayton case 'x': 25461b654882SGreg Clayton // hex number in the format 25470603aa9dSGreg Clayton if (isxdigit(p[1])) 25481b654882SGreg Clayton { 25490603aa9dSGreg Clayton ++p; // Skip the 'x' 25501b654882SGreg Clayton 25510603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 25520603aa9dSGreg Clayton // NULL terminator 25531b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 25541b654882SGreg Clayton hex_str[0] = *p; 25550603aa9dSGreg Clayton if (isxdigit(p[1])) 25560603aa9dSGreg Clayton { 25570603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 25581b654882SGreg Clayton hex_str[1] = *p; 25590603aa9dSGreg Clayton } 25600603aa9dSGreg Clayton 25611b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 25620603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 2563c7bece56SGreg Clayton s.PutChar ((char)hex_value); 25641b654882SGreg Clayton } 25651b654882SGreg Clayton else 25661b654882SGreg Clayton { 25670603aa9dSGreg Clayton s.PutChar('x'); 25681b654882SGreg Clayton } 25691b654882SGreg Clayton break; 25701b654882SGreg Clayton 25711b654882SGreg Clayton default: 25720603aa9dSGreg Clayton // Just desensitize any other character by just printing what 25730603aa9dSGreg Clayton // came after the '\' 25740603aa9dSGreg Clayton s << *p; 25751b654882SGreg Clayton break; 25761b654882SGreg Clayton 25771b654882SGreg Clayton } 25781b654882SGreg Clayton 25791b654882SGreg Clayton } 25801b654882SGreg Clayton } 25811b654882SGreg Clayton if (end) 25821b654882SGreg Clayton *end = p; 25831b654882SGreg Clayton return success; 25841b654882SGreg Clayton } 25851b654882SGreg Clayton 2586228063cdSJim Ingham void 2587228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2588228063cdSJim Ingham { 25894f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 25904f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 25914f02b22dSJim Ingham // callback. 2592228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2593228063cdSJim Ingham } 2594228063cdSJim Ingham 2595228063cdSJim Ingham bool 2596228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2597228063cdSJim Ingham { 2598228063cdSJim Ingham Log::Callbacks log_callbacks; 2599228063cdSJim Ingham 2600228063cdSJim Ingham StreamSP log_stream_sp; 26019a028519SSean Callanan if (m_log_callback_stream_sp) 2602228063cdSJim Ingham { 2603228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2604228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2605228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2606228063cdSJim Ingham } 2607228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2608228063cdSJim Ingham { 2609228063cdSJim Ingham log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false)); 2610228063cdSJim Ingham } 2611228063cdSJim Ingham else 2612228063cdSJim Ingham { 2613228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2614c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 2615c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 2616c1b2ccfdSGreg Clayton if (!log_stream_sp) 2617228063cdSJim Ingham { 2618228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2619228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2620228063cdSJim Ingham } 2621228063cdSJim Ingham } 2622228063cdSJim Ingham assert (log_stream_sp.get()); 2623228063cdSJim Ingham 2624228063cdSJim Ingham if (log_options == 0) 2625228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2626228063cdSJim Ingham 2627228063cdSJim Ingham if (Log::GetLogChannelCallbacks (channel, log_callbacks)) 2628228063cdSJim Ingham { 2629228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2630228063cdSJim Ingham return true; 2631228063cdSJim Ingham } 2632228063cdSJim Ingham else 2633228063cdSJim Ingham { 2634228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2635228063cdSJim Ingham if (log_channel_sp) 2636228063cdSJim Ingham { 2637228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2638228063cdSJim Ingham { 2639228063cdSJim Ingham return true; 2640228063cdSJim Ingham } 2641228063cdSJim Ingham else 2642228063cdSJim Ingham { 2643228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2644228063cdSJim Ingham return false; 2645228063cdSJim Ingham } 2646228063cdSJim Ingham } 2647228063cdSJim Ingham else 2648228063cdSJim Ingham { 2649228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2650228063cdSJim Ingham return false; 2651228063cdSJim Ingham } 2652228063cdSJim Ingham } 2653228063cdSJim Ingham return false; 2654228063cdSJim Ingham } 2655228063cdSJim Ingham 26569585fbfcSGreg Clayton SourceManager & 26579585fbfcSGreg Clayton Debugger::GetSourceManager () 26589585fbfcSGreg Clayton { 26599585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 26609585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 26619585fbfcSGreg Clayton return *m_source_manager_ap; 26629585fbfcSGreg Clayton } 26639585fbfcSGreg Clayton 26649585fbfcSGreg Clayton 2665