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\ 10585d0c57bSGreg Clayton "{, name = '${thread.name}}"\ 10685d0c57bSGreg Clayton "{, queue = '${thread.queue}}"\ 10767cc0636SGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 10867cc0636SGreg Clayton "{\\nReturn value: ${thread.return-value}}"\ 10967cc0636SGreg Clayton "\\n" 11067cc0636SGreg Clayton 11167cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 11267cc0636SGreg Clayton MODULE_WITH_FUNC\ 11367cc0636SGreg Clayton FILE_AND_LINE\ 11467cc0636SGreg Clayton "\\n" 11567cc0636SGreg Clayton 11667cc0636SGreg Clayton 11767cc0636SGreg Clayton 118754a9369SGreg Clayton static PropertyDefinition 119754a9369SGreg Clayton g_properties[] = 12067cc0636SGreg Clayton { 12167cc0636SGreg Clayton { "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, 12267cc0636SGreg Clayton { "frame-format", OptionValue::eTypeString , true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." }, 12367cc0636SGreg Clayton { "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, 1244c05410fSGreg Clayton { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 12567cc0636SGreg Clayton { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 12667cc0636SGreg Clayton { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, 12767cc0636SGreg Clayton { "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." }, 12867cc0636SGreg Clayton { "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." }, 12967cc0636SGreg Clayton { "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." }, 13067cc0636SGreg Clayton { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, 13167cc0636SGreg Clayton { "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." }, 13267cc0636SGreg Clayton { "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." }, 133e8cd0c98SGreg Clayton 13467cc0636SGreg Clayton { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 13567cc0636SGreg Clayton }; 13667cc0636SGreg Clayton 13767cc0636SGreg Clayton enum 13867cc0636SGreg Clayton { 13967cc0636SGreg Clayton ePropertyAutoConfirm = 0, 14067cc0636SGreg Clayton ePropertyFrameFormat, 14167cc0636SGreg Clayton ePropertyNotiftVoid, 14267cc0636SGreg Clayton ePropertyPrompt, 14367cc0636SGreg Clayton ePropertyScriptLanguage, 14467cc0636SGreg Clayton ePropertyStopDisassemblyCount, 14567cc0636SGreg Clayton ePropertyStopDisassemblyDisplay, 14667cc0636SGreg Clayton ePropertyStopLineCountAfter, 14767cc0636SGreg Clayton ePropertyStopLineCountBefore, 14867cc0636SGreg Clayton ePropertyTerminalWidth, 14967cc0636SGreg Clayton ePropertyThreadFormat, 15067cc0636SGreg Clayton ePropertyUseExternalEditor 15167cc0636SGreg Clayton }; 15267cc0636SGreg Clayton 15367cc0636SGreg Clayton // 15467cc0636SGreg Clayton //const char * 15567cc0636SGreg Clayton //Debugger::GetFrameFormat() const 15667cc0636SGreg Clayton //{ 15767cc0636SGreg Clayton // return m_properties_sp->GetFrameFormat(); 15867cc0636SGreg Clayton //} 15967cc0636SGreg Clayton //const char * 16067cc0636SGreg Clayton //Debugger::GetThreadFormat() const 16167cc0636SGreg Clayton //{ 16267cc0636SGreg Clayton // return m_properties_sp->GetThreadFormat(); 16367cc0636SGreg Clayton //} 16467cc0636SGreg Clayton // 1654c05410fSGreg Clayton 1664c05410fSGreg Clayton 1674c05410fSGreg Clayton Error 1684c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 1694c05410fSGreg Clayton VarSetOperationType op, 1704c05410fSGreg Clayton const char *property_path, 1714c05410fSGreg Clayton const char *value) 1724c05410fSGreg Clayton { 1734c05410fSGreg Clayton Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 1744c05410fSGreg Clayton if (error.Success()) 1754c05410fSGreg Clayton { 1764c05410fSGreg Clayton if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 1774c05410fSGreg Clayton { 1784c05410fSGreg Clayton const char *new_prompt = GetPrompt(); 1794c05410fSGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 1804c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 1814c05410fSGreg Clayton } 1824c05410fSGreg Clayton } 1834c05410fSGreg Clayton return error; 1844c05410fSGreg Clayton } 1854c05410fSGreg Clayton 18667cc0636SGreg Clayton bool 18767cc0636SGreg Clayton Debugger::GetAutoConfirm () const 18867cc0636SGreg Clayton { 18967cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 190754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 19167cc0636SGreg Clayton } 19267cc0636SGreg Clayton 19367cc0636SGreg Clayton const char * 19467cc0636SGreg Clayton Debugger::GetFrameFormat() const 19567cc0636SGreg Clayton { 19667cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 197754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 19867cc0636SGreg Clayton } 19967cc0636SGreg Clayton 20067cc0636SGreg Clayton bool 20167cc0636SGreg Clayton Debugger::GetNotifyVoid () const 20267cc0636SGreg Clayton { 20367cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 204754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 20567cc0636SGreg Clayton } 20667cc0636SGreg Clayton 20767cc0636SGreg Clayton const char * 20867cc0636SGreg Clayton Debugger::GetPrompt() const 20967cc0636SGreg Clayton { 21067cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 211754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 21267cc0636SGreg Clayton } 21367cc0636SGreg Clayton 21467cc0636SGreg Clayton void 21567cc0636SGreg Clayton Debugger::SetPrompt(const char *p) 21667cc0636SGreg Clayton { 21767cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 21867cc0636SGreg Clayton m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 21967cc0636SGreg Clayton const char *new_prompt = GetPrompt(); 22067cc0636SGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));; 22167cc0636SGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 22267cc0636SGreg Clayton } 22367cc0636SGreg Clayton 22467cc0636SGreg Clayton const char * 22567cc0636SGreg Clayton Debugger::GetThreadFormat() const 22667cc0636SGreg Clayton { 22767cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 228754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 22967cc0636SGreg Clayton } 23067cc0636SGreg Clayton 23167cc0636SGreg Clayton lldb::ScriptLanguage 23267cc0636SGreg Clayton Debugger::GetScriptLanguage() const 23367cc0636SGreg Clayton { 23467cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 235754a9369SGreg Clayton return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 23667cc0636SGreg Clayton } 23767cc0636SGreg Clayton 23867cc0636SGreg Clayton bool 23967cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 24067cc0636SGreg Clayton { 24167cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 24267cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 24367cc0636SGreg Clayton } 24467cc0636SGreg Clayton 24567cc0636SGreg Clayton uint32_t 24667cc0636SGreg Clayton Debugger::GetTerminalWidth () const 24767cc0636SGreg Clayton { 24867cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 249754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 25067cc0636SGreg Clayton } 25167cc0636SGreg Clayton 25267cc0636SGreg Clayton bool 25367cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width) 25467cc0636SGreg Clayton { 25567cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 25667cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 25767cc0636SGreg Clayton } 25867cc0636SGreg Clayton 25967cc0636SGreg Clayton bool 26067cc0636SGreg Clayton Debugger::GetUseExternalEditor () const 26167cc0636SGreg Clayton { 26267cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 263754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 26467cc0636SGreg Clayton } 26567cc0636SGreg Clayton 26667cc0636SGreg Clayton bool 26767cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b) 26867cc0636SGreg Clayton { 26967cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 27067cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 27167cc0636SGreg Clayton } 27267cc0636SGreg Clayton 27367cc0636SGreg Clayton uint32_t 27467cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const 27567cc0636SGreg Clayton { 27667cc0636SGreg Clayton const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 277754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 27867cc0636SGreg Clayton } 27967cc0636SGreg Clayton 28067cc0636SGreg Clayton Debugger::StopDisassemblyType 28167cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const 28267cc0636SGreg Clayton { 28367cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 284754a9369SGreg Clayton return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 28567cc0636SGreg Clayton } 28667cc0636SGreg Clayton 28767cc0636SGreg Clayton uint32_t 28867cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const 28967cc0636SGreg Clayton { 29067cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 291754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 29267cc0636SGreg Clayton } 293e372b98dSGreg Clayton 2941b654882SGreg Clayton #pragma mark Debugger 2951b654882SGreg Clayton 29667cc0636SGreg Clayton //const DebuggerPropertiesSP & 29767cc0636SGreg Clayton //Debugger::GetSettings() const 29867cc0636SGreg Clayton //{ 29967cc0636SGreg Clayton // return m_properties_sp; 30067cc0636SGreg Clayton //} 30167cc0636SGreg Clayton // 30299d0faf2SGreg Clayton 3032f88aadfSCaroline Tice int 3042f88aadfSCaroline Tice Debugger::TestDebuggerRefCount () 3052f88aadfSCaroline Tice { 3062f88aadfSCaroline Tice return g_shared_debugger_refcount; 3072f88aadfSCaroline Tice } 3082f88aadfSCaroline Tice 30930fdc8d8SChris Lattner void 31030fdc8d8SChris Lattner Debugger::Initialize () 31130fdc8d8SChris Lattner { 312c15f55e2SGreg Clayton if (g_shared_debugger_refcount++ == 0) 313dbe54508SGreg Clayton lldb_private::Initialize(); 31499d0faf2SGreg Clayton } 31530fdc8d8SChris Lattner 31630fdc8d8SChris Lattner void 31730fdc8d8SChris Lattner Debugger::Terminate () 31830fdc8d8SChris Lattner { 3196611103cSGreg Clayton if (g_shared_debugger_refcount > 0) 3206611103cSGreg Clayton { 32130fdc8d8SChris Lattner g_shared_debugger_refcount--; 32230fdc8d8SChris Lattner if (g_shared_debugger_refcount == 0) 32330fdc8d8SChris Lattner { 324dbe54508SGreg Clayton lldb_private::WillTerminate(); 325dbe54508SGreg Clayton lldb_private::Terminate(); 3266760a517SCaroline Tice 32799d0faf2SGreg Clayton // Clear our master list of debugger objects 32899d0faf2SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 32999d0faf2SGreg Clayton GetDebuggerList().clear(); 33030fdc8d8SChris Lattner } 3316760a517SCaroline Tice } 3326760a517SCaroline Tice } 33330fdc8d8SChris Lattner 33420bd37f7SCaroline Tice void 33520bd37f7SCaroline Tice Debugger::SettingsInitialize () 33620bd37f7SCaroline Tice { 3376920b52bSGreg Clayton Target::SettingsInitialize (); 33820bd37f7SCaroline Tice } 33920bd37f7SCaroline Tice 34020bd37f7SCaroline Tice void 34120bd37f7SCaroline Tice Debugger::SettingsTerminate () 34220bd37f7SCaroline Tice { 3436920b52bSGreg Clayton Target::SettingsTerminate (); 34420bd37f7SCaroline Tice } 34520bd37f7SCaroline Tice 34621dfcd9dSEnrico Granata bool 347e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error) 34821dfcd9dSEnrico Granata { 34921dfcd9dSEnrico Granata lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec)); 350e743c782SEnrico Granata if (!dynlib_sp || dynlib_sp->IsValid() == false) 351e743c782SEnrico Granata { 352e743c782SEnrico Granata if (spec.Exists()) 353e743c782SEnrico Granata error.SetErrorString("this file does not represent a loadable dylib"); 354e743c782SEnrico Granata else 355e743c782SEnrico Granata error.SetErrorString("no such file"); 356e743c782SEnrico Granata return false; 357e743c782SEnrico Granata } 35821dfcd9dSEnrico Granata lldb::DebuggerSP debugger_sp(shared_from_this()); 35921dfcd9dSEnrico Granata lldb::SBDebugger debugger_sb(debugger_sp); 36021dfcd9dSEnrico Granata // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays 36121dfcd9dSEnrico Granata LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); 36221dfcd9dSEnrico Granata if (!init_func) 363e743c782SEnrico Granata { 364e743c782SEnrico Granata error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)"); 36521dfcd9dSEnrico Granata return false; 366e743c782SEnrico Granata } 36721dfcd9dSEnrico Granata if (init_func(debugger_sb)) 36821dfcd9dSEnrico Granata { 36921dfcd9dSEnrico Granata m_loaded_plugins.push_back(dynlib_sp); 37021dfcd9dSEnrico Granata return true; 37121dfcd9dSEnrico Granata } 372e743c782SEnrico Granata error.SetErrorString("dylib refused to be loaded"); 37321dfcd9dSEnrico Granata return false; 37421dfcd9dSEnrico Granata } 37521dfcd9dSEnrico Granata 37621dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 37721dfcd9dSEnrico Granata LoadPluginCallback 37821dfcd9dSEnrico Granata ( 37921dfcd9dSEnrico Granata void *baton, 38021dfcd9dSEnrico Granata FileSpec::FileType file_type, 38121dfcd9dSEnrico Granata const FileSpec &file_spec 38221dfcd9dSEnrico Granata ) 38321dfcd9dSEnrico Granata { 38421dfcd9dSEnrico Granata Error error; 38521dfcd9dSEnrico Granata 38621dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 38721dfcd9dSEnrico Granata 38821dfcd9dSEnrico Granata if (!baton) 38921dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 39021dfcd9dSEnrico Granata 39121dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 39221dfcd9dSEnrico Granata 39321dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 39421dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 39521dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 39621dfcd9dSEnrico Granata // file type information. 39721dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 39821dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 39921dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 40021dfcd9dSEnrico Granata { 40121dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 40221dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 40321dfcd9dSEnrico Granata 40421dfcd9dSEnrico Granata if (plugin_file_spec.GetFileNameExtension() != g_dylibext) 40521dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 40621dfcd9dSEnrico Granata 407e743c782SEnrico Granata Error plugin_load_error; 408e743c782SEnrico Granata debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 40921dfcd9dSEnrico Granata 41021dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 41121dfcd9dSEnrico Granata } 41221dfcd9dSEnrico Granata 41321dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 41421dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 41521dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 41621dfcd9dSEnrico Granata { 41721dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 41821dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 41921dfcd9dSEnrico Granata // might be enurating a file system that doesn't have correct file type 42021dfcd9dSEnrico Granata // information. 42121dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 42221dfcd9dSEnrico Granata } 42321dfcd9dSEnrico Granata 42421dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 42521dfcd9dSEnrico Granata } 42621dfcd9dSEnrico Granata 42721dfcd9dSEnrico Granata void 42821dfcd9dSEnrico Granata Debugger::InstanceInitialize () 42921dfcd9dSEnrico Granata { 43021dfcd9dSEnrico Granata FileSpec dir_spec; 43121dfcd9dSEnrico Granata const bool find_directories = true; 43221dfcd9dSEnrico Granata const bool find_files = true; 43321dfcd9dSEnrico Granata const bool find_other = true; 43421dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 43521dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 43621dfcd9dSEnrico Granata { 43721dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 43821dfcd9dSEnrico Granata { 43921dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 44021dfcd9dSEnrico Granata find_directories, 44121dfcd9dSEnrico Granata find_files, 44221dfcd9dSEnrico Granata find_other, 44321dfcd9dSEnrico Granata LoadPluginCallback, 44421dfcd9dSEnrico Granata this); 44521dfcd9dSEnrico Granata } 44621dfcd9dSEnrico Granata } 44721dfcd9dSEnrico Granata 44821dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 44921dfcd9dSEnrico Granata { 45021dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 45121dfcd9dSEnrico Granata { 45221dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 45321dfcd9dSEnrico Granata find_directories, 45421dfcd9dSEnrico Granata find_files, 45521dfcd9dSEnrico Granata find_other, 45621dfcd9dSEnrico Granata LoadPluginCallback, 45721dfcd9dSEnrico Granata this); 45821dfcd9dSEnrico Granata } 45921dfcd9dSEnrico Granata } 460e8cd0c98SGreg Clayton 461e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 46221dfcd9dSEnrico Granata } 46321dfcd9dSEnrico Granata 4646611103cSGreg Clayton DebuggerSP 465228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 4666611103cSGreg Clayton { 467228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 468c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 4696611103cSGreg Clayton { 4706611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 4716611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 4726611103cSGreg Clayton } 47321dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 4746611103cSGreg Clayton return debugger_sp; 4756611103cSGreg Clayton } 4766611103cSGreg Clayton 477e02657b1SCaroline Tice void 4784d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 479e02657b1SCaroline Tice { 480e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 481e02657b1SCaroline Tice return; 482e02657b1SCaroline Tice 4838314c525SJim Ingham debugger_sp->Clear(); 4848314c525SJim Ingham 485c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 486c15f55e2SGreg Clayton { 487e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 488e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 489e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 490e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 491e02657b1SCaroline Tice { 492e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 493e02657b1SCaroline Tice { 494e02657b1SCaroline Tice debugger_list.erase (pos); 495e02657b1SCaroline Tice return; 496e02657b1SCaroline Tice } 497e02657b1SCaroline Tice } 498e02657b1SCaroline Tice } 499c15f55e2SGreg Clayton } 500e02657b1SCaroline Tice 5014d122c40SGreg Clayton DebuggerSP 5023df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 5033df9a8dfSCaroline Tice { 5044d122c40SGreg Clayton DebuggerSP debugger_sp; 5056920b52bSGreg Clayton if (g_shared_debugger_refcount > 0) 5066920b52bSGreg Clayton { 5076920b52bSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5086920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5096920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5106920b52bSGreg Clayton 5116920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5126920b52bSGreg Clayton { 5136920b52bSGreg Clayton if ((*pos).get()->m_instance_name == instance_name) 5146920b52bSGreg Clayton { 5156920b52bSGreg Clayton debugger_sp = *pos; 5166920b52bSGreg Clayton break; 5176920b52bSGreg Clayton } 5186920b52bSGreg Clayton } 5196920b52bSGreg Clayton } 5203df9a8dfSCaroline Tice return debugger_sp; 5213df9a8dfSCaroline Tice } 5226611103cSGreg Clayton 5236611103cSGreg Clayton TargetSP 5246611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 5256611103cSGreg Clayton { 5264d122c40SGreg Clayton TargetSP target_sp; 527c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 528c15f55e2SGreg Clayton { 5296611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5306611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5316611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5326611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5336611103cSGreg Clayton { 5346611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 5356611103cSGreg Clayton if (target_sp) 5366611103cSGreg Clayton break; 5376611103cSGreg Clayton } 538c15f55e2SGreg Clayton } 5396611103cSGreg Clayton return target_sp; 5406611103cSGreg Clayton } 5416611103cSGreg Clayton 542e4e45924SGreg Clayton TargetSP 543e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 544e4e45924SGreg Clayton { 545e4e45924SGreg Clayton TargetSP target_sp; 546c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 547c15f55e2SGreg Clayton { 548e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 549e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 550e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 551e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 552e4e45924SGreg Clayton { 553e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 554e4e45924SGreg Clayton if (target_sp) 555e4e45924SGreg Clayton break; 556e4e45924SGreg Clayton } 557c15f55e2SGreg Clayton } 558e4e45924SGreg Clayton return target_sp; 559e4e45924SGreg Clayton } 560e4e45924SGreg Clayton 561228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 562ebc1bb27SCaroline Tice UserID (g_unique_id++), 56367cc0636SGreg Clayton Properties(OptionValuePropertiesSP(new OptionValueProperties())), 564d46c87a1SGreg Clayton m_input_comm("debugger.input"), 56530fdc8d8SChris Lattner m_input_file (), 56630fdc8d8SChris Lattner m_output_file (), 56730fdc8d8SChris Lattner m_error_file (), 568c5917d9aSJim Ingham m_terminal_state (), 5694bddaeb5SJim Ingham m_target_list (*this), 570ded470d3SGreg Clayton m_platform_list (), 57130fdc8d8SChris Lattner m_listener ("lldb.Debugger"), 5729585fbfcSGreg Clayton m_source_manager_ap(), 573e37d605eSJim Ingham m_source_file_cache(), 5746611103cSGreg Clayton m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 575d5a0a01bSCaroline Tice m_input_reader_stack (), 57667cc0636SGreg Clayton m_input_reader_data (), 57767cc0636SGreg Clayton m_instance_name() 57830fdc8d8SChris Lattner { 57967cc0636SGreg Clayton char instance_cstr[256]; 58067cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 58167cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 582228063cdSJim Ingham if (log_callback) 583228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 5846611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 585ded470d3SGreg Clayton // Always add our default platform to the platform list 586ded470d3SGreg Clayton PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 587ded470d3SGreg Clayton assert (default_platform_sp.get()); 588ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 58967cc0636SGreg Clayton 590754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 59167cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 59267cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 59367cc0636SGreg Clayton true, 59467cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 595754a9369SGreg Clayton if (m_command_interpreter_ap.get()) 596754a9369SGreg Clayton { 597754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 598754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 599754a9369SGreg Clayton true, 600754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 601754a9369SGreg Clayton } 60267cc0636SGreg Clayton OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 60367cc0636SGreg Clayton term_width->SetMinimumValue(10); 60467cc0636SGreg Clayton term_width->SetMaximumValue(1024); 60530fdc8d8SChris Lattner } 60630fdc8d8SChris Lattner 60730fdc8d8SChris Lattner Debugger::~Debugger () 60830fdc8d8SChris Lattner { 6098314c525SJim Ingham Clear(); 6108314c525SJim Ingham } 6118314c525SJim Ingham 6128314c525SJim Ingham void 6138314c525SJim Ingham Debugger::Clear() 6148314c525SJim Ingham { 6153d6086f6SCaroline Tice CleanUpInputReaders(); 6161ed54f50SGreg Clayton m_listener.Clear(); 6176611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 6186611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 6196611103cSGreg Clayton { 620ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 621ccbc08e6SGreg Clayton if (target_sp) 622ccbc08e6SGreg Clayton { 623ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 6246611103cSGreg Clayton if (process_sp) 6251fd07059SJim Ingham process_sp->Finalize(); 626ccbc08e6SGreg Clayton target_sp->Destroy(); 6276611103cSGreg Clayton } 62830fdc8d8SChris Lattner } 6294bddaeb5SJim Ingham BroadcasterManager::Clear (); 63030fdc8d8SChris Lattner 6310d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 6320d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 633c5917d9aSJim Ingham m_terminal_state.Clear(); 6340d69a3a4SGreg Clayton GetInputFile().Close (); 6350d69a3a4SGreg Clayton // Now that we have closed m_input_file, we can now tell our input communication 6360d69a3a4SGreg Clayton // class to close down. Its read thread should quickly exit after we close 6370d69a3a4SGreg Clayton // the input file handle above. 6380d69a3a4SGreg Clayton m_input_comm.Clear (); 6398314c525SJim Ingham } 64030fdc8d8SChris Lattner 64130fdc8d8SChris Lattner bool 642fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 643fc3f027dSGreg Clayton { 644fc3f027dSGreg Clayton return m_input_comm.GetCloseOnEOF(); 645fc3f027dSGreg Clayton } 646fc3f027dSGreg Clayton 647fc3f027dSGreg Clayton void 648fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 649fc3f027dSGreg Clayton { 650fc3f027dSGreg Clayton m_input_comm.SetCloseOnEOF(b); 651fc3f027dSGreg Clayton } 652fc3f027dSGreg Clayton 653fc3f027dSGreg Clayton bool 65430fdc8d8SChris Lattner Debugger::GetAsyncExecution () 65530fdc8d8SChris Lattner { 6566611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 65730fdc8d8SChris Lattner } 65830fdc8d8SChris Lattner 65930fdc8d8SChris Lattner void 66030fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 66130fdc8d8SChris Lattner { 6626611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 66330fdc8d8SChris Lattner } 66430fdc8d8SChris Lattner 66530fdc8d8SChris Lattner 66630fdc8d8SChris Lattner void 66730fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 66830fdc8d8SChris Lattner { 66951b1e2d2SGreg Clayton File &in_file = GetInputFile(); 67051b1e2d2SGreg Clayton in_file.SetStream (fh, tranfer_ownership); 67151b1e2d2SGreg Clayton if (in_file.IsValid() == false) 67251b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 67330fdc8d8SChris Lattner 67430fdc8d8SChris Lattner // Disconnect from any old connection if we had one 67530fdc8d8SChris Lattner m_input_comm.Disconnect (); 67632720b51SGreg Clayton // Pass false as the second argument to ConnectionFileDescriptor below because 67732720b51SGreg Clayton // our "in_file" above will already take ownership if requested and we don't 67832720b51SGreg Clayton // want to objects trying to own and close a file descriptor. 67932720b51SGreg Clayton m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false)); 68030fdc8d8SChris Lattner m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); 68130fdc8d8SChris Lattner 682c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 683c5917d9aSJim Ingham SaveInputTerminalState (); 684c5917d9aSJim Ingham 68530fdc8d8SChris Lattner Error error; 68630fdc8d8SChris Lattner if (m_input_comm.StartReadThread (&error) == false) 68730fdc8d8SChris Lattner { 68851b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 68951b1e2d2SGreg Clayton 69051b1e2d2SGreg Clayton err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); 69130fdc8d8SChris Lattner exit(1); 69230fdc8d8SChris Lattner } 69330fdc8d8SChris Lattner } 69430fdc8d8SChris Lattner 69530fdc8d8SChris Lattner void 69630fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 69730fdc8d8SChris Lattner { 69851b1e2d2SGreg Clayton File &out_file = GetOutputFile(); 69951b1e2d2SGreg Clayton out_file.SetStream (fh, tranfer_ownership); 70051b1e2d2SGreg Clayton if (out_file.IsValid() == false) 70151b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 7022f88aadfSCaroline Tice 703b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 704b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 705b588726eSEnrico Granata const bool can_create = false; 706b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 707b588726eSEnrico Granata if (script_interpreter) 708b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 70930fdc8d8SChris Lattner } 71030fdc8d8SChris Lattner 71130fdc8d8SChris Lattner void 71230fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 71330fdc8d8SChris Lattner { 71451b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 71551b1e2d2SGreg Clayton err_file.SetStream (fh, tranfer_ownership); 71651b1e2d2SGreg Clayton if (err_file.IsValid() == false) 71751b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 71830fdc8d8SChris Lattner } 71930fdc8d8SChris Lattner 720c5917d9aSJim Ingham void 721c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 722c5917d9aSJim Ingham { 723c5917d9aSJim Ingham File &in_file = GetInputFile(); 724c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 725c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 726c5917d9aSJim Ingham } 727c5917d9aSJim Ingham 728c5917d9aSJim Ingham void 729c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 730c5917d9aSJim Ingham { 731c5917d9aSJim Ingham m_terminal_state.Restore(); 732c5917d9aSJim Ingham } 733c5917d9aSJim Ingham 73430fdc8d8SChris Lattner ExecutionContext 7352976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 73630fdc8d8SChris Lattner { 73730fdc8d8SChris Lattner ExecutionContext exe_ctx; 738c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 739c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 74030fdc8d8SChris Lattner 74130fdc8d8SChris Lattner if (target_sp) 74230fdc8d8SChris Lattner { 743c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 744c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 745c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 74630fdc8d8SChris Lattner { 747c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 748c14ee32dSGreg Clayton if (thread_sp) 74930fdc8d8SChris Lattner { 750c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 751c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 752c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 753c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 75430fdc8d8SChris Lattner } 75530fdc8d8SChris Lattner } 75630fdc8d8SChris Lattner } 75730fdc8d8SChris Lattner return exe_ctx; 75830fdc8d8SChris Lattner 75930fdc8d8SChris Lattner } 76030fdc8d8SChris Lattner 761b44880caSCaroline Tice InputReaderSP 762b44880caSCaroline Tice Debugger::GetCurrentInputReader () 763b44880caSCaroline Tice { 764b44880caSCaroline Tice InputReaderSP reader_sp; 765b44880caSCaroline Tice 766d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 767b44880caSCaroline Tice { 768b44880caSCaroline Tice // Clear any finished readers from the stack 769b44880caSCaroline Tice while (CheckIfTopInputReaderIsDone()) ; 770b44880caSCaroline Tice 771d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 772d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 773b44880caSCaroline Tice } 774b44880caSCaroline Tice 775b44880caSCaroline Tice return reader_sp; 776b44880caSCaroline Tice } 777b44880caSCaroline Tice 77830fdc8d8SChris Lattner void 77930fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len) 78030fdc8d8SChris Lattner { 781efed6131SCaroline Tice if (bytes_len > 0) 78230fdc8d8SChris Lattner ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len); 783efed6131SCaroline Tice else 784efed6131SCaroline Tice ((Debugger *)baton)->DispatchInputEndOfFile (); 78530fdc8d8SChris Lattner } 78630fdc8d8SChris Lattner 78730fdc8d8SChris Lattner 78830fdc8d8SChris Lattner void 78930fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len) 79030fdc8d8SChris Lattner { 791efed6131SCaroline Tice if (bytes == NULL || bytes_len == 0) 792efed6131SCaroline Tice return; 79330fdc8d8SChris Lattner 79430fdc8d8SChris Lattner WriteToDefaultReader (bytes, bytes_len); 79530fdc8d8SChris Lattner } 79630fdc8d8SChris Lattner 79730fdc8d8SChris Lattner void 798efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 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 (eInputReaderInterrupt); 806efed6131SCaroline Tice 807b44880caSCaroline Tice // If notifying the reader of the interrupt finished the reader, we should pop it off the stack. 808efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 809efed6131SCaroline Tice } 810efed6131SCaroline Tice } 811efed6131SCaroline Tice 812efed6131SCaroline Tice void 813efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 814efed6131SCaroline Tice { 815efed6131SCaroline Tice m_input_reader_data.clear(); 816efed6131SCaroline Tice 817b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 818efed6131SCaroline Tice if (reader_sp) 819b44880caSCaroline Tice { 820efed6131SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 821efed6131SCaroline Tice 822b44880caSCaroline Tice // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack. 823efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 824efed6131SCaroline Tice } 825efed6131SCaroline Tice } 826efed6131SCaroline Tice 827efed6131SCaroline Tice void 8283d6086f6SCaroline Tice Debugger::CleanUpInputReaders () 8293d6086f6SCaroline Tice { 8303d6086f6SCaroline Tice m_input_reader_data.clear(); 8313d6086f6SCaroline Tice 832b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 833d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 8343d6086f6SCaroline Tice { 835b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 8363d6086f6SCaroline Tice if (reader_sp) 8373d6086f6SCaroline Tice { 8383d6086f6SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 8393d6086f6SCaroline Tice reader_sp->SetIsDone (true); 8403d6086f6SCaroline Tice } 8413d6086f6SCaroline Tice } 8423d6086f6SCaroline Tice } 8433d6086f6SCaroline Tice 8443d6086f6SCaroline Tice void 845969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification) 846969ed3d1SCaroline Tice { 847969ed3d1SCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader()); 848969ed3d1SCaroline Tice if (reader_sp) 849969ed3d1SCaroline Tice { 850969ed3d1SCaroline Tice reader_sp->Notify (notification); 851969ed3d1SCaroline Tice 852969ed3d1SCaroline Tice // Flush out any input readers that are done. 853969ed3d1SCaroline Tice while (CheckIfTopInputReaderIsDone ()) 854969ed3d1SCaroline Tice /* Do nothing. */; 855969ed3d1SCaroline Tice } 856969ed3d1SCaroline Tice } 857969ed3d1SCaroline Tice 8589088b068SCaroline Tice bool 8594d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp) 8609088b068SCaroline Tice { 8619088b068SCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader()); 8629088b068SCaroline Tice 863d61c10bcSCaroline Tice return (reader_sp.get() == top_reader_sp.get()); 8649088b068SCaroline Tice } 8659088b068SCaroline Tice 8669088b068SCaroline Tice 867969ed3d1SCaroline Tice void 86830fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) 86930fdc8d8SChris Lattner { 87030fdc8d8SChris Lattner if (bytes && bytes_len) 87130fdc8d8SChris Lattner m_input_reader_data.append (bytes, bytes_len); 87230fdc8d8SChris Lattner 87330fdc8d8SChris Lattner if (m_input_reader_data.empty()) 87430fdc8d8SChris Lattner return; 87530fdc8d8SChris Lattner 876d5a0a01bSCaroline Tice while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty()) 87730fdc8d8SChris Lattner { 87830fdc8d8SChris Lattner // Get the input reader from the top of the stack 879b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 88030fdc8d8SChris Lattner if (!reader_sp) 88130fdc8d8SChris Lattner break; 88230fdc8d8SChris Lattner 883471b31ceSGreg Clayton size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 88430fdc8d8SChris Lattner m_input_reader_data.size()); 88530fdc8d8SChris Lattner if (bytes_handled) 88630fdc8d8SChris Lattner { 88730fdc8d8SChris Lattner m_input_reader_data.erase (0, bytes_handled); 88830fdc8d8SChris Lattner } 88930fdc8d8SChris Lattner else 89030fdc8d8SChris Lattner { 89130fdc8d8SChris Lattner // No bytes were handled, we might not have reached our 89230fdc8d8SChris Lattner // granularity, just return and wait for more data 89330fdc8d8SChris Lattner break; 89430fdc8d8SChris Lattner } 89530fdc8d8SChris Lattner } 89630fdc8d8SChris Lattner 897b44880caSCaroline Tice // Flush out any input readers that are done. 89830fdc8d8SChris Lattner while (CheckIfTopInputReaderIsDone ()) 89930fdc8d8SChris Lattner /* Do nothing. */; 90030fdc8d8SChris Lattner 90130fdc8d8SChris Lattner } 90230fdc8d8SChris Lattner 90330fdc8d8SChris Lattner void 90430fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp) 90530fdc8d8SChris Lattner { 90630fdc8d8SChris Lattner if (!reader_sp) 90730fdc8d8SChris Lattner return; 908b44880caSCaroline Tice 90930fdc8d8SChris Lattner // Deactivate the old top reader 910b44880caSCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader ()); 911b44880caSCaroline Tice 91230fdc8d8SChris Lattner if (top_reader_sp) 91330fdc8d8SChris Lattner top_reader_sp->Notify (eInputReaderDeactivate); 914b44880caSCaroline Tice 915d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 91630fdc8d8SChris Lattner reader_sp->Notify (eInputReaderActivate); 91730fdc8d8SChris Lattner ActivateInputReader (reader_sp); 91830fdc8d8SChris Lattner } 91930fdc8d8SChris Lattner 92030fdc8d8SChris Lattner bool 9214d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp) 92230fdc8d8SChris Lattner { 92330fdc8d8SChris Lattner bool result = false; 92430fdc8d8SChris Lattner 92530fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 92630fdc8d8SChris Lattner // read on the stack referesh its prompt and if there is one... 927d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 92830fdc8d8SChris Lattner { 929b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 930d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 93130fdc8d8SChris Lattner 93230fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 93330fdc8d8SChris Lattner { 934d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 93530fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDeactivate); 93630fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDone); 93730fdc8d8SChris Lattner result = true; 93830fdc8d8SChris Lattner 939d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 94030fdc8d8SChris Lattner { 941d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 94230fdc8d8SChris Lattner if (reader_sp) 94330fdc8d8SChris Lattner { 94430fdc8d8SChris Lattner ActivateInputReader (reader_sp); 94530fdc8d8SChris Lattner reader_sp->Notify (eInputReaderReactivate); 94630fdc8d8SChris Lattner } 94730fdc8d8SChris Lattner } 94830fdc8d8SChris Lattner } 94930fdc8d8SChris Lattner } 95030fdc8d8SChris Lattner return result; 95130fdc8d8SChris Lattner } 95230fdc8d8SChris Lattner 95330fdc8d8SChris Lattner bool 95430fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone () 95530fdc8d8SChris Lattner { 95630fdc8d8SChris Lattner bool result = false; 957d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 95830fdc8d8SChris Lattner { 959b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 960d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 96130fdc8d8SChris Lattner 96230fdc8d8SChris Lattner if (reader_sp && reader_sp->IsDone()) 96330fdc8d8SChris Lattner { 96430fdc8d8SChris Lattner result = true; 96530fdc8d8SChris Lattner PopInputReader (reader_sp); 96630fdc8d8SChris Lattner } 96730fdc8d8SChris Lattner } 96830fdc8d8SChris Lattner return result; 96930fdc8d8SChris Lattner } 97030fdc8d8SChris Lattner 97130fdc8d8SChris Lattner void 97230fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 97330fdc8d8SChris Lattner { 97451b1e2d2SGreg Clayton int input_fd = m_input_file.GetFile().GetDescriptor(); 97530fdc8d8SChris Lattner 97651b1e2d2SGreg Clayton if (input_fd >= 0) 97730fdc8d8SChris Lattner { 97851b1e2d2SGreg Clayton Terminal tty(input_fd); 979a3406614SGreg Clayton 980a3406614SGreg Clayton tty.SetEcho(reader_sp->GetEcho()); 98130fdc8d8SChris Lattner 98230fdc8d8SChris Lattner switch (reader_sp->GetGranularity()) 98330fdc8d8SChris Lattner { 98430fdc8d8SChris Lattner case eInputReaderGranularityByte: 98530fdc8d8SChris Lattner case eInputReaderGranularityWord: 986a3406614SGreg Clayton tty.SetCanonical (false); 98730fdc8d8SChris Lattner break; 98830fdc8d8SChris Lattner 98930fdc8d8SChris Lattner case eInputReaderGranularityLine: 99030fdc8d8SChris Lattner case eInputReaderGranularityAll: 991a3406614SGreg Clayton tty.SetCanonical (true); 99230fdc8d8SChris Lattner break; 99330fdc8d8SChris Lattner 99430fdc8d8SChris Lattner default: 99530fdc8d8SChris Lattner break; 99630fdc8d8SChris Lattner } 99730fdc8d8SChris Lattner } 99830fdc8d8SChris Lattner } 9996611103cSGreg Clayton 10005b52f0c7SJim Ingham StreamSP 10015b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 10025b52f0c7SJim Ingham { 10035b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10045b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 10055b52f0c7SJim Ingham } 10065b52f0c7SJim Ingham 10075b52f0c7SJim Ingham StreamSP 10085b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 10095b52f0c7SJim Ingham { 10105b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10115b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 10125b52f0c7SJim Ingham } 10135b52f0c7SJim Ingham 1014c7bece56SGreg Clayton size_t 1015061858ceSEnrico Granata Debugger::GetNumDebuggers() 1016061858ceSEnrico Granata { 1017c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1018c15f55e2SGreg Clayton { 1019061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1020061858ceSEnrico Granata return GetDebuggerList().size(); 1021061858ceSEnrico Granata } 1022c15f55e2SGreg Clayton return 0; 1023c15f55e2SGreg Clayton } 1024061858ceSEnrico Granata 1025061858ceSEnrico Granata lldb::DebuggerSP 1026c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1027061858ceSEnrico Granata { 1028061858ceSEnrico Granata DebuggerSP debugger_sp; 1029061858ceSEnrico Granata 1030c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1031c15f55e2SGreg Clayton { 1032061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1033061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1034061858ceSEnrico Granata 1035061858ceSEnrico Granata if (index < debugger_list.size()) 1036061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1037c15f55e2SGreg Clayton } 1038061858ceSEnrico Granata 1039061858ceSEnrico Granata return debugger_sp; 1040061858ceSEnrico Granata } 1041061858ceSEnrico Granata 1042ebc1bb27SCaroline Tice DebuggerSP 1043ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1044ebc1bb27SCaroline Tice { 10454d122c40SGreg Clayton DebuggerSP debugger_sp; 1046ebc1bb27SCaroline Tice 1047c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1048c15f55e2SGreg Clayton { 1049ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 1050ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1051ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1052ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1053ebc1bb27SCaroline Tice { 1054ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 1055ebc1bb27SCaroline Tice { 1056ebc1bb27SCaroline Tice debugger_sp = *pos; 1057ebc1bb27SCaroline Tice break; 1058ebc1bb27SCaroline Tice } 1059ebc1bb27SCaroline Tice } 1060c15f55e2SGreg Clayton } 1061ebc1bb27SCaroline Tice return debugger_sp; 1062ebc1bb27SCaroline Tice } 10633df9a8dfSCaroline Tice 10641b654882SGreg Clayton static void 10651b654882SGreg Clayton TestPromptFormats (StackFrame *frame) 10661b654882SGreg Clayton { 10671b654882SGreg Clayton if (frame == NULL) 10681b654882SGreg Clayton return; 10691b654882SGreg Clayton 10701b654882SGreg Clayton StreamString s; 10711b654882SGreg Clayton const char *prompt_format = 10721b654882SGreg Clayton "{addr = '${addr}'\n}" 10731b654882SGreg Clayton "{process.id = '${process.id}'\n}" 10741b654882SGreg Clayton "{process.name = '${process.name}'\n}" 10751b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 10761b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 10771b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 10781b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 10791b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 10801b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 10811b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 10821b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 10831b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 10841b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 10851b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 10861b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 10871b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 10881b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 10891b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 10901b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 10911b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 10921b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 10931b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 10941b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 10951b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 10961b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 10971b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 10981b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 10991b654882SGreg Clayton "{function.id = '${function.id}'\n}" 11001b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1101ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 11021b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 11031b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 11041b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 11051b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 11061b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 11071b654882SGreg Clayton "{line.number = '${line.number}'\n}" 11081b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 11091b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 11101b654882SGreg Clayton ; 11111b654882SGreg Clayton 11121b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 11131b654882SGreg Clayton ExecutionContext exe_ctx; 11140603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 11151b654882SGreg Clayton const char *end = NULL; 11161b654882SGreg Clayton if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end)) 11171b654882SGreg Clayton { 11181b654882SGreg Clayton printf("%s\n", s.GetData()); 11191b654882SGreg Clayton } 11201b654882SGreg Clayton else 11211b654882SGreg Clayton { 11221b654882SGreg Clayton printf ("error: at '%s'\n", end); 11231b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 11241b654882SGreg Clayton } 11251b654882SGreg Clayton } 11261b654882SGreg Clayton 11279fc1944eSEnrico Granata static bool 11289fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin, 11299fc1944eSEnrico Granata const char* var_name_end, 11309fc1944eSEnrico Granata const char** var_name_final, 11319fc1944eSEnrico Granata const char** percent_position, 11324d122c40SGreg Clayton Format* custom_format, 11339fc1944eSEnrico Granata ValueObject::ValueObjectRepresentationStyle* val_obj_display) 11349fc1944eSEnrico Granata { 11355160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 11369fc1944eSEnrico Granata *percent_position = ::strchr(var_name_begin,'%'); 11379fc1944eSEnrico Granata if (!*percent_position || *percent_position > var_name_end) 1138e992a089SEnrico Granata { 1139e992a089SEnrico Granata if (log) 1140d228483dSEnrico Granata log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 11419fc1944eSEnrico Granata *var_name_final = var_name_end; 1142e992a089SEnrico Granata } 11439fc1944eSEnrico Granata else 11449fc1944eSEnrico Granata { 11459fc1944eSEnrico Granata *var_name_final = *percent_position; 114636aa5ae6SEnrico Granata std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1); 1147e992a089SEnrico Granata if (log) 114836aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str()); 114936aa5ae6SEnrico Granata if ( !FormatManager::GetFormatFromCString(format_name.c_str(), 11509fc1944eSEnrico Granata true, 11519fc1944eSEnrico Granata *custom_format) ) 11529fc1944eSEnrico Granata { 1153e992a089SEnrico Granata if (log) 115436aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] %s is an unknown format", format_name.c_str()); 115536aa5ae6SEnrico Granata 115636aa5ae6SEnrico Granata switch (format_name.front()) 115736aa5ae6SEnrico Granata { 115836aa5ae6SEnrico Granata case '@': // if this is an @ sign, print ObjC description 115986cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 116036aa5ae6SEnrico Granata break; 116136aa5ae6SEnrico Granata case 'V': // if this is a V, print the value using the default format 116286cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 116336aa5ae6SEnrico Granata break; 116436aa5ae6SEnrico Granata case 'L': // if this is an L, print the location of the value 116586cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 116636aa5ae6SEnrico Granata break; 116736aa5ae6SEnrico Granata case 'S': // if this is an S, print the summary after all 116886cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 116936aa5ae6SEnrico Granata break; 117036aa5ae6SEnrico Granata case '#': // if this is a '#', print the number of children 117186cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 117236aa5ae6SEnrico Granata break; 117336aa5ae6SEnrico Granata case 'T': // if this is a 'T', print the type 117486cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 117536aa5ae6SEnrico Granata break; 117636aa5ae6SEnrico Granata default: 117736aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 117836aa5ae6SEnrico Granata break; 117936aa5ae6SEnrico Granata } 11809fc1944eSEnrico Granata } 11819fc1944eSEnrico Granata // a good custom format tells us to print the value using it 11829fc1944eSEnrico Granata else 1183e992a089SEnrico Granata { 1184e992a089SEnrico Granata if (log) 1185d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] will display value for this VO"); 118686cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1187e992a089SEnrico Granata } 11889fc1944eSEnrico Granata } 1189e992a089SEnrico Granata if (log) 1190d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1191e992a089SEnrico Granata *custom_format, 1192e992a089SEnrico Granata *val_obj_display); 11939fc1944eSEnrico Granata return true; 11949fc1944eSEnrico Granata } 11959fc1944eSEnrico Granata 11969fc1944eSEnrico Granata static bool 11979fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 11989fc1944eSEnrico Granata const char* var_name_end, 11999fc1944eSEnrico Granata const char* var_name_final, 12009fc1944eSEnrico Granata const char** open_bracket_position, 12019fc1944eSEnrico Granata const char** separator_position, 12029fc1944eSEnrico Granata const char** close_bracket_position, 12039fc1944eSEnrico Granata const char** var_name_final_if_array_range, 12049fc1944eSEnrico Granata int64_t* index_lower, 12059fc1944eSEnrico Granata int64_t* index_higher) 12069fc1944eSEnrico Granata { 12075160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12089fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 12099fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 12109fc1944eSEnrico Granata { 12119fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 12129fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 12139fc1944eSEnrico Granata // as usual, we assume that [] will come before % 12149fc1944eSEnrico Granata //printf("trying to expand a []\n"); 12159fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 12169fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 12179fc1944eSEnrico Granata { 1218e992a089SEnrico Granata if (log) 1219d228483dSEnrico Granata log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 12209fc1944eSEnrico Granata *index_lower = 0; 12219fc1944eSEnrico Granata } 12229fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 12239fc1944eSEnrico Granata { 12249fc1944eSEnrico Granata char *end = NULL; 12259fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12269fc1944eSEnrico Granata *index_higher = *index_lower; 1227e992a089SEnrico Granata if (log) 1228d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 12299fc1944eSEnrico Granata } 12309fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 12319fc1944eSEnrico Granata { 12329fc1944eSEnrico Granata char *end = NULL; 12339fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12349fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 1235e992a089SEnrico Granata if (log) 1236d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 12379fc1944eSEnrico Granata } 12389fc1944eSEnrico Granata else 1239e992a089SEnrico Granata { 1240e992a089SEnrico Granata if (log) 1241d228483dSEnrico Granata log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 12429fc1944eSEnrico Granata return false; 1243e992a089SEnrico Granata } 12449fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 12459fc1944eSEnrico Granata { 1246e992a089SEnrico Granata if (log) 1247d228483dSEnrico Granata log->Printf("[ScanBracketedRange] swapping indices"); 1248c7bece56SGreg Clayton int64_t temp = *index_lower; 12499fc1944eSEnrico Granata *index_lower = *index_higher; 12509fc1944eSEnrico Granata *index_higher = temp; 12519fc1944eSEnrico Granata } 12529fc1944eSEnrico Granata } 1253e992a089SEnrico Granata else if (log) 1254d228483dSEnrico Granata log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 12559fc1944eSEnrico Granata return true; 12569fc1944eSEnrico Granata } 12579fc1944eSEnrico Granata 12589fc1944eSEnrico Granata static ValueObjectSP 1259c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 1260c7bece56SGreg Clayton size_t index, 12619fc1944eSEnrico Granata StackFrame* frame, 1262fc7a7f3bSEnrico Granata bool deref_pointer) 12639fc1944eSEnrico Granata { 12645160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1265fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1266599171adSEnrico Granata std::string ptr_deref_buffer(10,0); 1267599171adSEnrico Granata ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1268e992a089SEnrico Granata if (log) 1269599171adSEnrico Granata log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1270fc7a7f3bSEnrico Granata const char* first_unparsed; 1271fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1272fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1273fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 127486cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1275599171adSEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1276fc7a7f3bSEnrico Granata &first_unparsed, 1277fc7a7f3bSEnrico Granata &reason_to_stop, 1278fc7a7f3bSEnrico Granata &final_value_type, 1279fc7a7f3bSEnrico Granata options, 1280fc7a7f3bSEnrico Granata &what_next); 1281fc7a7f3bSEnrico Granata if (!item) 1282fc7a7f3bSEnrico Granata { 1283e992a089SEnrico Granata if (log) 1284d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1285e992a089SEnrico Granata " final_value_type %d", 1286fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1287fc7a7f3bSEnrico Granata } 12889fc1944eSEnrico Granata else 12899fc1944eSEnrico Granata { 1290e992a089SEnrico Granata if (log) 1291d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1292e992a089SEnrico Granata " final_value_type %d", 1293fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 12949fc1944eSEnrico Granata } 12959fc1944eSEnrico Granata return item; 12969fc1944eSEnrico Granata } 12979fc1944eSEnrico Granata 12981b654882SGreg Clayton bool 12991b654882SGreg Clayton Debugger::FormatPrompt 13001b654882SGreg Clayton ( 13011b654882SGreg Clayton const char *format, 13021b654882SGreg Clayton const SymbolContext *sc, 13031b654882SGreg Clayton const ExecutionContext *exe_ctx, 13041b654882SGreg Clayton const Address *addr, 13051b654882SGreg Clayton Stream &s, 13064becb37eSEnrico Granata const char **end, 1307c482a192SEnrico Granata ValueObject* valobj 13081b654882SGreg Clayton ) 13091b654882SGreg Clayton { 1310c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 13111b654882SGreg Clayton bool success = true; 13121b654882SGreg Clayton const char *p; 13135160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 13141b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 13151b654882SGreg Clayton { 1316c482a192SEnrico Granata if (realvalobj) 13174becb37eSEnrico Granata { 1318c482a192SEnrico Granata valobj = realvalobj; 1319c482a192SEnrico Granata realvalobj = NULL; 13204becb37eSEnrico Granata } 13211b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 13221b654882SGreg Clayton if (non_special_chars > 0) 13231b654882SGreg Clayton { 13241b654882SGreg Clayton if (success) 13251b654882SGreg Clayton s.Write (p, non_special_chars); 13261b654882SGreg Clayton p += non_special_chars; 13271b654882SGreg Clayton } 13281b654882SGreg Clayton 13291b654882SGreg Clayton if (*p == '\0') 13301b654882SGreg Clayton { 13311b654882SGreg Clayton break; 13321b654882SGreg Clayton } 13331b654882SGreg Clayton else if (*p == '{') 13341b654882SGreg Clayton { 13351b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 13361b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 13371b654882SGreg Clayton // a format that only prints out the function or symbol name if there 13381b654882SGreg Clayton // is one in the symbol context you can use: 13391b654882SGreg Clayton // "{function =${function.name}}" 13401b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 13411b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 13421b654882SGreg Clayton // will then be evaluated and only be output if there is a function 13431b654882SGreg Clayton // or symbol with a valid name. 13441b654882SGreg Clayton StreamString sub_strm; 13451b654882SGreg Clayton 13461b654882SGreg Clayton ++p; // Skip the '{' 13471b654882SGreg Clayton 1348c482a192SEnrico Granata if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 13491b654882SGreg Clayton { 13501b654882SGreg Clayton // The stream had all it needed 13511b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 13521b654882SGreg Clayton } 13531b654882SGreg Clayton if (*p != '}') 13541b654882SGreg Clayton { 13551b654882SGreg Clayton success = false; 13561b654882SGreg Clayton break; 13571b654882SGreg Clayton } 13581b654882SGreg Clayton } 13591b654882SGreg Clayton else if (*p == '}') 13601b654882SGreg Clayton { 13611b654882SGreg Clayton // End of a enclosing scope 13621b654882SGreg Clayton break; 13631b654882SGreg Clayton } 13641b654882SGreg Clayton else if (*p == '$') 13651b654882SGreg Clayton { 13661b654882SGreg Clayton // We have a prompt variable to print 13671b654882SGreg Clayton ++p; 13681b654882SGreg Clayton if (*p == '{') 13691b654882SGreg Clayton { 13701b654882SGreg Clayton ++p; 13711b654882SGreg Clayton const char *var_name_begin = p; 13721b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 13731b654882SGreg Clayton 13741b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 13751b654882SGreg Clayton { 13761b654882SGreg Clayton // if we have already failed to parse, skip this variable 13771b654882SGreg Clayton if (success) 13781b654882SGreg Clayton { 13791b654882SGreg Clayton const char *cstr = NULL; 13801b654882SGreg Clayton Address format_addr; 13811b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 13821b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 13831b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 13841b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 13851b654882SGreg Clayton FileSpec format_file_spec; 1386e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 13871b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 13889fc1944eSEnrico Granata bool do_deref_pointer = false; 138986cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 139086cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 13911b654882SGreg Clayton 13921b654882SGreg Clayton // Each variable must set success to true below... 13931b654882SGreg Clayton bool var_success = false; 13941b654882SGreg Clayton switch (var_name_begin[0]) 13951b654882SGreg Clayton { 13964becb37eSEnrico Granata case '*': 13976f3533fbSEnrico Granata case 'v': 13986f3533fbSEnrico Granata case 's': 13994becb37eSEnrico Granata { 1400c482a192SEnrico Granata if (!valobj) 140134132754SGreg Clayton break; 14026f3533fbSEnrico Granata 1403c3e320a7SEnrico Granata if (log) 1404d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1405c3e320a7SEnrico Granata 14066f3533fbSEnrico Granata // check for *var and *svar 14076f3533fbSEnrico Granata if (*var_name_begin == '*') 14086f3533fbSEnrico Granata { 14099fc1944eSEnrico Granata do_deref_pointer = true; 14109fc1944eSEnrico Granata var_name_begin++; 14119fc1944eSEnrico Granata } 1412c3e320a7SEnrico Granata 1413c3e320a7SEnrico Granata if (log) 1414d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1415c3e320a7SEnrico Granata 14166f3533fbSEnrico Granata if (*var_name_begin == 's') 14174becb37eSEnrico Granata { 1418c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 141986cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 142086cc9829SEnrico Granata if (!valobj) 142186cc9829SEnrico Granata break; 14226f3533fbSEnrico Granata var_name_begin++; 14236f3533fbSEnrico Granata } 14246f3533fbSEnrico Granata 1425c3e320a7SEnrico Granata if (log) 1426d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1427c3e320a7SEnrico Granata 14286f3533fbSEnrico Granata // should be a 'v' by now 14296f3533fbSEnrico Granata if (*var_name_begin != 'v') 14306f3533fbSEnrico Granata break; 14316f3533fbSEnrico Granata 1432c3e320a7SEnrico Granata if (log) 1433d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1434c3e320a7SEnrico Granata 1435fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 143686cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1437fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 14388c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 143986cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 144034132754SGreg Clayton ValueObject* target = NULL; 14414d122c40SGreg Clayton Format custom_format = eFormatInvalid; 144234132754SGreg Clayton const char* var_name_final = NULL; 14439fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 144434132754SGreg Clayton const char* close_bracket_position = NULL; 144534132754SGreg Clayton int64_t index_lower = -1; 144634132754SGreg Clayton int64_t index_higher = -1; 14479fc1944eSEnrico Granata bool is_array_range = false; 1448fc7a7f3bSEnrico Granata const char* first_unparsed; 144985933ed4SEnrico Granata bool was_plain_var = false; 145085933ed4SEnrico Granata bool was_var_format = false; 1451a777dc2aSEnrico Granata bool was_var_indexed = false; 1452fc7a7f3bSEnrico Granata 1453c482a192SEnrico Granata if (!valobj) break; 1454c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 14559fc1944eSEnrico Granata if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) 14560a3958e0SEnrico Granata { 145785933ed4SEnrico Granata was_plain_var = true; 1458c482a192SEnrico Granata target = valobj; 145986cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 14600a3958e0SEnrico Granata } 14619fc1944eSEnrico Granata else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) 14629fc1944eSEnrico Granata { 146385933ed4SEnrico Granata was_var_format = true; 14649fc1944eSEnrico Granata // this is a variable with some custom format applied to it 14659fc1944eSEnrico Granata const char* percent_position; 1466c482a192SEnrico Granata target = valobj; 146786cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 14689fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 14699fc1944eSEnrico Granata var_name_end, 14709fc1944eSEnrico Granata &var_name_final, 14719fc1944eSEnrico Granata &percent_position, 14729fc1944eSEnrico Granata &custom_format, 14739fc1944eSEnrico Granata &val_obj_display); 14740a3958e0SEnrico Granata } 14759fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 14769fc1944eSEnrico Granata else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) 14779fc1944eSEnrico Granata { 1478a777dc2aSEnrico Granata if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0) 1479a777dc2aSEnrico Granata was_var_indexed = true; 14809fc1944eSEnrico Granata const char* percent_position; 14819fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 14829fc1944eSEnrico Granata var_name_end, 14839fc1944eSEnrico Granata &var_name_final, 14849fc1944eSEnrico Granata &percent_position, 14859fc1944eSEnrico Granata &custom_format, 14869fc1944eSEnrico Granata &val_obj_display); 14879fc1944eSEnrico Granata 14889fc1944eSEnrico Granata const char* open_bracket_position; 14899fc1944eSEnrico Granata const char* separator_position; 14909fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 14919fc1944eSEnrico Granata var_name_end, 14929fc1944eSEnrico Granata var_name_final, 14939fc1944eSEnrico Granata &open_bracket_position, 14949fc1944eSEnrico Granata &separator_position, 14959fc1944eSEnrico Granata &close_bracket_position, 14969fc1944eSEnrico Granata &var_name_final_if_array_range, 14979fc1944eSEnrico Granata &index_lower, 14989fc1944eSEnrico Granata &index_higher); 14999fc1944eSEnrico Granata 15009fc1944eSEnrico Granata Error error; 15019fc1944eSEnrico Granata 1502599171adSEnrico Granata std::string expr_path(var_name_final-var_name_begin-1,0); 1503599171adSEnrico Granata memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1504fc7a7f3bSEnrico Granata 1505e992a089SEnrico Granata if (log) 1506599171adSEnrico Granata log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1507fc7a7f3bSEnrico Granata 1508599171adSEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1509fc7a7f3bSEnrico Granata &first_unparsed, 1510fc7a7f3bSEnrico Granata &reason_to_stop, 1511fc7a7f3bSEnrico Granata &final_value_type, 1512fc7a7f3bSEnrico Granata options, 1513fc7a7f3bSEnrico Granata &what_next).get(); 1514fc7a7f3bSEnrico Granata 1515fc7a7f3bSEnrico Granata if (!target) 15169fc1944eSEnrico Granata { 1517e992a089SEnrico Granata if (log) 1518d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1519e992a089SEnrico Granata " final_value_type %d", 1520fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1521fc7a7f3bSEnrico Granata break; 15220a3958e0SEnrico Granata } 1523a7187d00SEnrico Granata else 1524fc7a7f3bSEnrico Granata { 1525e992a089SEnrico Granata if (log) 1526d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1527e992a089SEnrico Granata " final_value_type %d", 1528fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1529a7187d00SEnrico Granata } 15300a3958e0SEnrico Granata } 15310a3958e0SEnrico Granata else 15320a3958e0SEnrico Granata break; 15339fc1944eSEnrico Granata 153486cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 153586cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1536fc7a7f3bSEnrico Granata 153786cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1538fc7a7f3bSEnrico Granata 1539a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 15400a3958e0SEnrico Granata { 15419fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 15429fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 15439fc1944eSEnrico Granata // to get to the target ValueObject 15449fc1944eSEnrico Granata Error error; 15459fc1944eSEnrico Granata target = target->Dereference(error).get(); 1546dc940730SEnrico Granata if (error.Fail()) 1547dc940730SEnrico Granata { 1548dc940730SEnrico Granata if (log) 1549d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1550dc940730SEnrico Granata break; 1551dc940730SEnrico Granata } 15529fc1944eSEnrico Granata do_deref_pointer = false; 15530a3958e0SEnrico Granata } 15540a3958e0SEnrico Granata 1555a777dc2aSEnrico Granata // <rdar://problem/11338654> 1556a777dc2aSEnrico Granata // we do not want to use the summary for a bitfield of type T:n 1557a777dc2aSEnrico Granata // if we were originally dealing with just a T - that would get 1558a777dc2aSEnrico Granata // us into an endless recursion 1559a777dc2aSEnrico Granata if (target->IsBitfield() && was_var_indexed) 1560a777dc2aSEnrico Granata { 1561a777dc2aSEnrico Granata // TODO: check for a (T:n)-specific summary - we should still obey that 1562a777dc2aSEnrico Granata StreamString bitfield_name; 1563a777dc2aSEnrico Granata bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1564a777dc2aSEnrico Granata lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1565a777dc2aSEnrico Granata if (!DataVisualization::GetSummaryForType(type_sp)) 1566a777dc2aSEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1567a777dc2aSEnrico Granata } 1568a777dc2aSEnrico Granata 156985933ed4SEnrico Granata // TODO use flags for these 15704ef877f5SGreg Clayton bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL); 1571f4efecd9SEnrico Granata bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); 157285933ed4SEnrico Granata bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType()); 1573f4efecd9SEnrico Granata 157486cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1575f4efecd9SEnrico Granata { 157685933ed4SEnrico Granata StreamString str_temp; 1577e992a089SEnrico Granata if (log) 1578d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1579d64d0bc0SEnrico Granata 15805088c486SGreg Clayton if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1581d64d0bc0SEnrico Granata { 1582f4efecd9SEnrico Granata // try to use the special cases 158385933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 158485933ed4SEnrico Granata val_obj_display, 158585933ed4SEnrico Granata custom_format); 1586e992a089SEnrico Granata if (log) 1587d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1588d64d0bc0SEnrico Granata 1589d64d0bc0SEnrico Granata // should not happen 15905088c486SGreg Clayton if (var_success) 159185933ed4SEnrico Granata s << str_temp.GetData(); 1592d64d0bc0SEnrico Granata var_success = true; 1593d64d0bc0SEnrico Granata break; 1594d64d0bc0SEnrico Granata } 1595d64d0bc0SEnrico Granata else 1596d64d0bc0SEnrico Granata { 159788da35f8SEnrico Granata if (was_plain_var) // if ${var} 1598d64d0bc0SEnrico Granata { 1599d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1600d64d0bc0SEnrico Granata } 160188da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 160288da35f8SEnrico Granata { 160323f59509SGreg Clayton target->DumpPrintableRepresentation (s, 160488da35f8SEnrico Granata val_obj_display, 160586cc9829SEnrico Granata custom_format, 160686cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 160788da35f8SEnrico Granata } 1608d64d0bc0SEnrico Granata var_success = true; 1609d64d0bc0SEnrico Granata break; 1610d64d0bc0SEnrico Granata } 1611d64d0bc0SEnrico Granata } 1612d64d0bc0SEnrico Granata 1613d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1614d64d0bc0SEnrico Granata // type @ location message 1615d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1616d64d0bc0SEnrico Granata { 1617d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1618d64d0bc0SEnrico Granata var_success = true; 161985933ed4SEnrico Granata break; 162085933ed4SEnrico Granata } 162185933ed4SEnrico Granata 1622d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 162386cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 162485933ed4SEnrico Granata { 162585933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 162685933ed4SEnrico Granata var_success = true; 1627f4efecd9SEnrico Granata break; 1628f4efecd9SEnrico Granata } 1629f4efecd9SEnrico Granata 16309fc1944eSEnrico Granata if (!is_array_range) 1631e992a089SEnrico Granata { 1632e992a089SEnrico Granata if (log) 1633d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 16349fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1635e992a089SEnrico Granata } 16369fc1944eSEnrico Granata else 16379fc1944eSEnrico Granata { 1638e992a089SEnrico Granata if (log) 1639d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 16409fc1944eSEnrico Granata if (!is_array && !is_pointer) 16419fc1944eSEnrico Granata break; 1642e992a089SEnrico Granata if (log) 1643d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] handle as array"); 1644fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1645fc7a7f3bSEnrico Granata StreamString special_directions_writer; 16460a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 16470a3958e0SEnrico Granata { 1648fc7a7f3bSEnrico Granata ConstString additional_data; 1649fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1650fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1651fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1652fc7a7f3bSEnrico Granata additional_data.GetCString()); 1653fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 16540a3958e0SEnrico Granata } 16550a3958e0SEnrico Granata 16560a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 16570a3958e0SEnrico Granata s.PutChar('['); 16580a3958e0SEnrico Granata var_success = true; 16590a3958e0SEnrico Granata 16609fc1944eSEnrico Granata if (index_higher < 0) 1661c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 16620a3958e0SEnrico Granata 1663cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 166422c55d18SEnrico Granata 16650a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 16660a3958e0SEnrico Granata { 1667fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 16689fc1944eSEnrico Granata index_lower, 1669c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1670fc7a7f3bSEnrico Granata false).get(); 16710a3958e0SEnrico Granata 1672fc7a7f3bSEnrico Granata if (!item) 1673fc7a7f3bSEnrico Granata { 1674e992a089SEnrico Granata if (log) 1675d01b2953SDaniel Malea log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1676fc7a7f3bSEnrico Granata } 1677fc7a7f3bSEnrico Granata else 1678fc7a7f3bSEnrico Granata { 1679e992a089SEnrico Granata if (log) 1680d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1681fc7a7f3bSEnrico Granata } 1682fc7a7f3bSEnrico Granata 16830a3958e0SEnrico Granata if (!special_directions) 16849fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 16850a3958e0SEnrico Granata else 16860a3958e0SEnrico Granata var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); 16870a3958e0SEnrico Granata 168822c55d18SEnrico Granata if (--max_num_children == 0) 168922c55d18SEnrico Granata { 169022c55d18SEnrico Granata s.PutCString(", ..."); 169122c55d18SEnrico Granata break; 169222c55d18SEnrico Granata } 169322c55d18SEnrico Granata 16940a3958e0SEnrico Granata if (index_lower < index_higher) 16950a3958e0SEnrico Granata s.PutChar(','); 16960a3958e0SEnrico Granata } 16970a3958e0SEnrico Granata s.PutChar(']'); 16984becb37eSEnrico Granata } 16994becb37eSEnrico Granata } 170034132754SGreg Clayton break; 17011b654882SGreg Clayton case 'a': 17021b654882SGreg Clayton if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 17031b654882SGreg Clayton { 17041b654882SGreg Clayton if (addr && addr->IsValid()) 17051b654882SGreg Clayton { 17061b654882SGreg Clayton var_success = true; 17071b654882SGreg Clayton format_addr = *addr; 17081b654882SGreg Clayton } 17091b654882SGreg Clayton } 17105a31471eSGreg Clayton else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0) 17115a31471eSGreg Clayton { 17125a31471eSGreg Clayton var_success = true; 17135a31471eSGreg Clayton var_name_begin += strlen("ansi."); // Skip the "ansi." 17145a31471eSGreg Clayton if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0) 17155a31471eSGreg Clayton { 17165a31471eSGreg Clayton var_name_begin += strlen("fg."); // Skip the "fg." 17175a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 17185a31471eSGreg Clayton { 17195a31471eSGreg Clayton s.Printf ("%s%s%s", 17205a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17215a31471eSGreg Clayton lldb_utility::ansi::k_fg_black, 17225a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17235a31471eSGreg Clayton } 17245a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 17255a31471eSGreg Clayton { 17265a31471eSGreg Clayton s.Printf ("%s%s%s", 17275a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17285a31471eSGreg Clayton lldb_utility::ansi::k_fg_red, 17295a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17305a31471eSGreg Clayton } 17315a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 17325a31471eSGreg Clayton { 17335a31471eSGreg Clayton s.Printf ("%s%s%s", 17345a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17355a31471eSGreg Clayton lldb_utility::ansi::k_fg_green, 17365a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17375a31471eSGreg Clayton } 17385a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 17395a31471eSGreg Clayton { 17405a31471eSGreg Clayton s.Printf ("%s%s%s", 17415a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17425a31471eSGreg Clayton lldb_utility::ansi::k_fg_yellow, 17435a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17445a31471eSGreg Clayton } 17455a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 17465a31471eSGreg Clayton { 17475a31471eSGreg Clayton s.Printf ("%s%s%s", 17485a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17495a31471eSGreg Clayton lldb_utility::ansi::k_fg_blue, 17505a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17515a31471eSGreg Clayton } 17525a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 17535a31471eSGreg Clayton { 17545a31471eSGreg Clayton s.Printf ("%s%s%s", 17555a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17565a31471eSGreg Clayton lldb_utility::ansi::k_fg_purple, 17575a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17585a31471eSGreg Clayton } 17595a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 17605a31471eSGreg Clayton { 17615a31471eSGreg Clayton s.Printf ("%s%s%s", 17625a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17635a31471eSGreg Clayton lldb_utility::ansi::k_fg_cyan, 17645a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17655a31471eSGreg Clayton } 17665a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 17675a31471eSGreg Clayton { 17685a31471eSGreg Clayton s.Printf ("%s%s%s", 17695a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17705a31471eSGreg Clayton lldb_utility::ansi::k_fg_white, 17715a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17725a31471eSGreg Clayton } 17735a31471eSGreg Clayton else 17745a31471eSGreg Clayton { 17755a31471eSGreg Clayton var_success = false; 17765a31471eSGreg Clayton } 17775a31471eSGreg Clayton } 17785a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0) 17795a31471eSGreg Clayton { 17805a31471eSGreg Clayton var_name_begin += strlen("bg."); // Skip the "bg." 17815a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 17825a31471eSGreg Clayton { 17835a31471eSGreg Clayton s.Printf ("%s%s%s", 17845a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17855a31471eSGreg Clayton lldb_utility::ansi::k_bg_black, 17865a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17875a31471eSGreg Clayton } 17885a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 17895a31471eSGreg Clayton { 17905a31471eSGreg Clayton s.Printf ("%s%s%s", 17915a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17925a31471eSGreg Clayton lldb_utility::ansi::k_bg_red, 17935a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17945a31471eSGreg Clayton } 17955a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 17965a31471eSGreg Clayton { 17975a31471eSGreg Clayton s.Printf ("%s%s%s", 17985a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17995a31471eSGreg Clayton lldb_utility::ansi::k_bg_green, 18005a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18015a31471eSGreg Clayton } 18025a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 18035a31471eSGreg Clayton { 18045a31471eSGreg Clayton s.Printf ("%s%s%s", 18055a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18065a31471eSGreg Clayton lldb_utility::ansi::k_bg_yellow, 18075a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18085a31471eSGreg Clayton } 18095a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 18105a31471eSGreg Clayton { 18115a31471eSGreg Clayton s.Printf ("%s%s%s", 18125a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18135a31471eSGreg Clayton lldb_utility::ansi::k_bg_blue, 18145a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18155a31471eSGreg Clayton } 18165a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 18175a31471eSGreg Clayton { 18185a31471eSGreg Clayton s.Printf ("%s%s%s", 18195a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18205a31471eSGreg Clayton lldb_utility::ansi::k_bg_purple, 18215a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18225a31471eSGreg Clayton } 18235a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 18245a31471eSGreg Clayton { 18255a31471eSGreg Clayton s.Printf ("%s%s%s", 18265a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18275a31471eSGreg Clayton lldb_utility::ansi::k_bg_cyan, 18285a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18295a31471eSGreg Clayton } 18305a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 18315a31471eSGreg Clayton { 18325a31471eSGreg Clayton s.Printf ("%s%s%s", 18335a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18345a31471eSGreg Clayton lldb_utility::ansi::k_bg_white, 18355a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18365a31471eSGreg Clayton } 18375a31471eSGreg Clayton else 18385a31471eSGreg Clayton { 18395a31471eSGreg Clayton var_success = false; 18405a31471eSGreg Clayton } 18415a31471eSGreg Clayton } 18425a31471eSGreg Clayton else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0) 18435a31471eSGreg Clayton { 18445a31471eSGreg Clayton s.Printf ("%s%s%s", 18455a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18465a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_normal, 18475a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18485a31471eSGreg Clayton } 18495a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0) 18505a31471eSGreg Clayton { 18515a31471eSGreg Clayton s.Printf ("%s%s%s", 18525a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18535a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_bold, 18545a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18555a31471eSGreg Clayton } 18565a31471eSGreg Clayton else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0) 18575a31471eSGreg Clayton { 18585a31471eSGreg Clayton s.Printf ("%s%s%s", 18595a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18605a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_faint, 18615a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18625a31471eSGreg Clayton } 18635a31471eSGreg Clayton else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0) 18645a31471eSGreg Clayton { 18655a31471eSGreg Clayton s.Printf ("%s%s%s", 18665a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18675a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_italic, 18685a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18695a31471eSGreg Clayton } 18705a31471eSGreg Clayton else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0) 18715a31471eSGreg Clayton { 18725a31471eSGreg Clayton s.Printf ("%s%s%s", 18735a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18745a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_underline, 18755a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18765a31471eSGreg Clayton } 18775a31471eSGreg Clayton else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0) 18785a31471eSGreg Clayton { 18795a31471eSGreg Clayton s.Printf ("%s%s%s", 18805a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18815a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_slow_blink, 18825a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18835a31471eSGreg Clayton } 18845a31471eSGreg Clayton else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0) 18855a31471eSGreg Clayton { 18865a31471eSGreg Clayton s.Printf ("%s%s%s", 18875a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18885a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_fast_blink, 18895a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18905a31471eSGreg Clayton } 18915a31471eSGreg Clayton else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0) 18925a31471eSGreg Clayton { 18935a31471eSGreg Clayton s.Printf ("%s%s%s", 18945a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18955a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_negative, 18965a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18975a31471eSGreg Clayton } 18985a31471eSGreg Clayton else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0) 18995a31471eSGreg Clayton { 19005a31471eSGreg Clayton s.Printf ("%s%s%s", 19015a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 19025a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_conceal, 19035a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 19045a31471eSGreg Clayton 19055a31471eSGreg Clayton } 19065a31471eSGreg Clayton else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0) 19075a31471eSGreg Clayton { 19085a31471eSGreg Clayton s.Printf ("%s%s%s", 19095a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 19105a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_crossed_out, 19115a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 19125a31471eSGreg Clayton } 19135a31471eSGreg Clayton else 19145a31471eSGreg Clayton { 19155a31471eSGreg Clayton var_success = false; 19165a31471eSGreg Clayton } 19175a31471eSGreg Clayton } 19181b654882SGreg Clayton break; 19191b654882SGreg Clayton 19201b654882SGreg Clayton case 'p': 19211b654882SGreg Clayton if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 19221b654882SGreg Clayton { 1923c14ee32dSGreg Clayton if (exe_ctx) 1924c14ee32dSGreg Clayton { 1925c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 1926c14ee32dSGreg Clayton if (process) 19271b654882SGreg Clayton { 19281b654882SGreg Clayton var_name_begin += ::strlen ("process."); 19291b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 19301b654882SGreg Clayton { 1931d01b2953SDaniel Malea s.Printf("%" PRIu64, process->GetID()); 19321b654882SGreg Clayton var_success = true; 19331b654882SGreg Clayton } 19341b654882SGreg Clayton else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 19351b654882SGreg Clayton (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 19361b654882SGreg Clayton (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 19371b654882SGreg Clayton { 1938c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1939aa149cbdSGreg Clayton if (exe_module) 19401b654882SGreg Clayton { 19411b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 19421b654882SGreg Clayton { 1943aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 19441b654882SGreg Clayton var_success = format_file_spec; 19451b654882SGreg Clayton } 19461b654882SGreg Clayton else 19471b654882SGreg Clayton { 1948aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 19491b654882SGreg Clayton var_success = format_file_spec; 19501b654882SGreg Clayton } 19511b654882SGreg Clayton } 19521b654882SGreg Clayton } 19531b654882SGreg Clayton } 19541b654882SGreg Clayton } 1955c14ee32dSGreg Clayton } 19561b654882SGreg Clayton break; 19571b654882SGreg Clayton 19581b654882SGreg Clayton case 't': 19591b654882SGreg Clayton if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 19601b654882SGreg Clayton { 1961c14ee32dSGreg Clayton if (exe_ctx) 1962c14ee32dSGreg Clayton { 1963c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 1964c14ee32dSGreg Clayton if (thread) 19651b654882SGreg Clayton { 19661b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 19671b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 19681b654882SGreg Clayton { 1969d01b2953SDaniel Malea s.Printf("0x%4.4" PRIx64, thread->GetID()); 19701b654882SGreg Clayton var_success = true; 19711b654882SGreg Clayton } 1972160c9d81SGreg Clayton else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0) 1973160c9d81SGreg Clayton { 1974160c9d81SGreg Clayton s.Printf("0x%4.4" PRIx64, thread->GetProtocolID()); 1975160c9d81SGreg Clayton var_success = true; 1976160c9d81SGreg Clayton } 19771b654882SGreg Clayton else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 19781b654882SGreg Clayton { 1979c14ee32dSGreg Clayton s.Printf("%u", thread->GetIndexID()); 19801b654882SGreg Clayton var_success = true; 19811b654882SGreg Clayton } 19821b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 19831b654882SGreg Clayton { 1984c14ee32dSGreg Clayton cstr = thread->GetName(); 19851b654882SGreg Clayton var_success = cstr && cstr[0]; 19861b654882SGreg Clayton if (var_success) 19871b654882SGreg Clayton s.PutCString(cstr); 19881b654882SGreg Clayton } 19891b654882SGreg Clayton else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 19901b654882SGreg Clayton { 1991c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 19921b654882SGreg Clayton var_success = cstr && cstr[0]; 19931b654882SGreg Clayton if (var_success) 19941b654882SGreg Clayton s.PutCString(cstr); 19951b654882SGreg Clayton } 19961b654882SGreg Clayton else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 19971b654882SGreg Clayton { 1998c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 19995d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 20001b654882SGreg Clayton { 2001b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 20021b654882SGreg Clayton if (cstr && cstr[0]) 20031b654882SGreg Clayton { 20041b654882SGreg Clayton s.PutCString(cstr); 20051b654882SGreg Clayton var_success = true; 20061b654882SGreg Clayton } 20071b654882SGreg Clayton } 20081b654882SGreg Clayton } 200973ca05a2SJim Ingham else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0) 201073ca05a2SJim Ingham { 201173ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 20125d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 201373ca05a2SJim Ingham { 201473ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 201573ca05a2SJim Ingham if (return_valobj_sp) 201673ca05a2SJim Ingham { 20179fb5ab55SEnrico Granata ValueObject::DumpValueObject (s, return_valobj_sp.get()); 201873ca05a2SJim Ingham var_success = true; 201973ca05a2SJim Ingham } 202073ca05a2SJim Ingham } 202173ca05a2SJim Ingham } 202273ca05a2SJim Ingham } 20231b654882SGreg Clayton } 20241b654882SGreg Clayton } 20251b654882SGreg Clayton else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 20261b654882SGreg Clayton { 202767cc0636SGreg Clayton // TODO: hookup properties 202867cc0636SGreg Clayton // if (!target_properties_sp) 202967cc0636SGreg Clayton // { 203067cc0636SGreg Clayton // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 203167cc0636SGreg Clayton // if (target) 203267cc0636SGreg Clayton // target_properties_sp = target->GetProperties(); 203367cc0636SGreg Clayton // } 203467cc0636SGreg Clayton // 203567cc0636SGreg Clayton // if (target_properties_sp) 203667cc0636SGreg Clayton // { 203767cc0636SGreg Clayton // var_name_begin += ::strlen ("target."); 203867cc0636SGreg Clayton // const char *end_property = strchr(var_name_begin, '}'); 203967cc0636SGreg Clayton // if (end_property) 204067cc0636SGreg Clayton // { 204167cc0636SGreg Clayton // ConstString property_name(var_name_begin, end_property - var_name_begin); 204267cc0636SGreg Clayton // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 204367cc0636SGreg Clayton // if (!property_value.empty()) 204467cc0636SGreg Clayton // { 204567cc0636SGreg Clayton // s.PutCString (property_value.c_str()); 204667cc0636SGreg Clayton // var_success = true; 204767cc0636SGreg Clayton // } 204867cc0636SGreg Clayton // } 204967cc0636SGreg Clayton // } 20500603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 20510603aa9dSGreg Clayton if (target) 20521b654882SGreg Clayton { 20531b654882SGreg Clayton var_name_begin += ::strlen ("target."); 20541b654882SGreg Clayton if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 20551b654882SGreg Clayton { 20561b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 20571b654882SGreg Clayton if (arch.IsValid()) 20581b654882SGreg Clayton { 205964195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 20601b654882SGreg Clayton var_success = true; 20611b654882SGreg Clayton } 20621b654882SGreg Clayton } 20631b654882SGreg Clayton } 20641b654882SGreg Clayton } 20651b654882SGreg Clayton break; 20661b654882SGreg Clayton 20671b654882SGreg Clayton 20681b654882SGreg Clayton case 'm': 20691b654882SGreg Clayton if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 20701b654882SGreg Clayton { 20710603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 20721b654882SGreg Clayton { 20730603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 20741b654882SGreg Clayton var_name_begin += ::strlen ("module."); 20751b654882SGreg Clayton 20761b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 20771b654882SGreg Clayton { 20781b654882SGreg Clayton if (module->GetFileSpec()) 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() = module->GetFileSpec().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 = module->GetFileSpec(); 20901b654882SGreg Clayton var_success = format_file_spec; 20911b654882SGreg Clayton } 20921b654882SGreg Clayton } 20931b654882SGreg Clayton } 20941b654882SGreg Clayton } 20951b654882SGreg Clayton } 20961b654882SGreg Clayton break; 20971b654882SGreg Clayton 20981b654882SGreg Clayton 20991b654882SGreg Clayton case 'f': 21001b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 21011b654882SGreg Clayton { 21021b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 21031b654882SGreg Clayton { 21041b654882SGreg Clayton var_name_begin += ::strlen ("file."); 21051b654882SGreg Clayton 21061b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 21071b654882SGreg Clayton { 21081b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 21091b654882SGreg Clayton var_success = format_file_spec; 21101b654882SGreg Clayton } 21111b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 21121b654882SGreg Clayton { 21131b654882SGreg Clayton format_file_spec = *sc->comp_unit; 21141b654882SGreg Clayton var_success = format_file_spec; 21151b654882SGreg Clayton } 21161b654882SGreg Clayton } 21171b654882SGreg Clayton } 21181b654882SGreg Clayton else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 21191b654882SGreg Clayton { 2120c14ee32dSGreg Clayton if (exe_ctx) 2121c14ee32dSGreg Clayton { 2122c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2123c14ee32dSGreg Clayton if (frame) 21241b654882SGreg Clayton { 21251b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 21261b654882SGreg Clayton if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 21271b654882SGreg Clayton { 2128c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 21291b654882SGreg Clayton var_success = true; 21301b654882SGreg Clayton } 21311b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 21321b654882SGreg Clayton { 21331b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21341b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 21351b654882SGreg Clayton var_success = true; 21361b654882SGreg Clayton } 21371b654882SGreg Clayton else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 21381b654882SGreg Clayton { 21391b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21401b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 21411b654882SGreg Clayton var_success = true; 21421b654882SGreg Clayton } 21431b654882SGreg Clayton else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 21441b654882SGreg Clayton { 21451b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21461b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 21471b654882SGreg Clayton var_success = true; 21481b654882SGreg Clayton } 21491b654882SGreg Clayton else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 21501b654882SGreg Clayton { 21511b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21521b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 21531b654882SGreg Clayton var_success = true; 21541b654882SGreg Clayton } 21551b654882SGreg Clayton else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 21561b654882SGreg Clayton { 2157c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 21581b654882SGreg Clayton if (reg_ctx) 21591b654882SGreg Clayton { 21601b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 21611b654882SGreg Clayton if (var_name_begin < var_name_end) 21621b654882SGreg Clayton { 21631b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 21641b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 21651b654882SGreg Clayton if (reg_info) 21661b654882SGreg Clayton var_success = true; 21671b654882SGreg Clayton } 21681b654882SGreg Clayton } 21691b654882SGreg Clayton } 21701b654882SGreg Clayton } 21711b654882SGreg Clayton } 2172c14ee32dSGreg Clayton } 21731b654882SGreg Clayton else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 21741b654882SGreg Clayton { 21751b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 21761b654882SGreg Clayton { 21771b654882SGreg Clayton var_name_begin += ::strlen ("function."); 21781b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 21791b654882SGreg Clayton { 21801b654882SGreg Clayton if (sc->function) 2181d01b2953SDaniel Malea s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 21821b654882SGreg Clayton else 21831b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 21841b654882SGreg Clayton 21851b654882SGreg Clayton var_success = true; 21861b654882SGreg Clayton } 21871b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 21881b654882SGreg Clayton { 21891b654882SGreg Clayton if (sc->function) 21901b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21911b654882SGreg Clayton else if (sc->symbol) 21921b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 21931b654882SGreg Clayton if (cstr) 21941b654882SGreg Clayton { 21951b654882SGreg Clayton s.PutCString(cstr); 21960d9c9934SGreg Clayton 21970d9c9934SGreg Clayton if (sc->block) 21980d9c9934SGreg Clayton { 21990d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 22000d9c9934SGreg Clayton if (inline_block) 22010d9c9934SGreg Clayton { 22020d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 22030d9c9934SGreg Clayton if (inline_info) 22040d9c9934SGreg Clayton { 22050d9c9934SGreg Clayton s.PutCString(" [inlined] "); 22060d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 22070d9c9934SGreg Clayton } 22080d9c9934SGreg Clayton } 22090d9c9934SGreg Clayton } 22101b654882SGreg Clayton var_success = true; 22111b654882SGreg Clayton } 22121b654882SGreg Clayton } 22136d3dbf51SGreg Clayton else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0) 22146d3dbf51SGreg Clayton { 22156d3dbf51SGreg Clayton // Print the function name with arguments in it 22166d3dbf51SGreg Clayton 22176d3dbf51SGreg Clayton if (sc->function) 22186d3dbf51SGreg Clayton { 22196d3dbf51SGreg Clayton var_success = true; 22206d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 22216d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 22226d3dbf51SGreg Clayton if (cstr) 22236d3dbf51SGreg Clayton { 22246d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 22256d3dbf51SGreg Clayton VariableListSP variable_list_sp; 22266d3dbf51SGreg Clayton bool get_function_vars = true; 22276d3dbf51SGreg Clayton if (sc->block) 22286d3dbf51SGreg Clayton { 22296d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 22306d3dbf51SGreg Clayton 22316d3dbf51SGreg Clayton if (inline_block) 22326d3dbf51SGreg Clayton { 22336d3dbf51SGreg Clayton get_function_vars = false; 22346d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 22356d3dbf51SGreg Clayton if (inline_info) 22366d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 22376d3dbf51SGreg Clayton } 22386d3dbf51SGreg Clayton } 22396d3dbf51SGreg Clayton 22406d3dbf51SGreg Clayton if (get_function_vars) 22416d3dbf51SGreg Clayton { 22426d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 22436d3dbf51SGreg Clayton } 22446d3dbf51SGreg Clayton 22456d3dbf51SGreg Clayton if (inline_info) 22466d3dbf51SGreg Clayton { 22476d3dbf51SGreg Clayton s.PutCString (cstr); 22486d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 22496d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 22506d3dbf51SGreg Clayton } 22516d3dbf51SGreg Clayton 22526d3dbf51SGreg Clayton VariableList args; 22536d3dbf51SGreg Clayton if (variable_list_sp) 2254*cc7f9bf5SEnrico Granata variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 22556d3dbf51SGreg Clayton if (args.GetSize() > 0) 22566d3dbf51SGreg Clayton { 22576d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 22586d3dbf51SGreg Clayton const char *close_paren = NULL; 22596d3dbf51SGreg Clayton if (open_paren) 2260855958caSGreg Clayton { 2261855958caSGreg Clayton if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0) 2262855958caSGreg Clayton { 2263855958caSGreg Clayton open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2264855958caSGreg Clayton if (open_paren) 22656d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 2266855958caSGreg Clayton } 2267855958caSGreg Clayton else 2268855958caSGreg Clayton close_paren = strchr (open_paren, ')'); 2269855958caSGreg Clayton } 22706d3dbf51SGreg Clayton 22716d3dbf51SGreg Clayton if (open_paren) 22726d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 22736d3dbf51SGreg Clayton else 22746d3dbf51SGreg Clayton { 22756d3dbf51SGreg Clayton s.PutCString (cstr); 22766d3dbf51SGreg Clayton s.PutChar ('('); 22776d3dbf51SGreg Clayton } 22785b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 22796d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 22806d3dbf51SGreg Clayton { 22816d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 22826d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 22836d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 22846d3dbf51SGreg Clayton const char *var_value = var_value_sp->GetValueAsCString(); 22856d3dbf51SGreg Clayton if (arg_idx > 0) 22866d3dbf51SGreg Clayton s.PutCString (", "); 22873b188b17SGreg Clayton if (var_value_sp->GetError().Success()) 2288*cc7f9bf5SEnrico Granata { 2289*cc7f9bf5SEnrico Granata if (var_value) 22906d3dbf51SGreg Clayton s.Printf ("%s=%s", var_name, var_value); 22913b188b17SGreg Clayton else 2292*cc7f9bf5SEnrico Granata s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2293*cc7f9bf5SEnrico Granata } 2294*cc7f9bf5SEnrico Granata else 22953b188b17SGreg Clayton s.Printf ("%s=<unavailable>", var_name); 22966d3dbf51SGreg Clayton } 22976d3dbf51SGreg Clayton 22986d3dbf51SGreg Clayton if (close_paren) 22996d3dbf51SGreg Clayton s.PutCString (close_paren); 23006d3dbf51SGreg Clayton else 23016d3dbf51SGreg Clayton s.PutChar(')'); 23026d3dbf51SGreg Clayton 23036d3dbf51SGreg Clayton } 23046d3dbf51SGreg Clayton else 23056d3dbf51SGreg Clayton { 23066d3dbf51SGreg Clayton s.PutCString(cstr); 23076d3dbf51SGreg Clayton } 23086d3dbf51SGreg Clayton } 23096d3dbf51SGreg Clayton } 23106d3dbf51SGreg Clayton else if (sc->symbol) 23116d3dbf51SGreg Clayton { 23126d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 23136d3dbf51SGreg Clayton if (cstr) 23146d3dbf51SGreg Clayton { 23156d3dbf51SGreg Clayton s.PutCString(cstr); 23166d3dbf51SGreg Clayton var_success = true; 23176d3dbf51SGreg Clayton } 23186d3dbf51SGreg Clayton } 23196d3dbf51SGreg Clayton } 23201b654882SGreg Clayton else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 23211b654882SGreg Clayton { 23221b654882SGreg Clayton var_success = addr != NULL; 23231b654882SGreg Clayton if (var_success) 23241b654882SGreg Clayton { 23251b654882SGreg Clayton format_addr = *addr; 23261b654882SGreg Clayton calculate_format_addr_function_offset = true; 23271b654882SGreg Clayton } 23281b654882SGreg Clayton } 23291b654882SGreg Clayton else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 23301b654882SGreg Clayton { 23311b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 23321b654882SGreg Clayton if (var_success) 23331b654882SGreg Clayton { 23341b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23351b654882SGreg Clayton calculate_format_addr_function_offset = true; 23361b654882SGreg Clayton } 23371b654882SGreg Clayton } 23381b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 23391b654882SGreg Clayton { 2340c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2341c14ee32dSGreg Clayton var_success = frame != NULL; 23421b654882SGreg Clayton if (var_success) 23431b654882SGreg Clayton { 2344c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23451b654882SGreg Clayton calculate_format_addr_function_offset = true; 23461b654882SGreg Clayton } 23471b654882SGreg Clayton } 23481b654882SGreg Clayton } 23491b654882SGreg Clayton } 23501b654882SGreg Clayton break; 23511b654882SGreg Clayton 23521b654882SGreg Clayton case 'l': 23531b654882SGreg Clayton if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 23541b654882SGreg Clayton { 23551b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 23561b654882SGreg Clayton { 23571b654882SGreg Clayton var_name_begin += ::strlen ("line."); 23581b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 23591b654882SGreg Clayton { 23601b654882SGreg Clayton var_name_begin += ::strlen ("file."); 23611b654882SGreg Clayton 23621b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 23631b654882SGreg Clayton { 23641b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 23651b654882SGreg Clayton var_success = format_file_spec; 23661b654882SGreg Clayton } 23671b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 23681b654882SGreg Clayton { 23691b654882SGreg Clayton format_file_spec = sc->line_entry.file; 23701b654882SGreg Clayton var_success = format_file_spec; 23711b654882SGreg Clayton } 23721b654882SGreg Clayton } 23731b654882SGreg Clayton else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 23741b654882SGreg Clayton { 23751b654882SGreg Clayton var_success = true; 23761b654882SGreg Clayton s.Printf("%u", sc->line_entry.line); 23771b654882SGreg Clayton } 23781b654882SGreg Clayton else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 23791b654882SGreg Clayton (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 23801b654882SGreg Clayton { 23811b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 23821b654882SGreg Clayton if (var_success) 23831b654882SGreg Clayton { 23841b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23851b654882SGreg Clayton if (var_name_begin[0] == 'e') 23861b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 23871b654882SGreg Clayton } 23881b654882SGreg Clayton } 23891b654882SGreg Clayton } 23901b654882SGreg Clayton } 23911b654882SGreg Clayton break; 23921b654882SGreg Clayton } 23931b654882SGreg Clayton 23941b654882SGreg Clayton if (var_success) 23951b654882SGreg Clayton { 23961b654882SGreg Clayton // If format addr is valid, then we need to print an address 23971b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 23981b654882SGreg Clayton { 2399c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 24001b654882SGreg Clayton // We have a register value to display... 24011b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 24021b654882SGreg Clayton { 2403c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 24041b654882SGreg Clayton } 24051b654882SGreg Clayton else 24061b654882SGreg Clayton { 24071b654882SGreg Clayton if (reg_ctx == NULL) 2408c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 24091b654882SGreg Clayton 24101b654882SGreg Clayton if (reg_ctx) 24111b654882SGreg Clayton { 24121b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 24131b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 24141b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 24151b654882SGreg Clayton var_success = reg_info != NULL; 24161b654882SGreg Clayton } 24171b654882SGreg Clayton } 24181b654882SGreg Clayton } 24191b654882SGreg Clayton 24201b654882SGreg Clayton if (reg_info != NULL) 24211b654882SGreg Clayton { 24227349bd90SGreg Clayton RegisterValue reg_value; 24237349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 24247349bd90SGreg Clayton if (var_success) 24251b654882SGreg Clayton { 24269a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 24271b654882SGreg Clayton } 24281b654882SGreg Clayton } 24291b654882SGreg Clayton 24301b654882SGreg Clayton if (format_file_spec) 24311b654882SGreg Clayton { 24321b654882SGreg Clayton s << format_file_spec; 24331b654882SGreg Clayton } 24341b654882SGreg Clayton 24351b654882SGreg Clayton // If format addr is valid, then we need to print an address 24361b654882SGreg Clayton if (format_addr.IsValid()) 24371b654882SGreg Clayton { 24380603aa9dSGreg Clayton var_success = false; 24390603aa9dSGreg Clayton 24401b654882SGreg Clayton if (calculate_format_addr_function_offset) 24411b654882SGreg Clayton { 24421b654882SGreg Clayton Address func_addr; 24430603aa9dSGreg Clayton 24440603aa9dSGreg Clayton if (sc) 24450603aa9dSGreg Clayton { 24461b654882SGreg Clayton if (sc->function) 24470d9c9934SGreg Clayton { 24481b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 24490d9c9934SGreg Clayton if (sc->block) 24500d9c9934SGreg Clayton { 24510d9c9934SGreg Clayton // Check to make sure we aren't in an inline 24520d9c9934SGreg Clayton // function. If we are, use the inline block 24530d9c9934SGreg Clayton // range that contains "format_addr" since 24540d9c9934SGreg Clayton // blocks can be discontiguous. 24550d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 24560d9c9934SGreg Clayton AddressRange inline_range; 24570d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 24580d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 24590d9c9934SGreg Clayton } 24600d9c9934SGreg Clayton } 2461e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2462e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 24630603aa9dSGreg Clayton } 24641b654882SGreg Clayton 24650603aa9dSGreg Clayton if (func_addr.IsValid()) 24661b654882SGreg Clayton { 24671b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 24681b654882SGreg Clayton { 24691b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 24701b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 24711b654882SGreg Clayton if (addr_file_addr > func_file_addr) 2472d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 24731b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 2474d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 24750603aa9dSGreg Clayton var_success = true; 24761b654882SGreg Clayton } 24771b654882SGreg Clayton else 24780603aa9dSGreg Clayton { 24790603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24800603aa9dSGreg Clayton if (target) 24810603aa9dSGreg Clayton { 24820603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 24830603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 24840603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 2485d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 24860603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 2487d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 24880603aa9dSGreg Clayton var_success = true; 24890603aa9dSGreg Clayton } 24900603aa9dSGreg Clayton } 24911b654882SGreg Clayton } 24921b654882SGreg Clayton } 24931b654882SGreg Clayton else 24941b654882SGreg Clayton { 24950603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24961b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 24970603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 24980603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 24991b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 25001b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 25011b654882SGreg Clayton 25021b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 25030603aa9dSGreg Clayton { 2504514487e8SGreg Clayton int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 250535f1a0d5SGreg Clayton if (addr_width == 0) 250635f1a0d5SGreg Clayton addr_width = 16; 2507d01b2953SDaniel Malea s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 25080603aa9dSGreg Clayton var_success = true; 25090603aa9dSGreg Clayton } 25101b654882SGreg Clayton } 25111b654882SGreg Clayton } 25121b654882SGreg Clayton } 25131b654882SGreg Clayton 25141b654882SGreg Clayton if (var_success == false) 25151b654882SGreg Clayton success = false; 25161b654882SGreg Clayton } 25171b654882SGreg Clayton p = var_name_end; 25181b654882SGreg Clayton } 25191b654882SGreg Clayton else 25201b654882SGreg Clayton break; 25211b654882SGreg Clayton } 25221b654882SGreg Clayton else 25231b654882SGreg Clayton { 25241b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 25251b654882SGreg Clayton s.PutChar(*p); 25261b654882SGreg Clayton } 25271b654882SGreg Clayton } 25281b654882SGreg Clayton else if (*p == '\\') 25291b654882SGreg Clayton { 25301b654882SGreg Clayton ++p; // skip the slash 25311b654882SGreg Clayton switch (*p) 25321b654882SGreg Clayton { 25331b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 25341b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 25351b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 25361b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 25371b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 25381b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 25391b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 25401b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 25411b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 25421b654882SGreg Clayton case '0': 25431b654882SGreg Clayton // 1 to 3 octal chars 25441b654882SGreg Clayton { 25450603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 25460603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 25470603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 25480603aa9dSGreg Clayton 25490603aa9dSGreg Clayton int i; 25500603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 25510603aa9dSGreg Clayton oct_str[i] = p[i]; 25520603aa9dSGreg Clayton 25530603aa9dSGreg Clayton // We don't want to consume the last octal character since 25540603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 25550603aa9dSGreg Clayton // one less than i (even if i is zero) 25560603aa9dSGreg Clayton p += i - 1; 25570603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 25580603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 25591b654882SGreg Clayton { 2560c7bece56SGreg Clayton s.PutChar((char)octal_value); 25611b654882SGreg Clayton } 25621b654882SGreg Clayton } 25631b654882SGreg Clayton break; 25641b654882SGreg Clayton 25651b654882SGreg Clayton case 'x': 25661b654882SGreg Clayton // hex number in the format 25670603aa9dSGreg Clayton if (isxdigit(p[1])) 25681b654882SGreg Clayton { 25690603aa9dSGreg Clayton ++p; // Skip the 'x' 25701b654882SGreg Clayton 25710603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 25720603aa9dSGreg Clayton // NULL terminator 25731b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 25741b654882SGreg Clayton hex_str[0] = *p; 25750603aa9dSGreg Clayton if (isxdigit(p[1])) 25760603aa9dSGreg Clayton { 25770603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 25781b654882SGreg Clayton hex_str[1] = *p; 25790603aa9dSGreg Clayton } 25800603aa9dSGreg Clayton 25811b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 25820603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 2583c7bece56SGreg Clayton s.PutChar ((char)hex_value); 25841b654882SGreg Clayton } 25851b654882SGreg Clayton else 25861b654882SGreg Clayton { 25870603aa9dSGreg Clayton s.PutChar('x'); 25881b654882SGreg Clayton } 25891b654882SGreg Clayton break; 25901b654882SGreg Clayton 25911b654882SGreg Clayton default: 25920603aa9dSGreg Clayton // Just desensitize any other character by just printing what 25930603aa9dSGreg Clayton // came after the '\' 25940603aa9dSGreg Clayton s << *p; 25951b654882SGreg Clayton break; 25961b654882SGreg Clayton 25971b654882SGreg Clayton } 25981b654882SGreg Clayton 25991b654882SGreg Clayton } 26001b654882SGreg Clayton } 26011b654882SGreg Clayton if (end) 26021b654882SGreg Clayton *end = p; 26031b654882SGreg Clayton return success; 26041b654882SGreg Clayton } 26051b654882SGreg Clayton 2606228063cdSJim Ingham void 2607228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2608228063cdSJim Ingham { 26094f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 26104f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 26114f02b22dSJim Ingham // callback. 2612228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2613228063cdSJim Ingham } 2614228063cdSJim Ingham 2615228063cdSJim Ingham bool 2616228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2617228063cdSJim Ingham { 2618228063cdSJim Ingham Log::Callbacks log_callbacks; 2619228063cdSJim Ingham 2620228063cdSJim Ingham StreamSP log_stream_sp; 26219a028519SSean Callanan if (m_log_callback_stream_sp) 2622228063cdSJim Ingham { 2623228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2624228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2625228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2626228063cdSJim Ingham } 2627228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2628228063cdSJim Ingham { 2629228063cdSJim Ingham log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false)); 2630228063cdSJim Ingham } 2631228063cdSJim Ingham else 2632228063cdSJim Ingham { 2633228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2634c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 2635c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 2636c1b2ccfdSGreg Clayton if (!log_stream_sp) 2637228063cdSJim Ingham { 2638228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2639228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2640228063cdSJim Ingham } 2641228063cdSJim Ingham } 2642228063cdSJim Ingham assert (log_stream_sp.get()); 2643228063cdSJim Ingham 2644228063cdSJim Ingham if (log_options == 0) 2645228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2646228063cdSJim Ingham 2647228063cdSJim Ingham if (Log::GetLogChannelCallbacks (channel, log_callbacks)) 2648228063cdSJim Ingham { 2649228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2650228063cdSJim Ingham return true; 2651228063cdSJim Ingham } 2652228063cdSJim Ingham else 2653228063cdSJim Ingham { 2654228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2655228063cdSJim Ingham if (log_channel_sp) 2656228063cdSJim Ingham { 2657228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2658228063cdSJim Ingham { 2659228063cdSJim Ingham return true; 2660228063cdSJim Ingham } 2661228063cdSJim Ingham else 2662228063cdSJim Ingham { 2663228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2664228063cdSJim Ingham return false; 2665228063cdSJim Ingham } 2666228063cdSJim Ingham } 2667228063cdSJim Ingham else 2668228063cdSJim Ingham { 2669228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2670228063cdSJim Ingham return false; 2671228063cdSJim Ingham } 2672228063cdSJim Ingham } 2673228063cdSJim Ingham return false; 2674228063cdSJim Ingham } 2675228063cdSJim Ingham 26769585fbfcSGreg Clayton SourceManager & 26779585fbfcSGreg Clayton Debugger::GetSourceManager () 26789585fbfcSGreg Clayton { 26799585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 26809585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 26819585fbfcSGreg Clayton return *m_source_manager_ap; 26829585fbfcSGreg Clayton } 26839585fbfcSGreg Clayton 26849585fbfcSGreg Clayton 2685