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: 1177*5c42d8a8SJim Ingham if (log) 117836aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 117936aa5ae6SEnrico Granata break; 118036aa5ae6SEnrico Granata } 11819fc1944eSEnrico Granata } 11829fc1944eSEnrico Granata // a good custom format tells us to print the value using it 11839fc1944eSEnrico Granata else 1184e992a089SEnrico Granata { 1185e992a089SEnrico Granata if (log) 1186d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] will display value for this VO"); 118786cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1188e992a089SEnrico Granata } 11899fc1944eSEnrico Granata } 1190e992a089SEnrico Granata if (log) 1191d228483dSEnrico Granata log->Printf("ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1192e992a089SEnrico Granata *custom_format, 1193e992a089SEnrico Granata *val_obj_display); 11949fc1944eSEnrico Granata return true; 11959fc1944eSEnrico Granata } 11969fc1944eSEnrico Granata 11979fc1944eSEnrico Granata static bool 11989fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 11999fc1944eSEnrico Granata const char* var_name_end, 12009fc1944eSEnrico Granata const char* var_name_final, 12019fc1944eSEnrico Granata const char** open_bracket_position, 12029fc1944eSEnrico Granata const char** separator_position, 12039fc1944eSEnrico Granata const char** close_bracket_position, 12049fc1944eSEnrico Granata const char** var_name_final_if_array_range, 12059fc1944eSEnrico Granata int64_t* index_lower, 12069fc1944eSEnrico Granata int64_t* index_higher) 12079fc1944eSEnrico Granata { 12085160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12099fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 12109fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 12119fc1944eSEnrico Granata { 12129fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 12139fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 12149fc1944eSEnrico Granata // as usual, we assume that [] will come before % 12159fc1944eSEnrico Granata //printf("trying to expand a []\n"); 12169fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 12179fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 12189fc1944eSEnrico Granata { 1219e992a089SEnrico Granata if (log) 1220d228483dSEnrico Granata log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 12219fc1944eSEnrico Granata *index_lower = 0; 12229fc1944eSEnrico Granata } 12239fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 12249fc1944eSEnrico Granata { 12259fc1944eSEnrico Granata char *end = NULL; 12269fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12279fc1944eSEnrico Granata *index_higher = *index_lower; 1228e992a089SEnrico Granata if (log) 1229d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 12309fc1944eSEnrico Granata } 12319fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 12329fc1944eSEnrico Granata { 12339fc1944eSEnrico Granata char *end = NULL; 12349fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12359fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 1236e992a089SEnrico Granata if (log) 1237d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 12389fc1944eSEnrico Granata } 12399fc1944eSEnrico Granata else 1240e992a089SEnrico Granata { 1241e992a089SEnrico Granata if (log) 1242d228483dSEnrico Granata log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 12439fc1944eSEnrico Granata return false; 1244e992a089SEnrico Granata } 12459fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 12469fc1944eSEnrico Granata { 1247e992a089SEnrico Granata if (log) 1248d228483dSEnrico Granata log->Printf("[ScanBracketedRange] swapping indices"); 1249c7bece56SGreg Clayton int64_t temp = *index_lower; 12509fc1944eSEnrico Granata *index_lower = *index_higher; 12519fc1944eSEnrico Granata *index_higher = temp; 12529fc1944eSEnrico Granata } 12539fc1944eSEnrico Granata } 1254e992a089SEnrico Granata else if (log) 1255d228483dSEnrico Granata log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 12569fc1944eSEnrico Granata return true; 12579fc1944eSEnrico Granata } 12589fc1944eSEnrico Granata 12599fc1944eSEnrico Granata static ValueObjectSP 1260c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 1261c7bece56SGreg Clayton size_t index, 12629fc1944eSEnrico Granata StackFrame* frame, 1263fc7a7f3bSEnrico Granata bool deref_pointer) 12649fc1944eSEnrico Granata { 12655160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1266fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1267599171adSEnrico Granata std::string ptr_deref_buffer(10,0); 1268599171adSEnrico Granata ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1269e992a089SEnrico Granata if (log) 1270599171adSEnrico Granata log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1271fc7a7f3bSEnrico Granata const char* first_unparsed; 1272fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1273fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1274fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 127586cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1276599171adSEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1277fc7a7f3bSEnrico Granata &first_unparsed, 1278fc7a7f3bSEnrico Granata &reason_to_stop, 1279fc7a7f3bSEnrico Granata &final_value_type, 1280fc7a7f3bSEnrico Granata options, 1281fc7a7f3bSEnrico Granata &what_next); 1282fc7a7f3bSEnrico Granata if (!item) 1283fc7a7f3bSEnrico Granata { 1284e992a089SEnrico Granata if (log) 1285d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1286e992a089SEnrico Granata " final_value_type %d", 1287fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1288fc7a7f3bSEnrico Granata } 12899fc1944eSEnrico Granata else 12909fc1944eSEnrico Granata { 1291e992a089SEnrico Granata if (log) 1292d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1293e992a089SEnrico Granata " final_value_type %d", 1294fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 12959fc1944eSEnrico Granata } 12969fc1944eSEnrico Granata return item; 12979fc1944eSEnrico Granata } 12989fc1944eSEnrico Granata 12991b654882SGreg Clayton bool 13001b654882SGreg Clayton Debugger::FormatPrompt 13011b654882SGreg Clayton ( 13021b654882SGreg Clayton const char *format, 13031b654882SGreg Clayton const SymbolContext *sc, 13041b654882SGreg Clayton const ExecutionContext *exe_ctx, 13051b654882SGreg Clayton const Address *addr, 13061b654882SGreg Clayton Stream &s, 13074becb37eSEnrico Granata const char **end, 1308c482a192SEnrico Granata ValueObject* valobj 13091b654882SGreg Clayton ) 13101b654882SGreg Clayton { 1311c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 13121b654882SGreg Clayton bool success = true; 13131b654882SGreg Clayton const char *p; 13145160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 13151b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 13161b654882SGreg Clayton { 1317c482a192SEnrico Granata if (realvalobj) 13184becb37eSEnrico Granata { 1319c482a192SEnrico Granata valobj = realvalobj; 1320c482a192SEnrico Granata realvalobj = NULL; 13214becb37eSEnrico Granata } 13221b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 13231b654882SGreg Clayton if (non_special_chars > 0) 13241b654882SGreg Clayton { 13251b654882SGreg Clayton if (success) 13261b654882SGreg Clayton s.Write (p, non_special_chars); 13271b654882SGreg Clayton p += non_special_chars; 13281b654882SGreg Clayton } 13291b654882SGreg Clayton 13301b654882SGreg Clayton if (*p == '\0') 13311b654882SGreg Clayton { 13321b654882SGreg Clayton break; 13331b654882SGreg Clayton } 13341b654882SGreg Clayton else if (*p == '{') 13351b654882SGreg Clayton { 13361b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 13371b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 13381b654882SGreg Clayton // a format that only prints out the function or symbol name if there 13391b654882SGreg Clayton // is one in the symbol context you can use: 13401b654882SGreg Clayton // "{function =${function.name}}" 13411b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 13421b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 13431b654882SGreg Clayton // will then be evaluated and only be output if there is a function 13441b654882SGreg Clayton // or symbol with a valid name. 13451b654882SGreg Clayton StreamString sub_strm; 13461b654882SGreg Clayton 13471b654882SGreg Clayton ++p; // Skip the '{' 13481b654882SGreg Clayton 1349c482a192SEnrico Granata if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 13501b654882SGreg Clayton { 13511b654882SGreg Clayton // The stream had all it needed 13521b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 13531b654882SGreg Clayton } 13541b654882SGreg Clayton if (*p != '}') 13551b654882SGreg Clayton { 13561b654882SGreg Clayton success = false; 13571b654882SGreg Clayton break; 13581b654882SGreg Clayton } 13591b654882SGreg Clayton } 13601b654882SGreg Clayton else if (*p == '}') 13611b654882SGreg Clayton { 13621b654882SGreg Clayton // End of a enclosing scope 13631b654882SGreg Clayton break; 13641b654882SGreg Clayton } 13651b654882SGreg Clayton else if (*p == '$') 13661b654882SGreg Clayton { 13671b654882SGreg Clayton // We have a prompt variable to print 13681b654882SGreg Clayton ++p; 13691b654882SGreg Clayton if (*p == '{') 13701b654882SGreg Clayton { 13711b654882SGreg Clayton ++p; 13721b654882SGreg Clayton const char *var_name_begin = p; 13731b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 13741b654882SGreg Clayton 13751b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 13761b654882SGreg Clayton { 13771b654882SGreg Clayton // if we have already failed to parse, skip this variable 13781b654882SGreg Clayton if (success) 13791b654882SGreg Clayton { 13801b654882SGreg Clayton const char *cstr = NULL; 13811b654882SGreg Clayton Address format_addr; 13821b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 13831b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 13841b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 13851b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 13861b654882SGreg Clayton FileSpec format_file_spec; 1387e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 13881b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 13899fc1944eSEnrico Granata bool do_deref_pointer = false; 139086cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 139186cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 13921b654882SGreg Clayton 13931b654882SGreg Clayton // Each variable must set success to true below... 13941b654882SGreg Clayton bool var_success = false; 13951b654882SGreg Clayton switch (var_name_begin[0]) 13961b654882SGreg Clayton { 13974becb37eSEnrico Granata case '*': 13986f3533fbSEnrico Granata case 'v': 13996f3533fbSEnrico Granata case 's': 14004becb37eSEnrico Granata { 1401c482a192SEnrico Granata if (!valobj) 140234132754SGreg Clayton break; 14036f3533fbSEnrico Granata 1404c3e320a7SEnrico Granata if (log) 1405d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1406c3e320a7SEnrico Granata 14076f3533fbSEnrico Granata // check for *var and *svar 14086f3533fbSEnrico Granata if (*var_name_begin == '*') 14096f3533fbSEnrico Granata { 14109fc1944eSEnrico Granata do_deref_pointer = true; 14119fc1944eSEnrico Granata var_name_begin++; 14129fc1944eSEnrico Granata } 1413c3e320a7SEnrico Granata 1414c3e320a7SEnrico Granata if (log) 1415d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1416c3e320a7SEnrico Granata 14176f3533fbSEnrico Granata if (*var_name_begin == 's') 14184becb37eSEnrico Granata { 1419c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 142086cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 142186cc9829SEnrico Granata if (!valobj) 142286cc9829SEnrico Granata break; 14236f3533fbSEnrico Granata var_name_begin++; 14246f3533fbSEnrico Granata } 14256f3533fbSEnrico Granata 1426c3e320a7SEnrico Granata if (log) 1427d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1428c3e320a7SEnrico Granata 14296f3533fbSEnrico Granata // should be a 'v' by now 14306f3533fbSEnrico Granata if (*var_name_begin != 'v') 14316f3533fbSEnrico Granata break; 14326f3533fbSEnrico Granata 1433c3e320a7SEnrico Granata if (log) 1434d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1435c3e320a7SEnrico Granata 1436fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 143786cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1438fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 14398c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 144086cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 144134132754SGreg Clayton ValueObject* target = NULL; 14424d122c40SGreg Clayton Format custom_format = eFormatInvalid; 144334132754SGreg Clayton const char* var_name_final = NULL; 14449fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 144534132754SGreg Clayton const char* close_bracket_position = NULL; 144634132754SGreg Clayton int64_t index_lower = -1; 144734132754SGreg Clayton int64_t index_higher = -1; 14489fc1944eSEnrico Granata bool is_array_range = false; 1449fc7a7f3bSEnrico Granata const char* first_unparsed; 145085933ed4SEnrico Granata bool was_plain_var = false; 145185933ed4SEnrico Granata bool was_var_format = false; 1452a777dc2aSEnrico Granata bool was_var_indexed = false; 1453fc7a7f3bSEnrico Granata 1454c482a192SEnrico Granata if (!valobj) break; 1455c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 14569fc1944eSEnrico Granata if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) 14570a3958e0SEnrico Granata { 145885933ed4SEnrico Granata was_plain_var = true; 1459c482a192SEnrico Granata target = valobj; 146086cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 14610a3958e0SEnrico Granata } 14629fc1944eSEnrico Granata else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) 14639fc1944eSEnrico Granata { 146485933ed4SEnrico Granata was_var_format = true; 14659fc1944eSEnrico Granata // this is a variable with some custom format applied to it 14669fc1944eSEnrico Granata const char* percent_position; 1467c482a192SEnrico Granata target = valobj; 146886cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 14699fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 14709fc1944eSEnrico Granata var_name_end, 14719fc1944eSEnrico Granata &var_name_final, 14729fc1944eSEnrico Granata &percent_position, 14739fc1944eSEnrico Granata &custom_format, 14749fc1944eSEnrico Granata &val_obj_display); 14750a3958e0SEnrico Granata } 14769fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 14779fc1944eSEnrico Granata else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) 14789fc1944eSEnrico Granata { 1479a777dc2aSEnrico Granata if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0) 1480a777dc2aSEnrico Granata was_var_indexed = true; 14819fc1944eSEnrico Granata const char* percent_position; 14829fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 14839fc1944eSEnrico Granata var_name_end, 14849fc1944eSEnrico Granata &var_name_final, 14859fc1944eSEnrico Granata &percent_position, 14869fc1944eSEnrico Granata &custom_format, 14879fc1944eSEnrico Granata &val_obj_display); 14889fc1944eSEnrico Granata 14899fc1944eSEnrico Granata const char* open_bracket_position; 14909fc1944eSEnrico Granata const char* separator_position; 14919fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 14929fc1944eSEnrico Granata var_name_end, 14939fc1944eSEnrico Granata var_name_final, 14949fc1944eSEnrico Granata &open_bracket_position, 14959fc1944eSEnrico Granata &separator_position, 14969fc1944eSEnrico Granata &close_bracket_position, 14979fc1944eSEnrico Granata &var_name_final_if_array_range, 14989fc1944eSEnrico Granata &index_lower, 14999fc1944eSEnrico Granata &index_higher); 15009fc1944eSEnrico Granata 15019fc1944eSEnrico Granata Error error; 15029fc1944eSEnrico Granata 1503599171adSEnrico Granata std::string expr_path(var_name_final-var_name_begin-1,0); 1504599171adSEnrico Granata memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1505fc7a7f3bSEnrico Granata 1506e992a089SEnrico Granata if (log) 1507599171adSEnrico Granata log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1508fc7a7f3bSEnrico Granata 1509599171adSEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1510fc7a7f3bSEnrico Granata &first_unparsed, 1511fc7a7f3bSEnrico Granata &reason_to_stop, 1512fc7a7f3bSEnrico Granata &final_value_type, 1513fc7a7f3bSEnrico Granata options, 1514fc7a7f3bSEnrico Granata &what_next).get(); 1515fc7a7f3bSEnrico Granata 1516fc7a7f3bSEnrico Granata if (!target) 15179fc1944eSEnrico Granata { 1518e992a089SEnrico Granata if (log) 1519d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1520e992a089SEnrico Granata " final_value_type %d", 1521fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1522fc7a7f3bSEnrico Granata break; 15230a3958e0SEnrico Granata } 1524a7187d00SEnrico Granata else 1525fc7a7f3bSEnrico Granata { 1526e992a089SEnrico Granata if (log) 1527d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1528e992a089SEnrico Granata " final_value_type %d", 1529fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1530a7187d00SEnrico Granata } 15310a3958e0SEnrico Granata } 15320a3958e0SEnrico Granata else 15330a3958e0SEnrico Granata break; 15349fc1944eSEnrico Granata 153586cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 153686cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1537fc7a7f3bSEnrico Granata 153886cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1539fc7a7f3bSEnrico Granata 1540a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 15410a3958e0SEnrico Granata { 15429fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 15439fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 15449fc1944eSEnrico Granata // to get to the target ValueObject 15459fc1944eSEnrico Granata Error error; 15469fc1944eSEnrico Granata target = target->Dereference(error).get(); 1547dc940730SEnrico Granata if (error.Fail()) 1548dc940730SEnrico Granata { 1549dc940730SEnrico Granata if (log) 1550d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1551dc940730SEnrico Granata break; 1552dc940730SEnrico Granata } 15539fc1944eSEnrico Granata do_deref_pointer = false; 15540a3958e0SEnrico Granata } 15550a3958e0SEnrico Granata 1556a777dc2aSEnrico Granata // <rdar://problem/11338654> 1557a777dc2aSEnrico Granata // we do not want to use the summary for a bitfield of type T:n 1558a777dc2aSEnrico Granata // if we were originally dealing with just a T - that would get 1559a777dc2aSEnrico Granata // us into an endless recursion 1560a777dc2aSEnrico Granata if (target->IsBitfield() && was_var_indexed) 1561a777dc2aSEnrico Granata { 1562a777dc2aSEnrico Granata // TODO: check for a (T:n)-specific summary - we should still obey that 1563a777dc2aSEnrico Granata StreamString bitfield_name; 1564a777dc2aSEnrico Granata bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1565a777dc2aSEnrico Granata lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1566a777dc2aSEnrico Granata if (!DataVisualization::GetSummaryForType(type_sp)) 1567a777dc2aSEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1568a777dc2aSEnrico Granata } 1569a777dc2aSEnrico Granata 157085933ed4SEnrico Granata // TODO use flags for these 15714ef877f5SGreg Clayton bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL); 1572f4efecd9SEnrico Granata bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); 157385933ed4SEnrico Granata bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType()); 1574f4efecd9SEnrico Granata 157586cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1576f4efecd9SEnrico Granata { 157785933ed4SEnrico Granata StreamString str_temp; 1578e992a089SEnrico Granata if (log) 1579d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1580d64d0bc0SEnrico Granata 15815088c486SGreg Clayton if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1582d64d0bc0SEnrico Granata { 1583f4efecd9SEnrico Granata // try to use the special cases 158485933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 158585933ed4SEnrico Granata val_obj_display, 158685933ed4SEnrico Granata custom_format); 1587e992a089SEnrico Granata if (log) 1588d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1589d64d0bc0SEnrico Granata 1590d64d0bc0SEnrico Granata // should not happen 15915088c486SGreg Clayton if (var_success) 159285933ed4SEnrico Granata s << str_temp.GetData(); 1593d64d0bc0SEnrico Granata var_success = true; 1594d64d0bc0SEnrico Granata break; 1595d64d0bc0SEnrico Granata } 1596d64d0bc0SEnrico Granata else 1597d64d0bc0SEnrico Granata { 159888da35f8SEnrico Granata if (was_plain_var) // if ${var} 1599d64d0bc0SEnrico Granata { 1600d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1601d64d0bc0SEnrico Granata } 160288da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 160388da35f8SEnrico Granata { 160423f59509SGreg Clayton target->DumpPrintableRepresentation (s, 160588da35f8SEnrico Granata val_obj_display, 160686cc9829SEnrico Granata custom_format, 160786cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 160888da35f8SEnrico Granata } 1609d64d0bc0SEnrico Granata var_success = true; 1610d64d0bc0SEnrico Granata break; 1611d64d0bc0SEnrico Granata } 1612d64d0bc0SEnrico Granata } 1613d64d0bc0SEnrico Granata 1614d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1615d64d0bc0SEnrico Granata // type @ location message 1616d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1617d64d0bc0SEnrico Granata { 1618d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1619d64d0bc0SEnrico Granata var_success = true; 162085933ed4SEnrico Granata break; 162185933ed4SEnrico Granata } 162285933ed4SEnrico Granata 1623d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 162486cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 162585933ed4SEnrico Granata { 162685933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 162785933ed4SEnrico Granata var_success = true; 1628f4efecd9SEnrico Granata break; 1629f4efecd9SEnrico Granata } 1630f4efecd9SEnrico Granata 16319fc1944eSEnrico Granata if (!is_array_range) 1632e992a089SEnrico Granata { 1633e992a089SEnrico Granata if (log) 1634d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 16359fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1636e992a089SEnrico Granata } 16379fc1944eSEnrico Granata else 16389fc1944eSEnrico Granata { 1639e992a089SEnrico Granata if (log) 1640d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 16419fc1944eSEnrico Granata if (!is_array && !is_pointer) 16429fc1944eSEnrico Granata break; 1643e992a089SEnrico Granata if (log) 1644d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] handle as array"); 1645fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1646fc7a7f3bSEnrico Granata StreamString special_directions_writer; 16470a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 16480a3958e0SEnrico Granata { 1649fc7a7f3bSEnrico Granata ConstString additional_data; 1650fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1651fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1652fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1653fc7a7f3bSEnrico Granata additional_data.GetCString()); 1654fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 16550a3958e0SEnrico Granata } 16560a3958e0SEnrico Granata 16570a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 16580a3958e0SEnrico Granata s.PutChar('['); 16590a3958e0SEnrico Granata var_success = true; 16600a3958e0SEnrico Granata 16619fc1944eSEnrico Granata if (index_higher < 0) 1662c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 16630a3958e0SEnrico Granata 1664cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 166522c55d18SEnrico Granata 16660a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 16670a3958e0SEnrico Granata { 1668fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 16699fc1944eSEnrico Granata index_lower, 1670c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1671fc7a7f3bSEnrico Granata false).get(); 16720a3958e0SEnrico Granata 1673fc7a7f3bSEnrico Granata if (!item) 1674fc7a7f3bSEnrico Granata { 1675e992a089SEnrico Granata if (log) 1676d01b2953SDaniel Malea log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1677fc7a7f3bSEnrico Granata } 1678fc7a7f3bSEnrico Granata else 1679fc7a7f3bSEnrico Granata { 1680e992a089SEnrico Granata if (log) 1681d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1682fc7a7f3bSEnrico Granata } 1683fc7a7f3bSEnrico Granata 16840a3958e0SEnrico Granata if (!special_directions) 16859fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 16860a3958e0SEnrico Granata else 16870a3958e0SEnrico Granata var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); 16880a3958e0SEnrico Granata 168922c55d18SEnrico Granata if (--max_num_children == 0) 169022c55d18SEnrico Granata { 169122c55d18SEnrico Granata s.PutCString(", ..."); 169222c55d18SEnrico Granata break; 169322c55d18SEnrico Granata } 169422c55d18SEnrico Granata 16950a3958e0SEnrico Granata if (index_lower < index_higher) 16960a3958e0SEnrico Granata s.PutChar(','); 16970a3958e0SEnrico Granata } 16980a3958e0SEnrico Granata s.PutChar(']'); 16994becb37eSEnrico Granata } 17004becb37eSEnrico Granata } 170134132754SGreg Clayton break; 17021b654882SGreg Clayton case 'a': 17031b654882SGreg Clayton if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 17041b654882SGreg Clayton { 17051b654882SGreg Clayton if (addr && addr->IsValid()) 17061b654882SGreg Clayton { 17071b654882SGreg Clayton var_success = true; 17081b654882SGreg Clayton format_addr = *addr; 17091b654882SGreg Clayton } 17101b654882SGreg Clayton } 17115a31471eSGreg Clayton else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0) 17125a31471eSGreg Clayton { 17135a31471eSGreg Clayton var_success = true; 17145a31471eSGreg Clayton var_name_begin += strlen("ansi."); // Skip the "ansi." 17155a31471eSGreg Clayton if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0) 17165a31471eSGreg Clayton { 17175a31471eSGreg Clayton var_name_begin += strlen("fg."); // Skip the "fg." 17185a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 17195a31471eSGreg Clayton { 17205a31471eSGreg Clayton s.Printf ("%s%s%s", 17215a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17225a31471eSGreg Clayton lldb_utility::ansi::k_fg_black, 17235a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17245a31471eSGreg Clayton } 17255a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 17265a31471eSGreg Clayton { 17275a31471eSGreg Clayton s.Printf ("%s%s%s", 17285a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17295a31471eSGreg Clayton lldb_utility::ansi::k_fg_red, 17305a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17315a31471eSGreg Clayton } 17325a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 17335a31471eSGreg Clayton { 17345a31471eSGreg Clayton s.Printf ("%s%s%s", 17355a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17365a31471eSGreg Clayton lldb_utility::ansi::k_fg_green, 17375a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17385a31471eSGreg Clayton } 17395a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 17405a31471eSGreg Clayton { 17415a31471eSGreg Clayton s.Printf ("%s%s%s", 17425a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17435a31471eSGreg Clayton lldb_utility::ansi::k_fg_yellow, 17445a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17455a31471eSGreg Clayton } 17465a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 17475a31471eSGreg Clayton { 17485a31471eSGreg Clayton s.Printf ("%s%s%s", 17495a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17505a31471eSGreg Clayton lldb_utility::ansi::k_fg_blue, 17515a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17525a31471eSGreg Clayton } 17535a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 17545a31471eSGreg Clayton { 17555a31471eSGreg Clayton s.Printf ("%s%s%s", 17565a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17575a31471eSGreg Clayton lldb_utility::ansi::k_fg_purple, 17585a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17595a31471eSGreg Clayton } 17605a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 17615a31471eSGreg Clayton { 17625a31471eSGreg Clayton s.Printf ("%s%s%s", 17635a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17645a31471eSGreg Clayton lldb_utility::ansi::k_fg_cyan, 17655a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17665a31471eSGreg Clayton } 17675a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 17685a31471eSGreg Clayton { 17695a31471eSGreg Clayton s.Printf ("%s%s%s", 17705a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17715a31471eSGreg Clayton lldb_utility::ansi::k_fg_white, 17725a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17735a31471eSGreg Clayton } 17745a31471eSGreg Clayton else 17755a31471eSGreg Clayton { 17765a31471eSGreg Clayton var_success = false; 17775a31471eSGreg Clayton } 17785a31471eSGreg Clayton } 17795a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0) 17805a31471eSGreg Clayton { 17815a31471eSGreg Clayton var_name_begin += strlen("bg."); // Skip the "bg." 17825a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 17835a31471eSGreg Clayton { 17845a31471eSGreg Clayton s.Printf ("%s%s%s", 17855a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17865a31471eSGreg Clayton lldb_utility::ansi::k_bg_black, 17875a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17885a31471eSGreg Clayton } 17895a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 17905a31471eSGreg Clayton { 17915a31471eSGreg Clayton s.Printf ("%s%s%s", 17925a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 17935a31471eSGreg Clayton lldb_utility::ansi::k_bg_red, 17945a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 17955a31471eSGreg Clayton } 17965a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 17975a31471eSGreg Clayton { 17985a31471eSGreg Clayton s.Printf ("%s%s%s", 17995a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18005a31471eSGreg Clayton lldb_utility::ansi::k_bg_green, 18015a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18025a31471eSGreg Clayton } 18035a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 18045a31471eSGreg Clayton { 18055a31471eSGreg Clayton s.Printf ("%s%s%s", 18065a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18075a31471eSGreg Clayton lldb_utility::ansi::k_bg_yellow, 18085a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18095a31471eSGreg Clayton } 18105a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 18115a31471eSGreg Clayton { 18125a31471eSGreg Clayton s.Printf ("%s%s%s", 18135a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18145a31471eSGreg Clayton lldb_utility::ansi::k_bg_blue, 18155a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18165a31471eSGreg Clayton } 18175a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 18185a31471eSGreg Clayton { 18195a31471eSGreg Clayton s.Printf ("%s%s%s", 18205a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18215a31471eSGreg Clayton lldb_utility::ansi::k_bg_purple, 18225a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18235a31471eSGreg Clayton } 18245a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 18255a31471eSGreg Clayton { 18265a31471eSGreg Clayton s.Printf ("%s%s%s", 18275a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18285a31471eSGreg Clayton lldb_utility::ansi::k_bg_cyan, 18295a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18305a31471eSGreg Clayton } 18315a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 18325a31471eSGreg Clayton { 18335a31471eSGreg Clayton s.Printf ("%s%s%s", 18345a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18355a31471eSGreg Clayton lldb_utility::ansi::k_bg_white, 18365a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18375a31471eSGreg Clayton } 18385a31471eSGreg Clayton else 18395a31471eSGreg Clayton { 18405a31471eSGreg Clayton var_success = false; 18415a31471eSGreg Clayton } 18425a31471eSGreg Clayton } 18435a31471eSGreg Clayton else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0) 18445a31471eSGreg Clayton { 18455a31471eSGreg Clayton s.Printf ("%s%s%s", 18465a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18475a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_normal, 18485a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18495a31471eSGreg Clayton } 18505a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0) 18515a31471eSGreg Clayton { 18525a31471eSGreg Clayton s.Printf ("%s%s%s", 18535a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18545a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_bold, 18555a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18565a31471eSGreg Clayton } 18575a31471eSGreg Clayton else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0) 18585a31471eSGreg Clayton { 18595a31471eSGreg Clayton s.Printf ("%s%s%s", 18605a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18615a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_faint, 18625a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18635a31471eSGreg Clayton } 18645a31471eSGreg Clayton else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0) 18655a31471eSGreg Clayton { 18665a31471eSGreg Clayton s.Printf ("%s%s%s", 18675a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18685a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_italic, 18695a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18705a31471eSGreg Clayton } 18715a31471eSGreg Clayton else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0) 18725a31471eSGreg Clayton { 18735a31471eSGreg Clayton s.Printf ("%s%s%s", 18745a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18755a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_underline, 18765a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18775a31471eSGreg Clayton } 18785a31471eSGreg Clayton else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0) 18795a31471eSGreg Clayton { 18805a31471eSGreg Clayton s.Printf ("%s%s%s", 18815a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18825a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_slow_blink, 18835a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18845a31471eSGreg Clayton } 18855a31471eSGreg Clayton else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0) 18865a31471eSGreg Clayton { 18875a31471eSGreg Clayton s.Printf ("%s%s%s", 18885a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18895a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_fast_blink, 18905a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18915a31471eSGreg Clayton } 18925a31471eSGreg Clayton else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0) 18935a31471eSGreg Clayton { 18945a31471eSGreg Clayton s.Printf ("%s%s%s", 18955a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 18965a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_negative, 18975a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 18985a31471eSGreg Clayton } 18995a31471eSGreg Clayton else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0) 19005a31471eSGreg Clayton { 19015a31471eSGreg Clayton s.Printf ("%s%s%s", 19025a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 19035a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_conceal, 19045a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 19055a31471eSGreg Clayton 19065a31471eSGreg Clayton } 19075a31471eSGreg Clayton else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0) 19085a31471eSGreg Clayton { 19095a31471eSGreg Clayton s.Printf ("%s%s%s", 19105a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 19115a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_crossed_out, 19125a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 19135a31471eSGreg Clayton } 19145a31471eSGreg Clayton else 19155a31471eSGreg Clayton { 19165a31471eSGreg Clayton var_success = false; 19175a31471eSGreg Clayton } 19185a31471eSGreg Clayton } 19191b654882SGreg Clayton break; 19201b654882SGreg Clayton 19211b654882SGreg Clayton case 'p': 19221b654882SGreg Clayton if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 19231b654882SGreg Clayton { 1924c14ee32dSGreg Clayton if (exe_ctx) 1925c14ee32dSGreg Clayton { 1926c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 1927c14ee32dSGreg Clayton if (process) 19281b654882SGreg Clayton { 19291b654882SGreg Clayton var_name_begin += ::strlen ("process."); 19301b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 19311b654882SGreg Clayton { 1932d01b2953SDaniel Malea s.Printf("%" PRIu64, process->GetID()); 19331b654882SGreg Clayton var_success = true; 19341b654882SGreg Clayton } 19351b654882SGreg Clayton else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 19361b654882SGreg Clayton (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 19371b654882SGreg Clayton (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 19381b654882SGreg Clayton { 1939c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1940aa149cbdSGreg Clayton if (exe_module) 19411b654882SGreg Clayton { 19421b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 19431b654882SGreg Clayton { 1944aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 19451b654882SGreg Clayton var_success = format_file_spec; 19461b654882SGreg Clayton } 19471b654882SGreg Clayton else 19481b654882SGreg Clayton { 1949aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 19501b654882SGreg Clayton var_success = format_file_spec; 19511b654882SGreg Clayton } 19521b654882SGreg Clayton } 19531b654882SGreg Clayton } 19541b654882SGreg Clayton } 19551b654882SGreg Clayton } 1956c14ee32dSGreg Clayton } 19571b654882SGreg Clayton break; 19581b654882SGreg Clayton 19591b654882SGreg Clayton case 't': 19601b654882SGreg Clayton if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 19611b654882SGreg Clayton { 1962c14ee32dSGreg Clayton if (exe_ctx) 1963c14ee32dSGreg Clayton { 1964c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 1965c14ee32dSGreg Clayton if (thread) 19661b654882SGreg Clayton { 19671b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 19681b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 19691b654882SGreg Clayton { 1970d01b2953SDaniel Malea s.Printf("0x%4.4" PRIx64, thread->GetID()); 19711b654882SGreg Clayton var_success = true; 19721b654882SGreg Clayton } 1973160c9d81SGreg Clayton else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0) 1974160c9d81SGreg Clayton { 1975160c9d81SGreg Clayton s.Printf("0x%4.4" PRIx64, thread->GetProtocolID()); 1976160c9d81SGreg Clayton var_success = true; 1977160c9d81SGreg Clayton } 19781b654882SGreg Clayton else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 19791b654882SGreg Clayton { 1980c14ee32dSGreg Clayton s.Printf("%u", thread->GetIndexID()); 19811b654882SGreg Clayton var_success = true; 19821b654882SGreg Clayton } 19831b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 19841b654882SGreg Clayton { 1985c14ee32dSGreg Clayton cstr = thread->GetName(); 19861b654882SGreg Clayton var_success = cstr && cstr[0]; 19871b654882SGreg Clayton if (var_success) 19881b654882SGreg Clayton s.PutCString(cstr); 19891b654882SGreg Clayton } 19901b654882SGreg Clayton else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 19911b654882SGreg Clayton { 1992c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 19931b654882SGreg Clayton var_success = cstr && cstr[0]; 19941b654882SGreg Clayton if (var_success) 19951b654882SGreg Clayton s.PutCString(cstr); 19961b654882SGreg Clayton } 19971b654882SGreg Clayton else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 19981b654882SGreg Clayton { 1999c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 20005d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 20011b654882SGreg Clayton { 2002b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 20031b654882SGreg Clayton if (cstr && cstr[0]) 20041b654882SGreg Clayton { 20051b654882SGreg Clayton s.PutCString(cstr); 20061b654882SGreg Clayton var_success = true; 20071b654882SGreg Clayton } 20081b654882SGreg Clayton } 20091b654882SGreg Clayton } 201073ca05a2SJim Ingham else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0) 201173ca05a2SJim Ingham { 201273ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 20135d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 201473ca05a2SJim Ingham { 201573ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 201673ca05a2SJim Ingham if (return_valobj_sp) 201773ca05a2SJim Ingham { 20189fb5ab55SEnrico Granata ValueObject::DumpValueObject (s, return_valobj_sp.get()); 201973ca05a2SJim Ingham var_success = true; 202073ca05a2SJim Ingham } 202173ca05a2SJim Ingham } 202273ca05a2SJim Ingham } 202373ca05a2SJim Ingham } 20241b654882SGreg Clayton } 20251b654882SGreg Clayton } 20261b654882SGreg Clayton else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 20271b654882SGreg Clayton { 202867cc0636SGreg Clayton // TODO: hookup properties 202967cc0636SGreg Clayton // if (!target_properties_sp) 203067cc0636SGreg Clayton // { 203167cc0636SGreg Clayton // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 203267cc0636SGreg Clayton // if (target) 203367cc0636SGreg Clayton // target_properties_sp = target->GetProperties(); 203467cc0636SGreg Clayton // } 203567cc0636SGreg Clayton // 203667cc0636SGreg Clayton // if (target_properties_sp) 203767cc0636SGreg Clayton // { 203867cc0636SGreg Clayton // var_name_begin += ::strlen ("target."); 203967cc0636SGreg Clayton // const char *end_property = strchr(var_name_begin, '}'); 204067cc0636SGreg Clayton // if (end_property) 204167cc0636SGreg Clayton // { 204267cc0636SGreg Clayton // ConstString property_name(var_name_begin, end_property - var_name_begin); 204367cc0636SGreg Clayton // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 204467cc0636SGreg Clayton // if (!property_value.empty()) 204567cc0636SGreg Clayton // { 204667cc0636SGreg Clayton // s.PutCString (property_value.c_str()); 204767cc0636SGreg Clayton // var_success = true; 204867cc0636SGreg Clayton // } 204967cc0636SGreg Clayton // } 205067cc0636SGreg Clayton // } 20510603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 20520603aa9dSGreg Clayton if (target) 20531b654882SGreg Clayton { 20541b654882SGreg Clayton var_name_begin += ::strlen ("target."); 20551b654882SGreg Clayton if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 20561b654882SGreg Clayton { 20571b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 20581b654882SGreg Clayton if (arch.IsValid()) 20591b654882SGreg Clayton { 206064195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 20611b654882SGreg Clayton var_success = true; 20621b654882SGreg Clayton } 20631b654882SGreg Clayton } 20641b654882SGreg Clayton } 20651b654882SGreg Clayton } 20661b654882SGreg Clayton break; 20671b654882SGreg Clayton 20681b654882SGreg Clayton 20691b654882SGreg Clayton case 'm': 20701b654882SGreg Clayton if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 20711b654882SGreg Clayton { 20720603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 20731b654882SGreg Clayton { 20740603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 20751b654882SGreg Clayton var_name_begin += ::strlen ("module."); 20761b654882SGreg Clayton 20771b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 20781b654882SGreg Clayton { 20791b654882SGreg Clayton if (module->GetFileSpec()) 20801b654882SGreg Clayton { 20811b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20821b654882SGreg Clayton 20831b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 20841b654882SGreg Clayton { 20851b654882SGreg Clayton format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 20861b654882SGreg Clayton var_success = format_file_spec; 20871b654882SGreg Clayton } 20881b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 20891b654882SGreg Clayton { 20901b654882SGreg Clayton format_file_spec = module->GetFileSpec(); 20911b654882SGreg Clayton var_success = format_file_spec; 20921b654882SGreg Clayton } 20931b654882SGreg Clayton } 20941b654882SGreg Clayton } 20951b654882SGreg Clayton } 20961b654882SGreg Clayton } 20971b654882SGreg Clayton break; 20981b654882SGreg Clayton 20991b654882SGreg Clayton 21001b654882SGreg Clayton case 'f': 21011b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 21021b654882SGreg Clayton { 21031b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 21041b654882SGreg Clayton { 21051b654882SGreg Clayton var_name_begin += ::strlen ("file."); 21061b654882SGreg Clayton 21071b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 21081b654882SGreg Clayton { 21091b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 21101b654882SGreg Clayton var_success = format_file_spec; 21111b654882SGreg Clayton } 21121b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 21131b654882SGreg Clayton { 21141b654882SGreg Clayton format_file_spec = *sc->comp_unit; 21151b654882SGreg Clayton var_success = format_file_spec; 21161b654882SGreg Clayton } 21171b654882SGreg Clayton } 21181b654882SGreg Clayton } 21191b654882SGreg Clayton else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 21201b654882SGreg Clayton { 2121c14ee32dSGreg Clayton if (exe_ctx) 2122c14ee32dSGreg Clayton { 2123c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2124c14ee32dSGreg Clayton if (frame) 21251b654882SGreg Clayton { 21261b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 21271b654882SGreg Clayton if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 21281b654882SGreg Clayton { 2129c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 21301b654882SGreg Clayton var_success = true; 21311b654882SGreg Clayton } 21321b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 21331b654882SGreg Clayton { 21341b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21351b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 21361b654882SGreg Clayton var_success = true; 21371b654882SGreg Clayton } 21381b654882SGreg Clayton else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 21391b654882SGreg Clayton { 21401b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21411b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 21421b654882SGreg Clayton var_success = true; 21431b654882SGreg Clayton } 21441b654882SGreg Clayton else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 21451b654882SGreg Clayton { 21461b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21471b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 21481b654882SGreg Clayton var_success = true; 21491b654882SGreg Clayton } 21501b654882SGreg Clayton else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 21511b654882SGreg Clayton { 21521b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21531b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 21541b654882SGreg Clayton var_success = true; 21551b654882SGreg Clayton } 21561b654882SGreg Clayton else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 21571b654882SGreg Clayton { 2158c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 21591b654882SGreg Clayton if (reg_ctx) 21601b654882SGreg Clayton { 21611b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 21621b654882SGreg Clayton if (var_name_begin < var_name_end) 21631b654882SGreg Clayton { 21641b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 21651b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 21661b654882SGreg Clayton if (reg_info) 21671b654882SGreg Clayton var_success = true; 21681b654882SGreg Clayton } 21691b654882SGreg Clayton } 21701b654882SGreg Clayton } 21711b654882SGreg Clayton } 21721b654882SGreg Clayton } 2173c14ee32dSGreg Clayton } 21741b654882SGreg Clayton else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 21751b654882SGreg Clayton { 21761b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 21771b654882SGreg Clayton { 21781b654882SGreg Clayton var_name_begin += ::strlen ("function."); 21791b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 21801b654882SGreg Clayton { 21811b654882SGreg Clayton if (sc->function) 2182d01b2953SDaniel Malea s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 21831b654882SGreg Clayton else 21841b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 21851b654882SGreg Clayton 21861b654882SGreg Clayton var_success = true; 21871b654882SGreg Clayton } 21881b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 21891b654882SGreg Clayton { 21901b654882SGreg Clayton if (sc->function) 21911b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21921b654882SGreg Clayton else if (sc->symbol) 21931b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 21941b654882SGreg Clayton if (cstr) 21951b654882SGreg Clayton { 21961b654882SGreg Clayton s.PutCString(cstr); 21970d9c9934SGreg Clayton 21980d9c9934SGreg Clayton if (sc->block) 21990d9c9934SGreg Clayton { 22000d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 22010d9c9934SGreg Clayton if (inline_block) 22020d9c9934SGreg Clayton { 22030d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 22040d9c9934SGreg Clayton if (inline_info) 22050d9c9934SGreg Clayton { 22060d9c9934SGreg Clayton s.PutCString(" [inlined] "); 22070d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 22080d9c9934SGreg Clayton } 22090d9c9934SGreg Clayton } 22100d9c9934SGreg Clayton } 22111b654882SGreg Clayton var_success = true; 22121b654882SGreg Clayton } 22131b654882SGreg Clayton } 22146d3dbf51SGreg Clayton else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0) 22156d3dbf51SGreg Clayton { 22166d3dbf51SGreg Clayton // Print the function name with arguments in it 22176d3dbf51SGreg Clayton 22186d3dbf51SGreg Clayton if (sc->function) 22196d3dbf51SGreg Clayton { 22206d3dbf51SGreg Clayton var_success = true; 22216d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 22226d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 22236d3dbf51SGreg Clayton if (cstr) 22246d3dbf51SGreg Clayton { 22256d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 22266d3dbf51SGreg Clayton VariableListSP variable_list_sp; 22276d3dbf51SGreg Clayton bool get_function_vars = true; 22286d3dbf51SGreg Clayton if (sc->block) 22296d3dbf51SGreg Clayton { 22306d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 22316d3dbf51SGreg Clayton 22326d3dbf51SGreg Clayton if (inline_block) 22336d3dbf51SGreg Clayton { 22346d3dbf51SGreg Clayton get_function_vars = false; 22356d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 22366d3dbf51SGreg Clayton if (inline_info) 22376d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 22386d3dbf51SGreg Clayton } 22396d3dbf51SGreg Clayton } 22406d3dbf51SGreg Clayton 22416d3dbf51SGreg Clayton if (get_function_vars) 22426d3dbf51SGreg Clayton { 22436d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 22446d3dbf51SGreg Clayton } 22456d3dbf51SGreg Clayton 22466d3dbf51SGreg Clayton if (inline_info) 22476d3dbf51SGreg Clayton { 22486d3dbf51SGreg Clayton s.PutCString (cstr); 22496d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 22506d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 22516d3dbf51SGreg Clayton } 22526d3dbf51SGreg Clayton 22536d3dbf51SGreg Clayton VariableList args; 22546d3dbf51SGreg Clayton if (variable_list_sp) 2255cc7f9bf5SEnrico Granata variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 22566d3dbf51SGreg Clayton if (args.GetSize() > 0) 22576d3dbf51SGreg Clayton { 22586d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 22596d3dbf51SGreg Clayton const char *close_paren = NULL; 22606d3dbf51SGreg Clayton if (open_paren) 2261855958caSGreg Clayton { 2262855958caSGreg Clayton if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0) 2263855958caSGreg Clayton { 2264855958caSGreg Clayton open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2265855958caSGreg Clayton if (open_paren) 22666d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 2267855958caSGreg Clayton } 2268855958caSGreg Clayton else 2269855958caSGreg Clayton close_paren = strchr (open_paren, ')'); 2270855958caSGreg Clayton } 22716d3dbf51SGreg Clayton 22726d3dbf51SGreg Clayton if (open_paren) 22736d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 22746d3dbf51SGreg Clayton else 22756d3dbf51SGreg Clayton { 22766d3dbf51SGreg Clayton s.PutCString (cstr); 22776d3dbf51SGreg Clayton s.PutChar ('('); 22786d3dbf51SGreg Clayton } 22795b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 22806d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 22816d3dbf51SGreg Clayton { 22826d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 22836d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 22846d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 22856d3dbf51SGreg Clayton const char *var_value = var_value_sp->GetValueAsCString(); 22866d3dbf51SGreg Clayton if (arg_idx > 0) 22876d3dbf51SGreg Clayton s.PutCString (", "); 22883b188b17SGreg Clayton if (var_value_sp->GetError().Success()) 2289cc7f9bf5SEnrico Granata { 2290cc7f9bf5SEnrico Granata if (var_value) 22916d3dbf51SGreg Clayton s.Printf ("%s=%s", var_name, var_value); 22923b188b17SGreg Clayton else 2293cc7f9bf5SEnrico Granata s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2294cc7f9bf5SEnrico Granata } 2295cc7f9bf5SEnrico Granata else 22963b188b17SGreg Clayton s.Printf ("%s=<unavailable>", var_name); 22976d3dbf51SGreg Clayton } 22986d3dbf51SGreg Clayton 22996d3dbf51SGreg Clayton if (close_paren) 23006d3dbf51SGreg Clayton s.PutCString (close_paren); 23016d3dbf51SGreg Clayton else 23026d3dbf51SGreg Clayton s.PutChar(')'); 23036d3dbf51SGreg Clayton 23046d3dbf51SGreg Clayton } 23056d3dbf51SGreg Clayton else 23066d3dbf51SGreg Clayton { 23076d3dbf51SGreg Clayton s.PutCString(cstr); 23086d3dbf51SGreg Clayton } 23096d3dbf51SGreg Clayton } 23106d3dbf51SGreg Clayton } 23116d3dbf51SGreg Clayton else if (sc->symbol) 23126d3dbf51SGreg Clayton { 23136d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 23146d3dbf51SGreg Clayton if (cstr) 23156d3dbf51SGreg Clayton { 23166d3dbf51SGreg Clayton s.PutCString(cstr); 23176d3dbf51SGreg Clayton var_success = true; 23186d3dbf51SGreg Clayton } 23196d3dbf51SGreg Clayton } 23206d3dbf51SGreg Clayton } 23211b654882SGreg Clayton else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 23221b654882SGreg Clayton { 23231b654882SGreg Clayton var_success = addr != NULL; 23241b654882SGreg Clayton if (var_success) 23251b654882SGreg Clayton { 23261b654882SGreg Clayton format_addr = *addr; 23271b654882SGreg Clayton calculate_format_addr_function_offset = true; 23281b654882SGreg Clayton } 23291b654882SGreg Clayton } 23301b654882SGreg Clayton else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 23311b654882SGreg Clayton { 23321b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 23331b654882SGreg Clayton if (var_success) 23341b654882SGreg Clayton { 23351b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23361b654882SGreg Clayton calculate_format_addr_function_offset = true; 23371b654882SGreg Clayton } 23381b654882SGreg Clayton } 23391b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 23401b654882SGreg Clayton { 2341c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2342c14ee32dSGreg Clayton var_success = frame != NULL; 23431b654882SGreg Clayton if (var_success) 23441b654882SGreg Clayton { 2345c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23461b654882SGreg Clayton calculate_format_addr_function_offset = true; 23471b654882SGreg Clayton } 23481b654882SGreg Clayton } 23491b654882SGreg Clayton } 23501b654882SGreg Clayton } 23511b654882SGreg Clayton break; 23521b654882SGreg Clayton 23531b654882SGreg Clayton case 'l': 23541b654882SGreg Clayton if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 23551b654882SGreg Clayton { 23561b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 23571b654882SGreg Clayton { 23581b654882SGreg Clayton var_name_begin += ::strlen ("line."); 23591b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 23601b654882SGreg Clayton { 23611b654882SGreg Clayton var_name_begin += ::strlen ("file."); 23621b654882SGreg Clayton 23631b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 23641b654882SGreg Clayton { 23651b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 23661b654882SGreg Clayton var_success = format_file_spec; 23671b654882SGreg Clayton } 23681b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 23691b654882SGreg Clayton { 23701b654882SGreg Clayton format_file_spec = sc->line_entry.file; 23711b654882SGreg Clayton var_success = format_file_spec; 23721b654882SGreg Clayton } 23731b654882SGreg Clayton } 23741b654882SGreg Clayton else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 23751b654882SGreg Clayton { 23761b654882SGreg Clayton var_success = true; 23771b654882SGreg Clayton s.Printf("%u", sc->line_entry.line); 23781b654882SGreg Clayton } 23791b654882SGreg Clayton else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 23801b654882SGreg Clayton (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 23811b654882SGreg Clayton { 23821b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 23831b654882SGreg Clayton if (var_success) 23841b654882SGreg Clayton { 23851b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23861b654882SGreg Clayton if (var_name_begin[0] == 'e') 23871b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 23881b654882SGreg Clayton } 23891b654882SGreg Clayton } 23901b654882SGreg Clayton } 23911b654882SGreg Clayton } 23921b654882SGreg Clayton break; 23931b654882SGreg Clayton } 23941b654882SGreg Clayton 23951b654882SGreg Clayton if (var_success) 23961b654882SGreg Clayton { 23971b654882SGreg Clayton // If format addr is valid, then we need to print an address 23981b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 23991b654882SGreg Clayton { 2400c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 24011b654882SGreg Clayton // We have a register value to display... 24021b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 24031b654882SGreg Clayton { 2404c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 24051b654882SGreg Clayton } 24061b654882SGreg Clayton else 24071b654882SGreg Clayton { 24081b654882SGreg Clayton if (reg_ctx == NULL) 2409c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 24101b654882SGreg Clayton 24111b654882SGreg Clayton if (reg_ctx) 24121b654882SGreg Clayton { 24131b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 24141b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 24151b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 24161b654882SGreg Clayton var_success = reg_info != NULL; 24171b654882SGreg Clayton } 24181b654882SGreg Clayton } 24191b654882SGreg Clayton } 24201b654882SGreg Clayton 24211b654882SGreg Clayton if (reg_info != NULL) 24221b654882SGreg Clayton { 24237349bd90SGreg Clayton RegisterValue reg_value; 24247349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 24257349bd90SGreg Clayton if (var_success) 24261b654882SGreg Clayton { 24279a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 24281b654882SGreg Clayton } 24291b654882SGreg Clayton } 24301b654882SGreg Clayton 24311b654882SGreg Clayton if (format_file_spec) 24321b654882SGreg Clayton { 24331b654882SGreg Clayton s << format_file_spec; 24341b654882SGreg Clayton } 24351b654882SGreg Clayton 24361b654882SGreg Clayton // If format addr is valid, then we need to print an address 24371b654882SGreg Clayton if (format_addr.IsValid()) 24381b654882SGreg Clayton { 24390603aa9dSGreg Clayton var_success = false; 24400603aa9dSGreg Clayton 24411b654882SGreg Clayton if (calculate_format_addr_function_offset) 24421b654882SGreg Clayton { 24431b654882SGreg Clayton Address func_addr; 24440603aa9dSGreg Clayton 24450603aa9dSGreg Clayton if (sc) 24460603aa9dSGreg Clayton { 24471b654882SGreg Clayton if (sc->function) 24480d9c9934SGreg Clayton { 24491b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 24500d9c9934SGreg Clayton if (sc->block) 24510d9c9934SGreg Clayton { 24520d9c9934SGreg Clayton // Check to make sure we aren't in an inline 24530d9c9934SGreg Clayton // function. If we are, use the inline block 24540d9c9934SGreg Clayton // range that contains "format_addr" since 24550d9c9934SGreg Clayton // blocks can be discontiguous. 24560d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 24570d9c9934SGreg Clayton AddressRange inline_range; 24580d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 24590d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 24600d9c9934SGreg Clayton } 24610d9c9934SGreg Clayton } 2462e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2463e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 24640603aa9dSGreg Clayton } 24651b654882SGreg Clayton 24660603aa9dSGreg Clayton if (func_addr.IsValid()) 24671b654882SGreg Clayton { 24681b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 24691b654882SGreg Clayton { 24701b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 24711b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 24721b654882SGreg Clayton if (addr_file_addr > func_file_addr) 2473d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 24741b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 2475d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 24760603aa9dSGreg Clayton var_success = true; 24771b654882SGreg Clayton } 24781b654882SGreg Clayton else 24790603aa9dSGreg Clayton { 24800603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24810603aa9dSGreg Clayton if (target) 24820603aa9dSGreg Clayton { 24830603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 24840603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 24850603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 2486d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 24870603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 2488d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 24890603aa9dSGreg Clayton var_success = true; 24900603aa9dSGreg Clayton } 24910603aa9dSGreg Clayton } 24921b654882SGreg Clayton } 24931b654882SGreg Clayton } 24941b654882SGreg Clayton else 24951b654882SGreg Clayton { 24960603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24971b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 24980603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 24990603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 25001b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 25011b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 25021b654882SGreg Clayton 25031b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 25040603aa9dSGreg Clayton { 2505514487e8SGreg Clayton int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 250635f1a0d5SGreg Clayton if (addr_width == 0) 250735f1a0d5SGreg Clayton addr_width = 16; 2508d01b2953SDaniel Malea s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 25090603aa9dSGreg Clayton var_success = true; 25100603aa9dSGreg Clayton } 25111b654882SGreg Clayton } 25121b654882SGreg Clayton } 25131b654882SGreg Clayton } 25141b654882SGreg Clayton 25151b654882SGreg Clayton if (var_success == false) 25161b654882SGreg Clayton success = false; 25171b654882SGreg Clayton } 25181b654882SGreg Clayton p = var_name_end; 25191b654882SGreg Clayton } 25201b654882SGreg Clayton else 25211b654882SGreg Clayton break; 25221b654882SGreg Clayton } 25231b654882SGreg Clayton else 25241b654882SGreg Clayton { 25251b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 25261b654882SGreg Clayton s.PutChar(*p); 25271b654882SGreg Clayton } 25281b654882SGreg Clayton } 25291b654882SGreg Clayton else if (*p == '\\') 25301b654882SGreg Clayton { 25311b654882SGreg Clayton ++p; // skip the slash 25321b654882SGreg Clayton switch (*p) 25331b654882SGreg Clayton { 25341b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 25351b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 25361b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 25371b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 25381b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 25391b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 25401b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 25411b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 25421b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 25431b654882SGreg Clayton case '0': 25441b654882SGreg Clayton // 1 to 3 octal chars 25451b654882SGreg Clayton { 25460603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 25470603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 25480603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 25490603aa9dSGreg Clayton 25500603aa9dSGreg Clayton int i; 25510603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 25520603aa9dSGreg Clayton oct_str[i] = p[i]; 25530603aa9dSGreg Clayton 25540603aa9dSGreg Clayton // We don't want to consume the last octal character since 25550603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 25560603aa9dSGreg Clayton // one less than i (even if i is zero) 25570603aa9dSGreg Clayton p += i - 1; 25580603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 25590603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 25601b654882SGreg Clayton { 2561c7bece56SGreg Clayton s.PutChar((char)octal_value); 25621b654882SGreg Clayton } 25631b654882SGreg Clayton } 25641b654882SGreg Clayton break; 25651b654882SGreg Clayton 25661b654882SGreg Clayton case 'x': 25671b654882SGreg Clayton // hex number in the format 25680603aa9dSGreg Clayton if (isxdigit(p[1])) 25691b654882SGreg Clayton { 25700603aa9dSGreg Clayton ++p; // Skip the 'x' 25711b654882SGreg Clayton 25720603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 25730603aa9dSGreg Clayton // NULL terminator 25741b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 25751b654882SGreg Clayton hex_str[0] = *p; 25760603aa9dSGreg Clayton if (isxdigit(p[1])) 25770603aa9dSGreg Clayton { 25780603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 25791b654882SGreg Clayton hex_str[1] = *p; 25800603aa9dSGreg Clayton } 25810603aa9dSGreg Clayton 25821b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 25830603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 2584c7bece56SGreg Clayton s.PutChar ((char)hex_value); 25851b654882SGreg Clayton } 25861b654882SGreg Clayton else 25871b654882SGreg Clayton { 25880603aa9dSGreg Clayton s.PutChar('x'); 25891b654882SGreg Clayton } 25901b654882SGreg Clayton break; 25911b654882SGreg Clayton 25921b654882SGreg Clayton default: 25930603aa9dSGreg Clayton // Just desensitize any other character by just printing what 25940603aa9dSGreg Clayton // came after the '\' 25950603aa9dSGreg Clayton s << *p; 25961b654882SGreg Clayton break; 25971b654882SGreg Clayton 25981b654882SGreg Clayton } 25991b654882SGreg Clayton 26001b654882SGreg Clayton } 26011b654882SGreg Clayton } 26021b654882SGreg Clayton if (end) 26031b654882SGreg Clayton *end = p; 26041b654882SGreg Clayton return success; 26051b654882SGreg Clayton } 26061b654882SGreg Clayton 2607228063cdSJim Ingham void 2608228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2609228063cdSJim Ingham { 26104f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 26114f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 26124f02b22dSJim Ingham // callback. 2613228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2614228063cdSJim Ingham } 2615228063cdSJim Ingham 2616228063cdSJim Ingham bool 2617228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2618228063cdSJim Ingham { 2619228063cdSJim Ingham Log::Callbacks log_callbacks; 2620228063cdSJim Ingham 2621228063cdSJim Ingham StreamSP log_stream_sp; 26229a028519SSean Callanan if (m_log_callback_stream_sp) 2623228063cdSJim Ingham { 2624228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2625228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2626228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2627228063cdSJim Ingham } 2628228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2629228063cdSJim Ingham { 2630228063cdSJim Ingham log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false)); 2631228063cdSJim Ingham } 2632228063cdSJim Ingham else 2633228063cdSJim Ingham { 2634228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2635c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 2636c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 2637c1b2ccfdSGreg Clayton if (!log_stream_sp) 2638228063cdSJim Ingham { 2639228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2640228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2641228063cdSJim Ingham } 2642228063cdSJim Ingham } 2643228063cdSJim Ingham assert (log_stream_sp.get()); 2644228063cdSJim Ingham 2645228063cdSJim Ingham if (log_options == 0) 2646228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2647228063cdSJim Ingham 264857abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 2649228063cdSJim Ingham { 2650228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2651228063cdSJim Ingham return true; 2652228063cdSJim Ingham } 2653228063cdSJim Ingham else 2654228063cdSJim Ingham { 2655228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2656228063cdSJim Ingham if (log_channel_sp) 2657228063cdSJim Ingham { 2658228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2659228063cdSJim Ingham { 2660228063cdSJim Ingham return true; 2661228063cdSJim Ingham } 2662228063cdSJim Ingham else 2663228063cdSJim Ingham { 2664228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2665228063cdSJim Ingham return false; 2666228063cdSJim Ingham } 2667228063cdSJim Ingham } 2668228063cdSJim Ingham else 2669228063cdSJim Ingham { 2670228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2671228063cdSJim Ingham return false; 2672228063cdSJim Ingham } 2673228063cdSJim Ingham } 2674228063cdSJim Ingham return false; 2675228063cdSJim Ingham } 2676228063cdSJim Ingham 26779585fbfcSGreg Clayton SourceManager & 26789585fbfcSGreg Clayton Debugger::GetSourceManager () 26799585fbfcSGreg Clayton { 26809585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 26819585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 26829585fbfcSGreg Clayton return *m_source_manager_ap; 26839585fbfcSGreg Clayton } 26849585fbfcSGreg Clayton 26859585fbfcSGreg Clayton 2686