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" 5084a53dfbSEnrico Granata #include "lldb/Target/Target.h" 5130fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 525a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h" 5330fdc8d8SChris Lattner 5430fdc8d8SChris Lattner using namespace lldb; 5530fdc8d8SChris Lattner using namespace lldb_private; 5630fdc8d8SChris Lattner 5730fdc8d8SChris Lattner 581b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0; 59ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1; 60ebc1bb27SCaroline Tice 611b654882SGreg Clayton #pragma mark Static Functions 621b654882SGreg Clayton 631b654882SGreg Clayton static Mutex & 641b654882SGreg Clayton GetDebuggerListMutex () 651b654882SGreg Clayton { 661b654882SGreg Clayton static Mutex g_mutex(Mutex::eMutexTypeRecursive); 671b654882SGreg Clayton return g_mutex; 681b654882SGreg Clayton } 691b654882SGreg Clayton 701b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList; 711b654882SGreg Clayton 721b654882SGreg Clayton static DebuggerList & 731b654882SGreg Clayton GetDebuggerList() 741b654882SGreg Clayton { 751b654882SGreg Clayton // hide the static debugger list inside a singleton accessor to avoid 761b654882SGreg Clayton // global init contructors 771b654882SGreg Clayton static DebuggerList g_list; 781b654882SGreg Clayton return g_list; 791b654882SGreg Clayton } 80e372b98dSGreg Clayton 81e372b98dSGreg Clayton OptionEnumValueElement 8267cc0636SGreg Clayton g_show_disassembly_enum_values[] = 83e372b98dSGreg Clayton { 8467cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, 8567cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, 8667cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, 87e372b98dSGreg Clayton { 0, NULL, NULL } 88e372b98dSGreg Clayton }; 89e372b98dSGreg Clayton 9067cc0636SGreg Clayton OptionEnumValueElement 9167cc0636SGreg Clayton g_language_enumerators[] = 9267cc0636SGreg Clayton { 9367cc0636SGreg Clayton { eScriptLanguageNone, "none", "Disable scripting languages."}, 9467cc0636SGreg Clayton { eScriptLanguagePython, "python", "Select python as the default scripting language."}, 9567cc0636SGreg Clayton { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."}, 96a12993c9SGreg Clayton { 0, NULL, NULL } 9767cc0636SGreg Clayton }; 98e372b98dSGreg Clayton 9967cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" 10067cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 10167cc0636SGreg Clayton 102*0769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ 10367cc0636SGreg Clayton "{, ${frame.pc}}"\ 10467cc0636SGreg Clayton MODULE_WITH_FUNC\ 10567cc0636SGreg Clayton FILE_AND_LINE\ 106*0769b2b1SMichael Sartain "{, name = '${thread.name}'}"\ 107*0769b2b1SMichael Sartain "{, queue = '${thread.queue}'}"\ 10867cc0636SGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 10967cc0636SGreg Clayton "{\\nReturn value: ${thread.return-value}}"\ 11067cc0636SGreg Clayton "\\n" 11167cc0636SGreg Clayton 11267cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 11367cc0636SGreg Clayton MODULE_WITH_FUNC\ 11467cc0636SGreg Clayton FILE_AND_LINE\ 11567cc0636SGreg Clayton "\\n" 11667cc0636SGreg Clayton 11767cc0636SGreg Clayton 11867cc0636SGreg Clayton 119754a9369SGreg Clayton static PropertyDefinition 120754a9369SGreg Clayton g_properties[] = 12167cc0636SGreg Clayton { 12267cc0636SGreg Clayton { "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, 12367cc0636SGreg 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." }, 12467cc0636SGreg Clayton { "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, 1254c05410fSGreg Clayton { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 12667cc0636SGreg Clayton { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 12767cc0636SGreg Clayton { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, 12867cc0636SGreg 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." }, 12967cc0636SGreg 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." }, 13067cc0636SGreg 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." }, 13167cc0636SGreg Clayton { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, 13267cc0636SGreg Clayton { "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." }, 13367cc0636SGreg Clayton { "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." }, 134c3ce7f27SMichael Sartain { "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." }, 135e8cd0c98SGreg Clayton 13667cc0636SGreg Clayton { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 13767cc0636SGreg Clayton }; 13867cc0636SGreg Clayton 13967cc0636SGreg Clayton enum 14067cc0636SGreg Clayton { 14167cc0636SGreg Clayton ePropertyAutoConfirm = 0, 14267cc0636SGreg Clayton ePropertyFrameFormat, 14367cc0636SGreg Clayton ePropertyNotiftVoid, 14467cc0636SGreg Clayton ePropertyPrompt, 14567cc0636SGreg Clayton ePropertyScriptLanguage, 14667cc0636SGreg Clayton ePropertyStopDisassemblyCount, 14767cc0636SGreg Clayton ePropertyStopDisassemblyDisplay, 14867cc0636SGreg Clayton ePropertyStopLineCountAfter, 14967cc0636SGreg Clayton ePropertyStopLineCountBefore, 15067cc0636SGreg Clayton ePropertyTerminalWidth, 15167cc0636SGreg Clayton ePropertyThreadFormat, 152c3ce7f27SMichael Sartain ePropertyUseExternalEditor, 153c3ce7f27SMichael Sartain ePropertyUseColor, 15467cc0636SGreg Clayton }; 15567cc0636SGreg Clayton 15667cc0636SGreg Clayton // 15767cc0636SGreg Clayton //const char * 15867cc0636SGreg Clayton //Debugger::GetFrameFormat() const 15967cc0636SGreg Clayton //{ 16067cc0636SGreg Clayton // return m_properties_sp->GetFrameFormat(); 16167cc0636SGreg Clayton //} 16267cc0636SGreg Clayton //const char * 16367cc0636SGreg Clayton //Debugger::GetThreadFormat() const 16467cc0636SGreg Clayton //{ 16567cc0636SGreg Clayton // return m_properties_sp->GetThreadFormat(); 16667cc0636SGreg Clayton //} 16767cc0636SGreg Clayton // 1684c05410fSGreg Clayton 1694c05410fSGreg Clayton 1704c05410fSGreg Clayton Error 1714c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 1724c05410fSGreg Clayton VarSetOperationType op, 1734c05410fSGreg Clayton const char *property_path, 1744c05410fSGreg Clayton const char *value) 1754c05410fSGreg Clayton { 17684a53dfbSEnrico Granata bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0; 17784a53dfbSEnrico Granata TargetSP target_sp; 178397ddd5fSEnrico Granata LoadScriptFromSymFile load_script_old_value; 17984a53dfbSEnrico Granata if (is_load_script && exe_ctx->GetTargetSP()) 18084a53dfbSEnrico Granata { 18184a53dfbSEnrico Granata target_sp = exe_ctx->GetTargetSP(); 18284a53dfbSEnrico Granata load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 18384a53dfbSEnrico Granata } 1844c05410fSGreg Clayton Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 1854c05410fSGreg Clayton if (error.Success()) 1864c05410fSGreg Clayton { 18784a53dfbSEnrico Granata // FIXME it would be nice to have "on-change" callbacks for properties 1884c05410fSGreg Clayton if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 1894c05410fSGreg Clayton { 1904c05410fSGreg Clayton const char *new_prompt = GetPrompt(); 191c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 192c3ce7f27SMichael Sartain if (str.length()) 193c3ce7f27SMichael Sartain new_prompt = str.c_str(); 1944c05410fSGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 1954c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 1964c05410fSGreg Clayton } 197c3ce7f27SMichael Sartain else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0) 198c3ce7f27SMichael Sartain { 199c3ce7f27SMichael Sartain // use-color changed. Ping the prompt so it can reset the ansi terminal codes. 200c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 201c3ce7f27SMichael Sartain } 202397ddd5fSEnrico Granata else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) 20384a53dfbSEnrico Granata { 204397ddd5fSEnrico Granata if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue) 20584a53dfbSEnrico Granata { 20684a53dfbSEnrico Granata std::list<Error> errors; 2079730339bSEnrico Granata StreamString feedback_stream; 2089730339bSEnrico Granata if (!target_sp->LoadScriptingResources(errors,&feedback_stream)) 20984a53dfbSEnrico Granata { 21084a53dfbSEnrico Granata for (auto error : errors) 21184a53dfbSEnrico Granata { 2129730339bSEnrico Granata GetErrorStream().Printf("%s\n",error.AsCString()); 21384a53dfbSEnrico Granata } 2149730339bSEnrico Granata if (feedback_stream.GetSize()) 2159730339bSEnrico Granata GetErrorStream().Printf("%s",feedback_stream.GetData()); 21684a53dfbSEnrico Granata } 21784a53dfbSEnrico Granata } 21884a53dfbSEnrico Granata } 2194c05410fSGreg Clayton } 2204c05410fSGreg Clayton return error; 2214c05410fSGreg Clayton } 2224c05410fSGreg Clayton 22367cc0636SGreg Clayton bool 22467cc0636SGreg Clayton Debugger::GetAutoConfirm () const 22567cc0636SGreg Clayton { 22667cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 227754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 22867cc0636SGreg Clayton } 22967cc0636SGreg Clayton 23067cc0636SGreg Clayton const char * 23167cc0636SGreg Clayton Debugger::GetFrameFormat() const 23267cc0636SGreg Clayton { 23367cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 234754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 23567cc0636SGreg Clayton } 23667cc0636SGreg Clayton 23767cc0636SGreg Clayton bool 23867cc0636SGreg Clayton Debugger::GetNotifyVoid () const 23967cc0636SGreg Clayton { 24067cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 241754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 24267cc0636SGreg Clayton } 24367cc0636SGreg Clayton 24467cc0636SGreg Clayton const char * 24567cc0636SGreg Clayton Debugger::GetPrompt() const 24667cc0636SGreg Clayton { 24767cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 248754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 24967cc0636SGreg Clayton } 25067cc0636SGreg Clayton 25167cc0636SGreg Clayton void 25267cc0636SGreg Clayton Debugger::SetPrompt(const char *p) 25367cc0636SGreg Clayton { 25467cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 25567cc0636SGreg Clayton m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 25667cc0636SGreg Clayton const char *new_prompt = GetPrompt(); 257c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 258c3ce7f27SMichael Sartain if (str.length()) 259c3ce7f27SMichael Sartain new_prompt = str.c_str(); 26067cc0636SGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));; 26167cc0636SGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 26267cc0636SGreg Clayton } 26367cc0636SGreg Clayton 26467cc0636SGreg Clayton const char * 26567cc0636SGreg Clayton Debugger::GetThreadFormat() const 26667cc0636SGreg Clayton { 26767cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 268754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 26967cc0636SGreg Clayton } 27067cc0636SGreg Clayton 27167cc0636SGreg Clayton lldb::ScriptLanguage 27267cc0636SGreg Clayton Debugger::GetScriptLanguage() const 27367cc0636SGreg Clayton { 27467cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 275754a9369SGreg Clayton return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 27667cc0636SGreg Clayton } 27767cc0636SGreg Clayton 27867cc0636SGreg Clayton bool 27967cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 28067cc0636SGreg Clayton { 28167cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 28267cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 28367cc0636SGreg Clayton } 28467cc0636SGreg Clayton 28567cc0636SGreg Clayton uint32_t 28667cc0636SGreg Clayton Debugger::GetTerminalWidth () const 28767cc0636SGreg Clayton { 28867cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 289754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 29067cc0636SGreg Clayton } 29167cc0636SGreg Clayton 29267cc0636SGreg Clayton bool 29367cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width) 29467cc0636SGreg Clayton { 29567cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 29667cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 29767cc0636SGreg Clayton } 29867cc0636SGreg Clayton 29967cc0636SGreg Clayton bool 30067cc0636SGreg Clayton Debugger::GetUseExternalEditor () const 30167cc0636SGreg Clayton { 30267cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 303754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 30467cc0636SGreg Clayton } 30567cc0636SGreg Clayton 30667cc0636SGreg Clayton bool 30767cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b) 30867cc0636SGreg Clayton { 30967cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 31067cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 31167cc0636SGreg Clayton } 31267cc0636SGreg Clayton 313c3ce7f27SMichael Sartain bool 314c3ce7f27SMichael Sartain Debugger::GetUseColor () const 315c3ce7f27SMichael Sartain { 316c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 317c3ce7f27SMichael Sartain return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 318c3ce7f27SMichael Sartain } 319c3ce7f27SMichael Sartain 320c3ce7f27SMichael Sartain bool 321c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b) 322c3ce7f27SMichael Sartain { 323c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 324c3ce7f27SMichael Sartain bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 325c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 326c3ce7f27SMichael Sartain return ret; 327c3ce7f27SMichael Sartain } 328c3ce7f27SMichael Sartain 32967cc0636SGreg Clayton uint32_t 33067cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const 33167cc0636SGreg Clayton { 33267cc0636SGreg Clayton const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 333754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 33467cc0636SGreg Clayton } 33567cc0636SGreg Clayton 33667cc0636SGreg Clayton Debugger::StopDisassemblyType 33767cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const 33867cc0636SGreg Clayton { 33967cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 340754a9369SGreg Clayton return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 34167cc0636SGreg Clayton } 34267cc0636SGreg Clayton 34367cc0636SGreg Clayton uint32_t 34467cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const 34567cc0636SGreg Clayton { 34667cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 347754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 34867cc0636SGreg Clayton } 349e372b98dSGreg Clayton 3501b654882SGreg Clayton #pragma mark Debugger 3511b654882SGreg Clayton 35267cc0636SGreg Clayton //const DebuggerPropertiesSP & 35367cc0636SGreg Clayton //Debugger::GetSettings() const 35467cc0636SGreg Clayton //{ 35567cc0636SGreg Clayton // return m_properties_sp; 35667cc0636SGreg Clayton //} 35767cc0636SGreg Clayton // 35899d0faf2SGreg Clayton 3592f88aadfSCaroline Tice int 3602f88aadfSCaroline Tice Debugger::TestDebuggerRefCount () 3612f88aadfSCaroline Tice { 3622f88aadfSCaroline Tice return g_shared_debugger_refcount; 3632f88aadfSCaroline Tice } 3642f88aadfSCaroline Tice 36530fdc8d8SChris Lattner void 36630fdc8d8SChris Lattner Debugger::Initialize () 36730fdc8d8SChris Lattner { 368c15f55e2SGreg Clayton if (g_shared_debugger_refcount++ == 0) 369dbe54508SGreg Clayton lldb_private::Initialize(); 37099d0faf2SGreg Clayton } 37130fdc8d8SChris Lattner 37230fdc8d8SChris Lattner void 37330fdc8d8SChris Lattner Debugger::Terminate () 37430fdc8d8SChris Lattner { 3756611103cSGreg Clayton if (g_shared_debugger_refcount > 0) 3766611103cSGreg Clayton { 37730fdc8d8SChris Lattner g_shared_debugger_refcount--; 37830fdc8d8SChris Lattner if (g_shared_debugger_refcount == 0) 37930fdc8d8SChris Lattner { 380dbe54508SGreg Clayton lldb_private::WillTerminate(); 381dbe54508SGreg Clayton lldb_private::Terminate(); 3826760a517SCaroline Tice 38399d0faf2SGreg Clayton // Clear our master list of debugger objects 38499d0faf2SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 38599d0faf2SGreg Clayton GetDebuggerList().clear(); 38630fdc8d8SChris Lattner } 3876760a517SCaroline Tice } 3886760a517SCaroline Tice } 38930fdc8d8SChris Lattner 39020bd37f7SCaroline Tice void 39120bd37f7SCaroline Tice Debugger::SettingsInitialize () 39220bd37f7SCaroline Tice { 3936920b52bSGreg Clayton Target::SettingsInitialize (); 39420bd37f7SCaroline Tice } 39520bd37f7SCaroline Tice 39620bd37f7SCaroline Tice void 39720bd37f7SCaroline Tice Debugger::SettingsTerminate () 39820bd37f7SCaroline Tice { 3996920b52bSGreg Clayton Target::SettingsTerminate (); 40020bd37f7SCaroline Tice } 40120bd37f7SCaroline Tice 40221dfcd9dSEnrico Granata bool 403e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error) 40421dfcd9dSEnrico Granata { 40521dfcd9dSEnrico Granata lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec)); 406e743c782SEnrico Granata if (!dynlib_sp || dynlib_sp->IsValid() == false) 407e743c782SEnrico Granata { 408e743c782SEnrico Granata if (spec.Exists()) 409e743c782SEnrico Granata error.SetErrorString("this file does not represent a loadable dylib"); 410e743c782SEnrico Granata else 411e743c782SEnrico Granata error.SetErrorString("no such file"); 412e743c782SEnrico Granata return false; 413e743c782SEnrico Granata } 41421dfcd9dSEnrico Granata lldb::DebuggerSP debugger_sp(shared_from_this()); 41521dfcd9dSEnrico Granata lldb::SBDebugger debugger_sb(debugger_sp); 4163cf443ddSMichael Sartain // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function. 41721dfcd9dSEnrico Granata // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays 41821dfcd9dSEnrico Granata LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); 41921dfcd9dSEnrico Granata if (!init_func) 420e743c782SEnrico Granata { 421e743c782SEnrico Granata error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)"); 42221dfcd9dSEnrico Granata return false; 423e743c782SEnrico Granata } 42421dfcd9dSEnrico Granata if (init_func(debugger_sb)) 42521dfcd9dSEnrico Granata { 42621dfcd9dSEnrico Granata m_loaded_plugins.push_back(dynlib_sp); 42721dfcd9dSEnrico Granata return true; 42821dfcd9dSEnrico Granata } 429e743c782SEnrico Granata error.SetErrorString("dylib refused to be loaded"); 43021dfcd9dSEnrico Granata return false; 43121dfcd9dSEnrico Granata } 43221dfcd9dSEnrico Granata 43321dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 43421dfcd9dSEnrico Granata LoadPluginCallback 43521dfcd9dSEnrico Granata ( 43621dfcd9dSEnrico Granata void *baton, 43721dfcd9dSEnrico Granata FileSpec::FileType file_type, 43821dfcd9dSEnrico Granata const FileSpec &file_spec 43921dfcd9dSEnrico Granata ) 44021dfcd9dSEnrico Granata { 44121dfcd9dSEnrico Granata Error error; 44221dfcd9dSEnrico Granata 44321dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 4443cf443ddSMichael Sartain static ConstString g_solibext("so"); 44521dfcd9dSEnrico Granata 44621dfcd9dSEnrico Granata if (!baton) 44721dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 44821dfcd9dSEnrico Granata 44921dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 45021dfcd9dSEnrico Granata 45121dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 45221dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 45321dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 45421dfcd9dSEnrico Granata // file type information. 45521dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 45621dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 45721dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 45821dfcd9dSEnrico Granata { 45921dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 46021dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 46121dfcd9dSEnrico Granata 4623cf443ddSMichael Sartain if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 4633cf443ddSMichael Sartain plugin_file_spec.GetFileNameExtension() != g_solibext) 4643cf443ddSMichael Sartain { 46521dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 4663cf443ddSMichael Sartain } 46721dfcd9dSEnrico Granata 468e743c782SEnrico Granata Error plugin_load_error; 469e743c782SEnrico Granata debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 47021dfcd9dSEnrico Granata 47121dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 47221dfcd9dSEnrico Granata } 47321dfcd9dSEnrico Granata 47421dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 47521dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 47621dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 47721dfcd9dSEnrico Granata { 47821dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 47921dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 48021dfcd9dSEnrico Granata // might be enurating a file system that doesn't have correct file type 48121dfcd9dSEnrico Granata // information. 48221dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 48321dfcd9dSEnrico Granata } 48421dfcd9dSEnrico Granata 48521dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 48621dfcd9dSEnrico Granata } 48721dfcd9dSEnrico Granata 48821dfcd9dSEnrico Granata void 48921dfcd9dSEnrico Granata Debugger::InstanceInitialize () 49021dfcd9dSEnrico Granata { 49121dfcd9dSEnrico Granata FileSpec dir_spec; 49221dfcd9dSEnrico Granata const bool find_directories = true; 49321dfcd9dSEnrico Granata const bool find_files = true; 49421dfcd9dSEnrico Granata const bool find_other = true; 49521dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 49621dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 49721dfcd9dSEnrico Granata { 49821dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 49921dfcd9dSEnrico Granata { 50021dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 50121dfcd9dSEnrico Granata find_directories, 50221dfcd9dSEnrico Granata find_files, 50321dfcd9dSEnrico Granata find_other, 50421dfcd9dSEnrico Granata LoadPluginCallback, 50521dfcd9dSEnrico Granata this); 50621dfcd9dSEnrico Granata } 50721dfcd9dSEnrico Granata } 50821dfcd9dSEnrico Granata 50921dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 51021dfcd9dSEnrico Granata { 51121dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 51221dfcd9dSEnrico Granata { 51321dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 51421dfcd9dSEnrico Granata find_directories, 51521dfcd9dSEnrico Granata find_files, 51621dfcd9dSEnrico Granata find_other, 51721dfcd9dSEnrico Granata LoadPluginCallback, 51821dfcd9dSEnrico Granata this); 51921dfcd9dSEnrico Granata } 52021dfcd9dSEnrico Granata } 521e8cd0c98SGreg Clayton 522e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 52321dfcd9dSEnrico Granata } 52421dfcd9dSEnrico Granata 5256611103cSGreg Clayton DebuggerSP 526228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 5276611103cSGreg Clayton { 528228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 529c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 5306611103cSGreg Clayton { 5316611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5326611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 5336611103cSGreg Clayton } 53421dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 5356611103cSGreg Clayton return debugger_sp; 5366611103cSGreg Clayton } 5376611103cSGreg Clayton 538e02657b1SCaroline Tice void 5394d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 540e02657b1SCaroline Tice { 541e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 542e02657b1SCaroline Tice return; 543e02657b1SCaroline Tice 5448314c525SJim Ingham debugger_sp->Clear(); 5458314c525SJim Ingham 546c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 547c15f55e2SGreg Clayton { 548e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 549e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 550e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 551e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 552e02657b1SCaroline Tice { 553e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 554e02657b1SCaroline Tice { 555e02657b1SCaroline Tice debugger_list.erase (pos); 556e02657b1SCaroline Tice return; 557e02657b1SCaroline Tice } 558e02657b1SCaroline Tice } 559e02657b1SCaroline Tice } 560c15f55e2SGreg Clayton } 561e02657b1SCaroline Tice 5624d122c40SGreg Clayton DebuggerSP 5633df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 5643df9a8dfSCaroline Tice { 5654d122c40SGreg Clayton DebuggerSP debugger_sp; 5666920b52bSGreg Clayton if (g_shared_debugger_refcount > 0) 5676920b52bSGreg Clayton { 5686920b52bSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5696920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5706920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5716920b52bSGreg Clayton 5726920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5736920b52bSGreg Clayton { 5746920b52bSGreg Clayton if ((*pos).get()->m_instance_name == instance_name) 5756920b52bSGreg Clayton { 5766920b52bSGreg Clayton debugger_sp = *pos; 5776920b52bSGreg Clayton break; 5786920b52bSGreg Clayton } 5796920b52bSGreg Clayton } 5806920b52bSGreg Clayton } 5813df9a8dfSCaroline Tice return debugger_sp; 5823df9a8dfSCaroline Tice } 5836611103cSGreg Clayton 5846611103cSGreg Clayton TargetSP 5856611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 5866611103cSGreg Clayton { 5874d122c40SGreg Clayton TargetSP target_sp; 588c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 589c15f55e2SGreg Clayton { 5906611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5916611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5926611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5936611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5946611103cSGreg Clayton { 5956611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 5966611103cSGreg Clayton if (target_sp) 5976611103cSGreg Clayton break; 5986611103cSGreg Clayton } 599c15f55e2SGreg Clayton } 6006611103cSGreg Clayton return target_sp; 6016611103cSGreg Clayton } 6026611103cSGreg Clayton 603e4e45924SGreg Clayton TargetSP 604e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 605e4e45924SGreg Clayton { 606e4e45924SGreg Clayton TargetSP target_sp; 607c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 608c15f55e2SGreg Clayton { 609e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 610e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 611e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 612e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 613e4e45924SGreg Clayton { 614e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 615e4e45924SGreg Clayton if (target_sp) 616e4e45924SGreg Clayton break; 617e4e45924SGreg Clayton } 618c15f55e2SGreg Clayton } 619e4e45924SGreg Clayton return target_sp; 620e4e45924SGreg Clayton } 621e4e45924SGreg Clayton 622228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 623ebc1bb27SCaroline Tice UserID (g_unique_id++), 62467cc0636SGreg Clayton Properties(OptionValuePropertiesSP(new OptionValueProperties())), 625d46c87a1SGreg Clayton m_input_comm("debugger.input"), 62630fdc8d8SChris Lattner m_input_file (), 62730fdc8d8SChris Lattner m_output_file (), 62830fdc8d8SChris Lattner m_error_file (), 629c5917d9aSJim Ingham m_terminal_state (), 6304bddaeb5SJim Ingham m_target_list (*this), 631ded470d3SGreg Clayton m_platform_list (), 63230fdc8d8SChris Lattner m_listener ("lldb.Debugger"), 6339585fbfcSGreg Clayton m_source_manager_ap(), 634e37d605eSJim Ingham m_source_file_cache(), 6356611103cSGreg Clayton m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 636d5a0a01bSCaroline Tice m_input_reader_stack (), 63767cc0636SGreg Clayton m_input_reader_data (), 63867cc0636SGreg Clayton m_instance_name() 63930fdc8d8SChris Lattner { 64067cc0636SGreg Clayton char instance_cstr[256]; 64167cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 64267cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 643228063cdSJim Ingham if (log_callback) 644228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 6456611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 646ded470d3SGreg Clayton // Always add our default platform to the platform list 647ded470d3SGreg Clayton PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 648ded470d3SGreg Clayton assert (default_platform_sp.get()); 649ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 65067cc0636SGreg Clayton 651754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 65267cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 65367cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 65467cc0636SGreg Clayton true, 65567cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 656754a9369SGreg Clayton if (m_command_interpreter_ap.get()) 657754a9369SGreg Clayton { 658754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 659754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 660754a9369SGreg Clayton true, 661754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 662754a9369SGreg Clayton } 66367cc0636SGreg Clayton OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 66467cc0636SGreg Clayton term_width->SetMinimumValue(10); 66567cc0636SGreg Clayton term_width->SetMaximumValue(1024); 666c3ce7f27SMichael Sartain 667c3ce7f27SMichael Sartain // Turn off use-color if this is a dumb terminal. 668c3ce7f27SMichael Sartain const char *term = getenv ("TERM"); 669c3ce7f27SMichael Sartain if (term && !strcmp (term, "dumb")) 670c3ce7f27SMichael Sartain SetUseColor (false); 67130fdc8d8SChris Lattner } 67230fdc8d8SChris Lattner 67330fdc8d8SChris Lattner Debugger::~Debugger () 67430fdc8d8SChris Lattner { 6758314c525SJim Ingham Clear(); 6768314c525SJim Ingham } 6778314c525SJim Ingham 6788314c525SJim Ingham void 6798314c525SJim Ingham Debugger::Clear() 6808314c525SJim Ingham { 6813d6086f6SCaroline Tice CleanUpInputReaders(); 6821ed54f50SGreg Clayton m_listener.Clear(); 6836611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 6846611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 6856611103cSGreg Clayton { 686ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 687ccbc08e6SGreg Clayton if (target_sp) 688ccbc08e6SGreg Clayton { 689ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 6906611103cSGreg Clayton if (process_sp) 6911fd07059SJim Ingham process_sp->Finalize(); 692ccbc08e6SGreg Clayton target_sp->Destroy(); 6936611103cSGreg Clayton } 69430fdc8d8SChris Lattner } 6954bddaeb5SJim Ingham BroadcasterManager::Clear (); 69630fdc8d8SChris Lattner 6970d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 6980d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 699c5917d9aSJim Ingham m_terminal_state.Clear(); 7000d69a3a4SGreg Clayton GetInputFile().Close (); 7010d69a3a4SGreg Clayton // Now that we have closed m_input_file, we can now tell our input communication 7020d69a3a4SGreg Clayton // class to close down. Its read thread should quickly exit after we close 7030d69a3a4SGreg Clayton // the input file handle above. 7040d69a3a4SGreg Clayton m_input_comm.Clear (); 7058314c525SJim Ingham } 70630fdc8d8SChris Lattner 70730fdc8d8SChris Lattner bool 708fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 709fc3f027dSGreg Clayton { 710fc3f027dSGreg Clayton return m_input_comm.GetCloseOnEOF(); 711fc3f027dSGreg Clayton } 712fc3f027dSGreg Clayton 713fc3f027dSGreg Clayton void 714fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 715fc3f027dSGreg Clayton { 716fc3f027dSGreg Clayton m_input_comm.SetCloseOnEOF(b); 717fc3f027dSGreg Clayton } 718fc3f027dSGreg Clayton 719fc3f027dSGreg Clayton bool 72030fdc8d8SChris Lattner Debugger::GetAsyncExecution () 72130fdc8d8SChris Lattner { 7226611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 72330fdc8d8SChris Lattner } 72430fdc8d8SChris Lattner 72530fdc8d8SChris Lattner void 72630fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 72730fdc8d8SChris Lattner { 7286611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 72930fdc8d8SChris Lattner } 73030fdc8d8SChris Lattner 73130fdc8d8SChris Lattner 73230fdc8d8SChris Lattner void 73330fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 73430fdc8d8SChris Lattner { 73551b1e2d2SGreg Clayton File &in_file = GetInputFile(); 73651b1e2d2SGreg Clayton in_file.SetStream (fh, tranfer_ownership); 73751b1e2d2SGreg Clayton if (in_file.IsValid() == false) 73851b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 73930fdc8d8SChris Lattner 74030fdc8d8SChris Lattner // Disconnect from any old connection if we had one 74130fdc8d8SChris Lattner m_input_comm.Disconnect (); 74232720b51SGreg Clayton // Pass false as the second argument to ConnectionFileDescriptor below because 74332720b51SGreg Clayton // our "in_file" above will already take ownership if requested and we don't 74432720b51SGreg Clayton // want to objects trying to own and close a file descriptor. 74532720b51SGreg Clayton m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false)); 74630fdc8d8SChris Lattner m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); 74730fdc8d8SChris Lattner 748c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 749c5917d9aSJim Ingham SaveInputTerminalState (); 750c5917d9aSJim Ingham 75130fdc8d8SChris Lattner Error error; 75230fdc8d8SChris Lattner if (m_input_comm.StartReadThread (&error) == false) 75330fdc8d8SChris Lattner { 75451b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 75551b1e2d2SGreg Clayton 75651b1e2d2SGreg Clayton err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); 75730fdc8d8SChris Lattner exit(1); 75830fdc8d8SChris Lattner } 75930fdc8d8SChris Lattner } 76030fdc8d8SChris Lattner 76130fdc8d8SChris Lattner void 76230fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 76330fdc8d8SChris Lattner { 76451b1e2d2SGreg Clayton File &out_file = GetOutputFile(); 76551b1e2d2SGreg Clayton out_file.SetStream (fh, tranfer_ownership); 76651b1e2d2SGreg Clayton if (out_file.IsValid() == false) 76751b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 7682f88aadfSCaroline Tice 769b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 770b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 771b588726eSEnrico Granata const bool can_create = false; 772b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 773b588726eSEnrico Granata if (script_interpreter) 774b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 77530fdc8d8SChris Lattner } 77630fdc8d8SChris Lattner 77730fdc8d8SChris Lattner void 77830fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 77930fdc8d8SChris Lattner { 78051b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 78151b1e2d2SGreg Clayton err_file.SetStream (fh, tranfer_ownership); 78251b1e2d2SGreg Clayton if (err_file.IsValid() == false) 78351b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 78430fdc8d8SChris Lattner } 78530fdc8d8SChris Lattner 786c5917d9aSJim Ingham void 787c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 788c5917d9aSJim Ingham { 789c5917d9aSJim Ingham File &in_file = GetInputFile(); 790c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 791c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 792c5917d9aSJim Ingham } 793c5917d9aSJim Ingham 794c5917d9aSJim Ingham void 795c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 796c5917d9aSJim Ingham { 797c5917d9aSJim Ingham m_terminal_state.Restore(); 798c5917d9aSJim Ingham } 799c5917d9aSJim Ingham 80030fdc8d8SChris Lattner ExecutionContext 8012976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 80230fdc8d8SChris Lattner { 80330fdc8d8SChris Lattner ExecutionContext exe_ctx; 804c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 805c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 80630fdc8d8SChris Lattner 80730fdc8d8SChris Lattner if (target_sp) 80830fdc8d8SChris Lattner { 809c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 810c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 811c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 81230fdc8d8SChris Lattner { 813c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 814c14ee32dSGreg Clayton if (thread_sp) 81530fdc8d8SChris Lattner { 816c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 817c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 818c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 819c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 82030fdc8d8SChris Lattner } 82130fdc8d8SChris Lattner } 82230fdc8d8SChris Lattner } 82330fdc8d8SChris Lattner return exe_ctx; 82430fdc8d8SChris Lattner 82530fdc8d8SChris Lattner } 82630fdc8d8SChris Lattner 827b44880caSCaroline Tice InputReaderSP 828b44880caSCaroline Tice Debugger::GetCurrentInputReader () 829b44880caSCaroline Tice { 830b44880caSCaroline Tice InputReaderSP reader_sp; 831b44880caSCaroline Tice 832d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 833b44880caSCaroline Tice { 834b44880caSCaroline Tice // Clear any finished readers from the stack 835b44880caSCaroline Tice while (CheckIfTopInputReaderIsDone()) ; 836b44880caSCaroline Tice 837d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 838d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 839b44880caSCaroline Tice } 840b44880caSCaroline Tice 841b44880caSCaroline Tice return reader_sp; 842b44880caSCaroline Tice } 843b44880caSCaroline Tice 84430fdc8d8SChris Lattner void 84530fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len) 84630fdc8d8SChris Lattner { 847efed6131SCaroline Tice if (bytes_len > 0) 84830fdc8d8SChris Lattner ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len); 849efed6131SCaroline Tice else 850efed6131SCaroline Tice ((Debugger *)baton)->DispatchInputEndOfFile (); 85130fdc8d8SChris Lattner } 85230fdc8d8SChris Lattner 85330fdc8d8SChris Lattner 85430fdc8d8SChris Lattner void 85530fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len) 85630fdc8d8SChris Lattner { 857efed6131SCaroline Tice if (bytes == NULL || bytes_len == 0) 858efed6131SCaroline Tice return; 85930fdc8d8SChris Lattner 86030fdc8d8SChris Lattner WriteToDefaultReader (bytes, bytes_len); 86130fdc8d8SChris Lattner } 86230fdc8d8SChris Lattner 86330fdc8d8SChris Lattner void 864efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 865efed6131SCaroline Tice { 866efed6131SCaroline Tice m_input_reader_data.clear(); 867efed6131SCaroline Tice 868b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 869efed6131SCaroline Tice if (reader_sp) 870b44880caSCaroline Tice { 871efed6131SCaroline Tice reader_sp->Notify (eInputReaderInterrupt); 872efed6131SCaroline Tice 873b44880caSCaroline Tice // If notifying the reader of the interrupt finished the reader, we should pop it off the stack. 874efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 875efed6131SCaroline Tice } 876efed6131SCaroline Tice } 877efed6131SCaroline Tice 878efed6131SCaroline Tice void 879efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 880efed6131SCaroline Tice { 881efed6131SCaroline Tice m_input_reader_data.clear(); 882efed6131SCaroline Tice 883b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 884efed6131SCaroline Tice if (reader_sp) 885b44880caSCaroline Tice { 886efed6131SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 887efed6131SCaroline Tice 888b44880caSCaroline Tice // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack. 889efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 890efed6131SCaroline Tice } 891efed6131SCaroline Tice } 892efed6131SCaroline Tice 893efed6131SCaroline Tice void 8943d6086f6SCaroline Tice Debugger::CleanUpInputReaders () 8953d6086f6SCaroline Tice { 8963d6086f6SCaroline Tice m_input_reader_data.clear(); 8973d6086f6SCaroline Tice 898b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 899d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 9003d6086f6SCaroline Tice { 901b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 9023d6086f6SCaroline Tice if (reader_sp) 9033d6086f6SCaroline Tice { 9043d6086f6SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 9053d6086f6SCaroline Tice reader_sp->SetIsDone (true); 9063d6086f6SCaroline Tice } 9073d6086f6SCaroline Tice } 9083d6086f6SCaroline Tice } 9093d6086f6SCaroline Tice 9103d6086f6SCaroline Tice void 911969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification) 912969ed3d1SCaroline Tice { 913969ed3d1SCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader()); 914969ed3d1SCaroline Tice if (reader_sp) 915969ed3d1SCaroline Tice { 916969ed3d1SCaroline Tice reader_sp->Notify (notification); 917969ed3d1SCaroline Tice 918969ed3d1SCaroline Tice // Flush out any input readers that are done. 919969ed3d1SCaroline Tice while (CheckIfTopInputReaderIsDone ()) 920969ed3d1SCaroline Tice /* Do nothing. */; 921969ed3d1SCaroline Tice } 922969ed3d1SCaroline Tice } 923969ed3d1SCaroline Tice 9249088b068SCaroline Tice bool 9254d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp) 9269088b068SCaroline Tice { 9279088b068SCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader()); 9289088b068SCaroline Tice 929d61c10bcSCaroline Tice return (reader_sp.get() == top_reader_sp.get()); 9309088b068SCaroline Tice } 9319088b068SCaroline Tice 9329088b068SCaroline Tice 933969ed3d1SCaroline Tice void 93430fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) 93530fdc8d8SChris Lattner { 93630fdc8d8SChris Lattner if (bytes && bytes_len) 93730fdc8d8SChris Lattner m_input_reader_data.append (bytes, bytes_len); 93830fdc8d8SChris Lattner 93930fdc8d8SChris Lattner if (m_input_reader_data.empty()) 94030fdc8d8SChris Lattner return; 94130fdc8d8SChris Lattner 942d5a0a01bSCaroline Tice while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty()) 94330fdc8d8SChris Lattner { 94430fdc8d8SChris Lattner // Get the input reader from the top of the stack 945b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 94630fdc8d8SChris Lattner if (!reader_sp) 94730fdc8d8SChris Lattner break; 94830fdc8d8SChris Lattner 949471b31ceSGreg Clayton size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 95030fdc8d8SChris Lattner m_input_reader_data.size()); 95130fdc8d8SChris Lattner if (bytes_handled) 95230fdc8d8SChris Lattner { 95330fdc8d8SChris Lattner m_input_reader_data.erase (0, bytes_handled); 95430fdc8d8SChris Lattner } 95530fdc8d8SChris Lattner else 95630fdc8d8SChris Lattner { 95730fdc8d8SChris Lattner // No bytes were handled, we might not have reached our 95830fdc8d8SChris Lattner // granularity, just return and wait for more data 95930fdc8d8SChris Lattner break; 96030fdc8d8SChris Lattner } 96130fdc8d8SChris Lattner } 96230fdc8d8SChris Lattner 963b44880caSCaroline Tice // Flush out any input readers that are done. 96430fdc8d8SChris Lattner while (CheckIfTopInputReaderIsDone ()) 96530fdc8d8SChris Lattner /* Do nothing. */; 96630fdc8d8SChris Lattner 96730fdc8d8SChris Lattner } 96830fdc8d8SChris Lattner 96930fdc8d8SChris Lattner void 97030fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp) 97130fdc8d8SChris Lattner { 97230fdc8d8SChris Lattner if (!reader_sp) 97330fdc8d8SChris Lattner return; 974b44880caSCaroline Tice 97530fdc8d8SChris Lattner // Deactivate the old top reader 976b44880caSCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader ()); 977b44880caSCaroline Tice 97830fdc8d8SChris Lattner if (top_reader_sp) 97930fdc8d8SChris Lattner top_reader_sp->Notify (eInputReaderDeactivate); 980b44880caSCaroline Tice 981d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 98230fdc8d8SChris Lattner reader_sp->Notify (eInputReaderActivate); 98330fdc8d8SChris Lattner ActivateInputReader (reader_sp); 98430fdc8d8SChris Lattner } 98530fdc8d8SChris Lattner 98630fdc8d8SChris Lattner bool 9874d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp) 98830fdc8d8SChris Lattner { 98930fdc8d8SChris Lattner bool result = false; 99030fdc8d8SChris Lattner 99130fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 99230fdc8d8SChris Lattner // read on the stack referesh its prompt and if there is one... 993d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 99430fdc8d8SChris Lattner { 995b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 996d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 99730fdc8d8SChris Lattner 99830fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 99930fdc8d8SChris Lattner { 1000d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 100130fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDeactivate); 100230fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDone); 100330fdc8d8SChris Lattner result = true; 100430fdc8d8SChris Lattner 1005d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 100630fdc8d8SChris Lattner { 1007d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 100830fdc8d8SChris Lattner if (reader_sp) 100930fdc8d8SChris Lattner { 101030fdc8d8SChris Lattner ActivateInputReader (reader_sp); 101130fdc8d8SChris Lattner reader_sp->Notify (eInputReaderReactivate); 101230fdc8d8SChris Lattner } 101330fdc8d8SChris Lattner } 101430fdc8d8SChris Lattner } 101530fdc8d8SChris Lattner } 101630fdc8d8SChris Lattner return result; 101730fdc8d8SChris Lattner } 101830fdc8d8SChris Lattner 101930fdc8d8SChris Lattner bool 102030fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone () 102130fdc8d8SChris Lattner { 102230fdc8d8SChris Lattner bool result = false; 1023d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 102430fdc8d8SChris Lattner { 1025b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 1026d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 102730fdc8d8SChris Lattner 102830fdc8d8SChris Lattner if (reader_sp && reader_sp->IsDone()) 102930fdc8d8SChris Lattner { 103030fdc8d8SChris Lattner result = true; 103130fdc8d8SChris Lattner PopInputReader (reader_sp); 103230fdc8d8SChris Lattner } 103330fdc8d8SChris Lattner } 103430fdc8d8SChris Lattner return result; 103530fdc8d8SChris Lattner } 103630fdc8d8SChris Lattner 103730fdc8d8SChris Lattner void 103830fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 103930fdc8d8SChris Lattner { 104051b1e2d2SGreg Clayton int input_fd = m_input_file.GetFile().GetDescriptor(); 104130fdc8d8SChris Lattner 104251b1e2d2SGreg Clayton if (input_fd >= 0) 104330fdc8d8SChris Lattner { 104451b1e2d2SGreg Clayton Terminal tty(input_fd); 1045a3406614SGreg Clayton 1046a3406614SGreg Clayton tty.SetEcho(reader_sp->GetEcho()); 104730fdc8d8SChris Lattner 104830fdc8d8SChris Lattner switch (reader_sp->GetGranularity()) 104930fdc8d8SChris Lattner { 105030fdc8d8SChris Lattner case eInputReaderGranularityByte: 105130fdc8d8SChris Lattner case eInputReaderGranularityWord: 1052a3406614SGreg Clayton tty.SetCanonical (false); 105330fdc8d8SChris Lattner break; 105430fdc8d8SChris Lattner 105530fdc8d8SChris Lattner case eInputReaderGranularityLine: 105630fdc8d8SChris Lattner case eInputReaderGranularityAll: 1057a3406614SGreg Clayton tty.SetCanonical (true); 105830fdc8d8SChris Lattner break; 105930fdc8d8SChris Lattner 106030fdc8d8SChris Lattner default: 106130fdc8d8SChris Lattner break; 106230fdc8d8SChris Lattner } 106330fdc8d8SChris Lattner } 106430fdc8d8SChris Lattner } 10656611103cSGreg Clayton 10665b52f0c7SJim Ingham StreamSP 10675b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 10685b52f0c7SJim Ingham { 10695b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10705b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 10715b52f0c7SJim Ingham } 10725b52f0c7SJim Ingham 10735b52f0c7SJim Ingham StreamSP 10745b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 10755b52f0c7SJim Ingham { 10765b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10775b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 10785b52f0c7SJim Ingham } 10795b52f0c7SJim Ingham 1080c7bece56SGreg Clayton size_t 1081061858ceSEnrico Granata Debugger::GetNumDebuggers() 1082061858ceSEnrico Granata { 1083c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1084c15f55e2SGreg Clayton { 1085061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1086061858ceSEnrico Granata return GetDebuggerList().size(); 1087061858ceSEnrico Granata } 1088c15f55e2SGreg Clayton return 0; 1089c15f55e2SGreg Clayton } 1090061858ceSEnrico Granata 1091061858ceSEnrico Granata lldb::DebuggerSP 1092c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1093061858ceSEnrico Granata { 1094061858ceSEnrico Granata DebuggerSP debugger_sp; 1095061858ceSEnrico Granata 1096c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1097c15f55e2SGreg Clayton { 1098061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1099061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1100061858ceSEnrico Granata 1101061858ceSEnrico Granata if (index < debugger_list.size()) 1102061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1103c15f55e2SGreg Clayton } 1104061858ceSEnrico Granata 1105061858ceSEnrico Granata return debugger_sp; 1106061858ceSEnrico Granata } 1107061858ceSEnrico Granata 1108ebc1bb27SCaroline Tice DebuggerSP 1109ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1110ebc1bb27SCaroline Tice { 11114d122c40SGreg Clayton DebuggerSP debugger_sp; 1112ebc1bb27SCaroline Tice 1113c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1114c15f55e2SGreg Clayton { 1115ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 1116ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1117ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1118ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1119ebc1bb27SCaroline Tice { 1120ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 1121ebc1bb27SCaroline Tice { 1122ebc1bb27SCaroline Tice debugger_sp = *pos; 1123ebc1bb27SCaroline Tice break; 1124ebc1bb27SCaroline Tice } 1125ebc1bb27SCaroline Tice } 1126c15f55e2SGreg Clayton } 1127ebc1bb27SCaroline Tice return debugger_sp; 1128ebc1bb27SCaroline Tice } 11293df9a8dfSCaroline Tice 11301b654882SGreg Clayton static void 11311b654882SGreg Clayton TestPromptFormats (StackFrame *frame) 11321b654882SGreg Clayton { 11331b654882SGreg Clayton if (frame == NULL) 11341b654882SGreg Clayton return; 11351b654882SGreg Clayton 11361b654882SGreg Clayton StreamString s; 11371b654882SGreg Clayton const char *prompt_format = 11381b654882SGreg Clayton "{addr = '${addr}'\n}" 11391b654882SGreg Clayton "{process.id = '${process.id}'\n}" 11401b654882SGreg Clayton "{process.name = '${process.name}'\n}" 11411b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 11421b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 11431b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 11441b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 11451b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 11461b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 11471b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 11481b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 11491b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 11501b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 11511b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 11521b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 11531b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 11541b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 11551b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 11561b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 11571b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 11581b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 11591b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 11601b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 11611b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 11621b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 11631b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 11641b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 11651b654882SGreg Clayton "{function.id = '${function.id}'\n}" 11661b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1167ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 11681b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 11691b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 11701b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 11711b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 11721b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 11731b654882SGreg Clayton "{line.number = '${line.number}'\n}" 11741b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 11751b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 11761b654882SGreg Clayton ; 11771b654882SGreg Clayton 11781b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 11791b654882SGreg Clayton ExecutionContext exe_ctx; 11800603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 1181c3ce7f27SMichael Sartain if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 11821b654882SGreg Clayton { 11831b654882SGreg Clayton printf("%s\n", s.GetData()); 11841b654882SGreg Clayton } 11851b654882SGreg Clayton else 11861b654882SGreg Clayton { 11871b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 11881b654882SGreg Clayton } 11891b654882SGreg Clayton } 11901b654882SGreg Clayton 11919fc1944eSEnrico Granata static bool 11929fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin, 11939fc1944eSEnrico Granata const char* var_name_end, 11949fc1944eSEnrico Granata const char** var_name_final, 11959fc1944eSEnrico Granata const char** percent_position, 11964d122c40SGreg Clayton Format* custom_format, 11979fc1944eSEnrico Granata ValueObject::ValueObjectRepresentationStyle* val_obj_display) 11989fc1944eSEnrico Granata { 11995160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12009fc1944eSEnrico Granata *percent_position = ::strchr(var_name_begin,'%'); 12019fc1944eSEnrico Granata if (!*percent_position || *percent_position > var_name_end) 1202e992a089SEnrico Granata { 1203e992a089SEnrico Granata if (log) 1204d228483dSEnrico Granata log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 12059fc1944eSEnrico Granata *var_name_final = var_name_end; 1206e992a089SEnrico Granata } 12079fc1944eSEnrico Granata else 12089fc1944eSEnrico Granata { 12099fc1944eSEnrico Granata *var_name_final = *percent_position; 121036aa5ae6SEnrico Granata std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1); 1211e992a089SEnrico Granata if (log) 121268ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str()); 121336aa5ae6SEnrico Granata if ( !FormatManager::GetFormatFromCString(format_name.c_str(), 12149fc1944eSEnrico Granata true, 12159fc1944eSEnrico Granata *custom_format) ) 12169fc1944eSEnrico Granata { 1217e992a089SEnrico Granata if (log) 121868ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str()); 121936aa5ae6SEnrico Granata 122036aa5ae6SEnrico Granata switch (format_name.front()) 122136aa5ae6SEnrico Granata { 122236aa5ae6SEnrico Granata case '@': // if this is an @ sign, print ObjC description 122386cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 122436aa5ae6SEnrico Granata break; 122536aa5ae6SEnrico Granata case 'V': // if this is a V, print the value using the default format 122686cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 122736aa5ae6SEnrico Granata break; 122836aa5ae6SEnrico Granata case 'L': // if this is an L, print the location of the value 122986cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 123036aa5ae6SEnrico Granata break; 123136aa5ae6SEnrico Granata case 'S': // if this is an S, print the summary after all 123286cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 123336aa5ae6SEnrico Granata break; 123436aa5ae6SEnrico Granata case '#': // if this is a '#', print the number of children 123586cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 123636aa5ae6SEnrico Granata break; 123736aa5ae6SEnrico Granata case 'T': // if this is a 'T', print the type 123886cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 123936aa5ae6SEnrico Granata break; 12402c75f11eSEnrico Granata case 'N': // if this is a 'N', print the name 12412c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleName; 12422c75f11eSEnrico Granata break; 12432c75f11eSEnrico Granata case '>': // if this is a '>', print the name 12442c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath; 12452c75f11eSEnrico Granata break; 124636aa5ae6SEnrico Granata default: 12475c42d8a8SJim Ingham if (log) 124836aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 124936aa5ae6SEnrico Granata break; 125036aa5ae6SEnrico Granata } 12519fc1944eSEnrico Granata } 12529fc1944eSEnrico Granata // a good custom format tells us to print the value using it 12539fc1944eSEnrico Granata else 1254e992a089SEnrico Granata { 1255e992a089SEnrico Granata if (log) 125668ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] will display value for this VO"); 125786cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1258e992a089SEnrico Granata } 12599fc1944eSEnrico Granata } 1260e992a089SEnrico Granata if (log) 126168ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1262e992a089SEnrico Granata *custom_format, 1263e992a089SEnrico Granata *val_obj_display); 12649fc1944eSEnrico Granata return true; 12659fc1944eSEnrico Granata } 12669fc1944eSEnrico Granata 12679fc1944eSEnrico Granata static bool 12689fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 12699fc1944eSEnrico Granata const char* var_name_end, 12709fc1944eSEnrico Granata const char* var_name_final, 12719fc1944eSEnrico Granata const char** open_bracket_position, 12729fc1944eSEnrico Granata const char** separator_position, 12739fc1944eSEnrico Granata const char** close_bracket_position, 12749fc1944eSEnrico Granata const char** var_name_final_if_array_range, 12759fc1944eSEnrico Granata int64_t* index_lower, 12769fc1944eSEnrico Granata int64_t* index_higher) 12779fc1944eSEnrico Granata { 12785160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12799fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 12809fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 12819fc1944eSEnrico Granata { 12829fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 12839fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 12849fc1944eSEnrico Granata // as usual, we assume that [] will come before % 12859fc1944eSEnrico Granata //printf("trying to expand a []\n"); 12869fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 12879fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 12889fc1944eSEnrico Granata { 1289e992a089SEnrico Granata if (log) 1290d228483dSEnrico Granata log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 12919fc1944eSEnrico Granata *index_lower = 0; 12929fc1944eSEnrico Granata } 12939fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 12949fc1944eSEnrico Granata { 12959fc1944eSEnrico Granata char *end = NULL; 12969fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12979fc1944eSEnrico Granata *index_higher = *index_lower; 1298e992a089SEnrico Granata if (log) 1299d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 13009fc1944eSEnrico Granata } 13019fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 13029fc1944eSEnrico Granata { 13039fc1944eSEnrico Granata char *end = NULL; 13049fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 13059fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 1306e992a089SEnrico Granata if (log) 1307d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 13089fc1944eSEnrico Granata } 13099fc1944eSEnrico Granata else 1310e992a089SEnrico Granata { 1311e992a089SEnrico Granata if (log) 1312d228483dSEnrico Granata log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 13139fc1944eSEnrico Granata return false; 1314e992a089SEnrico Granata } 13159fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 13169fc1944eSEnrico Granata { 1317e992a089SEnrico Granata if (log) 1318d228483dSEnrico Granata log->Printf("[ScanBracketedRange] swapping indices"); 1319c7bece56SGreg Clayton int64_t temp = *index_lower; 13209fc1944eSEnrico Granata *index_lower = *index_higher; 13219fc1944eSEnrico Granata *index_higher = temp; 13229fc1944eSEnrico Granata } 13239fc1944eSEnrico Granata } 1324e992a089SEnrico Granata else if (log) 1325d228483dSEnrico Granata log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 13269fc1944eSEnrico Granata return true; 13279fc1944eSEnrico Granata } 13289fc1944eSEnrico Granata 1329*0769b2b1SMichael Sartain template <typename T> 1330*0769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name) 1331*0769b2b1SMichael Sartain { 1332*0769b2b1SMichael Sartain if (script_interpreter) 1333*0769b2b1SMichael Sartain { 1334*0769b2b1SMichael Sartain Error script_error; 1335*0769b2b1SMichael Sartain std::string script_output; 1336*0769b2b1SMichael Sartain 1337*0769b2b1SMichael Sartain if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success()) 1338*0769b2b1SMichael Sartain { 1339*0769b2b1SMichael Sartain s.Printf("%s", script_output.c_str()); 1340*0769b2b1SMichael Sartain return true; 1341*0769b2b1SMichael Sartain } 1342*0769b2b1SMichael Sartain else 1343*0769b2b1SMichael Sartain { 1344*0769b2b1SMichael Sartain s.Printf("<error: %s>",script_error.AsCString()); 1345*0769b2b1SMichael Sartain } 1346*0769b2b1SMichael Sartain } 1347*0769b2b1SMichael Sartain return false; 1348*0769b2b1SMichael Sartain } 1349*0769b2b1SMichael Sartain 13509fc1944eSEnrico Granata static ValueObjectSP 1351c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 1352c7bece56SGreg Clayton size_t index, 13539fc1944eSEnrico Granata StackFrame* frame, 1354fc7a7f3bSEnrico Granata bool deref_pointer) 13559fc1944eSEnrico Granata { 13565160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1357fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1358599171adSEnrico Granata std::string ptr_deref_buffer(10,0); 1359599171adSEnrico Granata ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1360e992a089SEnrico Granata if (log) 1361599171adSEnrico Granata log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1362fc7a7f3bSEnrico Granata const char* first_unparsed; 1363fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1364fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1365fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 136686cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1367599171adSEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1368fc7a7f3bSEnrico Granata &first_unparsed, 1369fc7a7f3bSEnrico Granata &reason_to_stop, 1370fc7a7f3bSEnrico Granata &final_value_type, 1371fc7a7f3bSEnrico Granata options, 1372fc7a7f3bSEnrico Granata &what_next); 1373fc7a7f3bSEnrico Granata if (!item) 1374fc7a7f3bSEnrico Granata { 1375e992a089SEnrico Granata if (log) 1376d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1377e992a089SEnrico Granata " final_value_type %d", 1378fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1379fc7a7f3bSEnrico Granata } 13809fc1944eSEnrico Granata else 13819fc1944eSEnrico Granata { 1382e992a089SEnrico Granata if (log) 1383d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1384e992a089SEnrico Granata " final_value_type %d", 1385fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 13869fc1944eSEnrico Granata } 13879fc1944eSEnrico Granata return item; 13889fc1944eSEnrico Granata } 13899fc1944eSEnrico Granata 1390*0769b2b1SMichael Sartain static inline bool 1391*0769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var) 1392*0769b2b1SMichael Sartain { 1393*0769b2b1SMichael Sartain return (::strncmp (var_name_begin, var, strlen(var)) == 0); 1394*0769b2b1SMichael Sartain } 1395*0769b2b1SMichael Sartain 1396*0769b2b1SMichael Sartain static bool 1397*0769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format, 1398*0769b2b1SMichael Sartain const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr) 1399*0769b2b1SMichael Sartain { 1400*0769b2b1SMichael Sartain int var_len = strlen(var); 1401*0769b2b1SMichael Sartain if (::strncmp (var_name_begin, var, var_len) == 0) 1402*0769b2b1SMichael Sartain { 1403*0769b2b1SMichael Sartain var_name_begin += var_len; 1404*0769b2b1SMichael Sartain if (*var_name_begin == '}') 1405*0769b2b1SMichael Sartain { 1406*0769b2b1SMichael Sartain format = default_format; 1407*0769b2b1SMichael Sartain return true; 1408*0769b2b1SMichael Sartain } 1409*0769b2b1SMichael Sartain else if (*var_name_begin == '%') 1410*0769b2b1SMichael Sartain { 1411*0769b2b1SMichael Sartain // Allow format specifiers: x|X|u with optional width specifiers. 1412*0769b2b1SMichael Sartain // ${thread.id%x} ; hex 1413*0769b2b1SMichael Sartain // ${thread.id%X} ; uppercase hex 1414*0769b2b1SMichael Sartain // ${thread.id%u} ; unsigned decimal 1415*0769b2b1SMichael Sartain // ${thread.id%8.8X} ; width.precision + specifier 1416*0769b2b1SMichael Sartain // ${thread.id%tid} ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id) 1417*0769b2b1SMichael Sartain int dot_count = 0; 1418*0769b2b1SMichael Sartain const char *specifier = NULL; 1419*0769b2b1SMichael Sartain int width_precision_length = 0; 1420*0769b2b1SMichael Sartain const char *width_precision = ++var_name_begin; 1421*0769b2b1SMichael Sartain while (isdigit(*var_name_begin) || *var_name_begin == '.') 1422*0769b2b1SMichael Sartain { 1423*0769b2b1SMichael Sartain dot_count += (*var_name_begin == '.'); 1424*0769b2b1SMichael Sartain if (dot_count > 1) 1425*0769b2b1SMichael Sartain break; 1426*0769b2b1SMichael Sartain var_name_begin++; 1427*0769b2b1SMichael Sartain width_precision_length++; 1428*0769b2b1SMichael Sartain } 1429*0769b2b1SMichael Sartain 1430*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "tid}")) 1431*0769b2b1SMichael Sartain { 1432*0769b2b1SMichael Sartain Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr); 1433*0769b2b1SMichael Sartain if (target) 1434*0769b2b1SMichael Sartain { 1435*0769b2b1SMichael Sartain ArchSpec arch (target->GetArchitecture ()); 1436*0769b2b1SMichael Sartain llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS; 1437*0769b2b1SMichael Sartain if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux)) 1438*0769b2b1SMichael Sartain specifier = PRIu64; 1439*0769b2b1SMichael Sartain } 1440*0769b2b1SMichael Sartain if (!specifier) 1441*0769b2b1SMichael Sartain { 1442*0769b2b1SMichael Sartain format = default_format; 1443*0769b2b1SMichael Sartain return true; 1444*0769b2b1SMichael Sartain } 1445*0769b2b1SMichael Sartain } 1446*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "x}")) 1447*0769b2b1SMichael Sartain specifier = PRIx64; 1448*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "X}")) 1449*0769b2b1SMichael Sartain specifier = PRIX64; 1450*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "u}")) 1451*0769b2b1SMichael Sartain specifier = PRIu64; 1452*0769b2b1SMichael Sartain 1453*0769b2b1SMichael Sartain if (specifier) 1454*0769b2b1SMichael Sartain { 1455*0769b2b1SMichael Sartain format = "%"; 1456*0769b2b1SMichael Sartain if (width_precision_length) 1457*0769b2b1SMichael Sartain format += std::string(width_precision, width_precision_length); 1458*0769b2b1SMichael Sartain format += specifier; 1459*0769b2b1SMichael Sartain return true; 1460*0769b2b1SMichael Sartain } 1461*0769b2b1SMichael Sartain } 1462*0769b2b1SMichael Sartain } 1463*0769b2b1SMichael Sartain return false; 1464*0769b2b1SMichael Sartain } 1465*0769b2b1SMichael Sartain 1466c3ce7f27SMichael Sartain static bool 1467c3ce7f27SMichael Sartain FormatPromptRecurse 14681b654882SGreg Clayton ( 14691b654882SGreg Clayton const char *format, 14701b654882SGreg Clayton const SymbolContext *sc, 14711b654882SGreg Clayton const ExecutionContext *exe_ctx, 14721b654882SGreg Clayton const Address *addr, 14731b654882SGreg Clayton Stream &s, 14744becb37eSEnrico Granata const char **end, 1475c482a192SEnrico Granata ValueObject* valobj 14761b654882SGreg Clayton ) 14771b654882SGreg Clayton { 1478c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 14791b654882SGreg Clayton bool success = true; 14801b654882SGreg Clayton const char *p; 14815160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1482c3ce7f27SMichael Sartain 14831b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 14841b654882SGreg Clayton { 1485c482a192SEnrico Granata if (realvalobj) 14864becb37eSEnrico Granata { 1487c482a192SEnrico Granata valobj = realvalobj; 1488c482a192SEnrico Granata realvalobj = NULL; 14894becb37eSEnrico Granata } 14901b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 14911b654882SGreg Clayton if (non_special_chars > 0) 14921b654882SGreg Clayton { 14931b654882SGreg Clayton if (success) 14941b654882SGreg Clayton s.Write (p, non_special_chars); 14951b654882SGreg Clayton p += non_special_chars; 14961b654882SGreg Clayton } 14971b654882SGreg Clayton 14981b654882SGreg Clayton if (*p == '\0') 14991b654882SGreg Clayton { 15001b654882SGreg Clayton break; 15011b654882SGreg Clayton } 15021b654882SGreg Clayton else if (*p == '{') 15031b654882SGreg Clayton { 15041b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 15051b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 15061b654882SGreg Clayton // a format that only prints out the function or symbol name if there 15071b654882SGreg Clayton // is one in the symbol context you can use: 15081b654882SGreg Clayton // "{function =${function.name}}" 15091b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 15101b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 15111b654882SGreg Clayton // will then be evaluated and only be output if there is a function 15121b654882SGreg Clayton // or symbol with a valid name. 15131b654882SGreg Clayton StreamString sub_strm; 15141b654882SGreg Clayton 15151b654882SGreg Clayton ++p; // Skip the '{' 15161b654882SGreg Clayton 1517c3ce7f27SMichael Sartain if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 15181b654882SGreg Clayton { 15191b654882SGreg Clayton // The stream had all it needed 15201b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 15211b654882SGreg Clayton } 15221b654882SGreg Clayton if (*p != '}') 15231b654882SGreg Clayton { 15241b654882SGreg Clayton success = false; 15251b654882SGreg Clayton break; 15261b654882SGreg Clayton } 15271b654882SGreg Clayton } 15281b654882SGreg Clayton else if (*p == '}') 15291b654882SGreg Clayton { 15301b654882SGreg Clayton // End of a enclosing scope 15311b654882SGreg Clayton break; 15321b654882SGreg Clayton } 15331b654882SGreg Clayton else if (*p == '$') 15341b654882SGreg Clayton { 15351b654882SGreg Clayton // We have a prompt variable to print 15361b654882SGreg Clayton ++p; 15371b654882SGreg Clayton if (*p == '{') 15381b654882SGreg Clayton { 15391b654882SGreg Clayton ++p; 15401b654882SGreg Clayton const char *var_name_begin = p; 15411b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 15421b654882SGreg Clayton 15431b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 15441b654882SGreg Clayton { 15451b654882SGreg Clayton // if we have already failed to parse, skip this variable 15461b654882SGreg Clayton if (success) 15471b654882SGreg Clayton { 15481b654882SGreg Clayton const char *cstr = NULL; 1549*0769b2b1SMichael Sartain std::string token_format; 15501b654882SGreg Clayton Address format_addr; 15511b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 15521b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 15531b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 15541b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 15551b654882SGreg Clayton FileSpec format_file_spec; 1556e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 15571b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 15589fc1944eSEnrico Granata bool do_deref_pointer = false; 155986cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 156086cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 15611b654882SGreg Clayton 15621b654882SGreg Clayton // Each variable must set success to true below... 15631b654882SGreg Clayton bool var_success = false; 15641b654882SGreg Clayton switch (var_name_begin[0]) 15651b654882SGreg Clayton { 15664becb37eSEnrico Granata case '*': 15676f3533fbSEnrico Granata case 'v': 15686f3533fbSEnrico Granata case 's': 15694becb37eSEnrico Granata { 1570c482a192SEnrico Granata if (!valobj) 157134132754SGreg Clayton break; 15726f3533fbSEnrico Granata 1573c3e320a7SEnrico Granata if (log) 1574d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1575c3e320a7SEnrico Granata 15766f3533fbSEnrico Granata // check for *var and *svar 15776f3533fbSEnrico Granata if (*var_name_begin == '*') 15786f3533fbSEnrico Granata { 15799fc1944eSEnrico Granata do_deref_pointer = true; 15809fc1944eSEnrico Granata var_name_begin++; 1581c3e320a7SEnrico Granata if (log) 158268ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin); 158368ae4117SEnrico Granata } 1584c3e320a7SEnrico Granata 15856f3533fbSEnrico Granata if (*var_name_begin == 's') 15864becb37eSEnrico Granata { 1587c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 158886cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 158986cc9829SEnrico Granata if (!valobj) 159086cc9829SEnrico Granata break; 15916f3533fbSEnrico Granata var_name_begin++; 1592c3e320a7SEnrico Granata if (log) 159368ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin); 159468ae4117SEnrico Granata } 1595c3e320a7SEnrico Granata 15966f3533fbSEnrico Granata // should be a 'v' by now 15976f3533fbSEnrico Granata if (*var_name_begin != 'v') 15986f3533fbSEnrico Granata break; 15996f3533fbSEnrico Granata 1600c3e320a7SEnrico Granata if (log) 160168ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin); 1602c3e320a7SEnrico Granata 1603fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 160486cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1605fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 16068c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 160786cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 160834132754SGreg Clayton ValueObject* target = NULL; 16094d122c40SGreg Clayton Format custom_format = eFormatInvalid; 161034132754SGreg Clayton const char* var_name_final = NULL; 16119fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 161234132754SGreg Clayton const char* close_bracket_position = NULL; 161334132754SGreg Clayton int64_t index_lower = -1; 161434132754SGreg Clayton int64_t index_higher = -1; 16159fc1944eSEnrico Granata bool is_array_range = false; 1616fc7a7f3bSEnrico Granata const char* first_unparsed; 161785933ed4SEnrico Granata bool was_plain_var = false; 161885933ed4SEnrico Granata bool was_var_format = false; 1619a777dc2aSEnrico Granata bool was_var_indexed = false; 1620fc7a7f3bSEnrico Granata 1621c482a192SEnrico Granata if (!valobj) break; 1622c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 1623*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "var}")) 16240a3958e0SEnrico Granata { 162585933ed4SEnrico Granata was_plain_var = true; 1626c482a192SEnrico Granata target = valobj; 162786cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 16280a3958e0SEnrico Granata } 1629*0769b2b1SMichael Sartain else if (IsToken (var_name_begin,"var%")) 16309fc1944eSEnrico Granata { 163185933ed4SEnrico Granata was_var_format = true; 16329fc1944eSEnrico Granata // this is a variable with some custom format applied to it 16339fc1944eSEnrico Granata const char* percent_position; 1634c482a192SEnrico Granata target = valobj; 163586cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 16369fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 16379fc1944eSEnrico Granata var_name_end, 16389fc1944eSEnrico Granata &var_name_final, 16399fc1944eSEnrico Granata &percent_position, 16409fc1944eSEnrico Granata &custom_format, 16419fc1944eSEnrico Granata &val_obj_display); 16420a3958e0SEnrico Granata } 16439fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 1644*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "var")) 16459fc1944eSEnrico Granata { 1646*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "var[")) 1647a777dc2aSEnrico Granata was_var_indexed = true; 16489fc1944eSEnrico Granata const char* percent_position; 16499fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 16509fc1944eSEnrico Granata var_name_end, 16519fc1944eSEnrico Granata &var_name_final, 16529fc1944eSEnrico Granata &percent_position, 16539fc1944eSEnrico Granata &custom_format, 16549fc1944eSEnrico Granata &val_obj_display); 16559fc1944eSEnrico Granata 16569fc1944eSEnrico Granata const char* open_bracket_position; 16579fc1944eSEnrico Granata const char* separator_position; 16589fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 16599fc1944eSEnrico Granata var_name_end, 16609fc1944eSEnrico Granata var_name_final, 16619fc1944eSEnrico Granata &open_bracket_position, 16629fc1944eSEnrico Granata &separator_position, 16639fc1944eSEnrico Granata &close_bracket_position, 16649fc1944eSEnrico Granata &var_name_final_if_array_range, 16659fc1944eSEnrico Granata &index_lower, 16669fc1944eSEnrico Granata &index_higher); 16679fc1944eSEnrico Granata 16689fc1944eSEnrico Granata Error error; 16699fc1944eSEnrico Granata 1670599171adSEnrico Granata std::string expr_path(var_name_final-var_name_begin-1,0); 1671599171adSEnrico Granata memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1672fc7a7f3bSEnrico Granata 1673e992a089SEnrico Granata if (log) 1674599171adSEnrico Granata log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1675fc7a7f3bSEnrico Granata 1676599171adSEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1677fc7a7f3bSEnrico Granata &first_unparsed, 1678fc7a7f3bSEnrico Granata &reason_to_stop, 1679fc7a7f3bSEnrico Granata &final_value_type, 1680fc7a7f3bSEnrico Granata options, 1681fc7a7f3bSEnrico Granata &what_next).get(); 1682fc7a7f3bSEnrico Granata 1683fc7a7f3bSEnrico Granata if (!target) 16849fc1944eSEnrico Granata { 1685e992a089SEnrico Granata if (log) 1686d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1687e992a089SEnrico Granata " final_value_type %d", 1688fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1689fc7a7f3bSEnrico Granata break; 16900a3958e0SEnrico Granata } 1691a7187d00SEnrico Granata else 1692fc7a7f3bSEnrico Granata { 1693e992a089SEnrico Granata if (log) 1694d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1695e992a089SEnrico Granata " final_value_type %d", 1696fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1697a7187d00SEnrico Granata } 16980a3958e0SEnrico Granata } 16990a3958e0SEnrico Granata else 17000a3958e0SEnrico Granata break; 17019fc1944eSEnrico Granata 170286cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 170386cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1704fc7a7f3bSEnrico Granata 170586cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1706fc7a7f3bSEnrico Granata 1707a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 17080a3958e0SEnrico Granata { 17099fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 17109fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 17119fc1944eSEnrico Granata // to get to the target ValueObject 17129fc1944eSEnrico Granata Error error; 17139fc1944eSEnrico Granata target = target->Dereference(error).get(); 1714dc940730SEnrico Granata if (error.Fail()) 1715dc940730SEnrico Granata { 1716dc940730SEnrico Granata if (log) 1717d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1718dc940730SEnrico Granata break; 1719dc940730SEnrico Granata } 17209fc1944eSEnrico Granata do_deref_pointer = false; 17210a3958e0SEnrico Granata } 17220a3958e0SEnrico Granata 1723a777dc2aSEnrico Granata // <rdar://problem/11338654> 1724a777dc2aSEnrico Granata // we do not want to use the summary for a bitfield of type T:n 1725a777dc2aSEnrico Granata // if we were originally dealing with just a T - that would get 1726a777dc2aSEnrico Granata // us into an endless recursion 1727a777dc2aSEnrico Granata if (target->IsBitfield() && was_var_indexed) 1728a777dc2aSEnrico Granata { 1729a777dc2aSEnrico Granata // TODO: check for a (T:n)-specific summary - we should still obey that 1730a777dc2aSEnrico Granata StreamString bitfield_name; 1731a777dc2aSEnrico Granata bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1732a777dc2aSEnrico Granata lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1733a777dc2aSEnrico Granata if (!DataVisualization::GetSummaryForType(type_sp)) 1734a777dc2aSEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1735a777dc2aSEnrico Granata } 1736a777dc2aSEnrico Granata 173785933ed4SEnrico Granata // TODO use flags for these 173857ee3067SGreg Clayton const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL); 173957ee3067SGreg Clayton bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0; 174057ee3067SGreg Clayton bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0; 174157ee3067SGreg Clayton bool is_aggregate = target->GetClangType().IsAggregateType(); 1742f4efecd9SEnrico Granata 174386cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1744f4efecd9SEnrico Granata { 174585933ed4SEnrico Granata StreamString str_temp; 1746e992a089SEnrico Granata if (log) 1747d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1748d64d0bc0SEnrico Granata 17495088c486SGreg Clayton if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1750d64d0bc0SEnrico Granata { 1751f4efecd9SEnrico Granata // try to use the special cases 175285933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 175385933ed4SEnrico Granata val_obj_display, 175485933ed4SEnrico Granata custom_format); 1755e992a089SEnrico Granata if (log) 1756d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1757d64d0bc0SEnrico Granata 1758d64d0bc0SEnrico Granata // should not happen 17595088c486SGreg Clayton if (var_success) 176085933ed4SEnrico Granata s << str_temp.GetData(); 1761d64d0bc0SEnrico Granata var_success = true; 1762d64d0bc0SEnrico Granata break; 1763d64d0bc0SEnrico Granata } 1764d64d0bc0SEnrico Granata else 1765d64d0bc0SEnrico Granata { 176688da35f8SEnrico Granata if (was_plain_var) // if ${var} 1767d64d0bc0SEnrico Granata { 1768d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1769d64d0bc0SEnrico Granata } 177088da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 177188da35f8SEnrico Granata { 177223f59509SGreg Clayton target->DumpPrintableRepresentation (s, 177388da35f8SEnrico Granata val_obj_display, 177486cc9829SEnrico Granata custom_format, 177586cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 177688da35f8SEnrico Granata } 1777d64d0bc0SEnrico Granata var_success = true; 1778d64d0bc0SEnrico Granata break; 1779d64d0bc0SEnrico Granata } 1780d64d0bc0SEnrico Granata } 1781d64d0bc0SEnrico Granata 1782d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1783d64d0bc0SEnrico Granata // type @ location message 1784d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1785d64d0bc0SEnrico Granata { 1786d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1787d64d0bc0SEnrico Granata var_success = true; 178885933ed4SEnrico Granata break; 178985933ed4SEnrico Granata } 179085933ed4SEnrico Granata 1791d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 179286cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 179385933ed4SEnrico Granata { 179485933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 179585933ed4SEnrico Granata var_success = true; 1796f4efecd9SEnrico Granata break; 1797f4efecd9SEnrico Granata } 1798f4efecd9SEnrico Granata 17999fc1944eSEnrico Granata if (!is_array_range) 1800e992a089SEnrico Granata { 1801e992a089SEnrico Granata if (log) 1802d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 18039fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1804e992a089SEnrico Granata } 18059fc1944eSEnrico Granata else 18069fc1944eSEnrico Granata { 1807e992a089SEnrico Granata if (log) 1808d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 18099fc1944eSEnrico Granata if (!is_array && !is_pointer) 18109fc1944eSEnrico Granata break; 1811e992a089SEnrico Granata if (log) 1812d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] handle as array"); 1813fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1814fc7a7f3bSEnrico Granata StreamString special_directions_writer; 18150a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 18160a3958e0SEnrico Granata { 1817fc7a7f3bSEnrico Granata ConstString additional_data; 1818fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1819fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1820fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1821fc7a7f3bSEnrico Granata additional_data.GetCString()); 1822fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 18230a3958e0SEnrico Granata } 18240a3958e0SEnrico Granata 18250a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 18260a3958e0SEnrico Granata s.PutChar('['); 18270a3958e0SEnrico Granata var_success = true; 18280a3958e0SEnrico Granata 18299fc1944eSEnrico Granata if (index_higher < 0) 1830c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 18310a3958e0SEnrico Granata 1832cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 183322c55d18SEnrico Granata 18340a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 18350a3958e0SEnrico Granata { 1836fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 18379fc1944eSEnrico Granata index_lower, 1838c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1839fc7a7f3bSEnrico Granata false).get(); 18400a3958e0SEnrico Granata 1841fc7a7f3bSEnrico Granata if (!item) 1842fc7a7f3bSEnrico Granata { 1843e992a089SEnrico Granata if (log) 1844d01b2953SDaniel Malea log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1845fc7a7f3bSEnrico Granata } 1846fc7a7f3bSEnrico Granata else 1847fc7a7f3bSEnrico Granata { 1848e992a089SEnrico Granata if (log) 1849d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1850fc7a7f3bSEnrico Granata } 1851fc7a7f3bSEnrico Granata 18520a3958e0SEnrico Granata if (!special_directions) 18539fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 18540a3958e0SEnrico Granata else 1855c3ce7f27SMichael Sartain var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item); 18560a3958e0SEnrico Granata 185722c55d18SEnrico Granata if (--max_num_children == 0) 185822c55d18SEnrico Granata { 185922c55d18SEnrico Granata s.PutCString(", ..."); 186022c55d18SEnrico Granata break; 186122c55d18SEnrico Granata } 186222c55d18SEnrico Granata 18630a3958e0SEnrico Granata if (index_lower < index_higher) 18640a3958e0SEnrico Granata s.PutChar(','); 18650a3958e0SEnrico Granata } 18660a3958e0SEnrico Granata s.PutChar(']'); 18674becb37eSEnrico Granata } 18684becb37eSEnrico Granata } 186934132754SGreg Clayton break; 18701b654882SGreg Clayton case 'a': 1871*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "addr}")) 18721b654882SGreg Clayton { 18731b654882SGreg Clayton if (addr && addr->IsValid()) 18741b654882SGreg Clayton { 18751b654882SGreg Clayton var_success = true; 18761b654882SGreg Clayton format_addr = *addr; 18771b654882SGreg Clayton } 18781b654882SGreg Clayton } 18791b654882SGreg Clayton break; 18801b654882SGreg Clayton 18811b654882SGreg Clayton case 'p': 1882*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "process.")) 18831b654882SGreg Clayton { 1884c14ee32dSGreg Clayton if (exe_ctx) 1885c14ee32dSGreg Clayton { 1886c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 1887c14ee32dSGreg Clayton if (process) 18881b654882SGreg Clayton { 18891b654882SGreg Clayton var_name_begin += ::strlen ("process."); 1890*0769b2b1SMichael Sartain if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc)) 18911b654882SGreg Clayton { 1892*0769b2b1SMichael Sartain s.Printf(token_format.c_str(), process->GetID()); 18931b654882SGreg Clayton var_success = true; 18941b654882SGreg Clayton } 1895*0769b2b1SMichael Sartain else if ((IsToken (var_name_begin, "name}")) || 1896*0769b2b1SMichael Sartain (IsToken (var_name_begin, "file.basename}")) || 1897*0769b2b1SMichael Sartain (IsToken (var_name_begin, "file.fullpath}"))) 18981b654882SGreg Clayton { 1899c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1900aa149cbdSGreg Clayton if (exe_module) 19011b654882SGreg Clayton { 19021b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 19031b654882SGreg Clayton { 1904aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 19051b654882SGreg Clayton var_success = format_file_spec; 19061b654882SGreg Clayton } 19071b654882SGreg Clayton else 19081b654882SGreg Clayton { 1909aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 19101b654882SGreg Clayton var_success = format_file_spec; 19111b654882SGreg Clayton } 19121b654882SGreg Clayton } 19131b654882SGreg Clayton } 1914*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 1915aad8e480SEnrico Granata { 1916aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 1917aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 1918aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1919*0769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, process, script_name)) 1920aad8e480SEnrico Granata var_success = true; 1921aad8e480SEnrico Granata } 19221b654882SGreg Clayton } 19231b654882SGreg Clayton } 1924c14ee32dSGreg Clayton } 19251b654882SGreg Clayton break; 19261b654882SGreg Clayton 19271b654882SGreg Clayton case 't': 1928*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "thread.")) 19291b654882SGreg Clayton { 1930c14ee32dSGreg Clayton if (exe_ctx) 1931c14ee32dSGreg Clayton { 1932c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 1933c14ee32dSGreg Clayton if (thread) 19341b654882SGreg Clayton { 19351b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 1936*0769b2b1SMichael Sartain if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 19371b654882SGreg Clayton { 1938*0769b2b1SMichael Sartain s.Printf(token_format.c_str(), thread->GetID()); 19391b654882SGreg Clayton var_success = true; 19401b654882SGreg Clayton } 1941*0769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 1942160c9d81SGreg Clayton { 1943*0769b2b1SMichael Sartain s.Printf(token_format.c_str(), thread->GetProtocolID()); 1944160c9d81SGreg Clayton var_success = true; 1945160c9d81SGreg Clayton } 1946*0769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc)) 19471b654882SGreg Clayton { 1948*0769b2b1SMichael Sartain s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID()); 19491b654882SGreg Clayton var_success = true; 19501b654882SGreg Clayton } 1951*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name}")) 19521b654882SGreg Clayton { 1953c14ee32dSGreg Clayton cstr = thread->GetName(); 19541b654882SGreg Clayton var_success = cstr && cstr[0]; 19551b654882SGreg Clayton if (var_success) 19561b654882SGreg Clayton s.PutCString(cstr); 19571b654882SGreg Clayton } 1958*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "queue}")) 19591b654882SGreg Clayton { 1960c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 19611b654882SGreg Clayton var_success = cstr && cstr[0]; 19621b654882SGreg Clayton if (var_success) 19631b654882SGreg Clayton s.PutCString(cstr); 19641b654882SGreg Clayton } 1965*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "stop-reason}")) 19661b654882SGreg Clayton { 1967c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 19685d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 19691b654882SGreg Clayton { 1970b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 19711b654882SGreg Clayton if (cstr && cstr[0]) 19721b654882SGreg Clayton { 19731b654882SGreg Clayton s.PutCString(cstr); 19741b654882SGreg Clayton var_success = true; 19751b654882SGreg Clayton } 19761b654882SGreg Clayton } 19771b654882SGreg Clayton } 1978*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "return-value}")) 197973ca05a2SJim Ingham { 198073ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 19815d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 198273ca05a2SJim Ingham { 198373ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 198473ca05a2SJim Ingham if (return_valobj_sp) 198573ca05a2SJim Ingham { 19869fb5ab55SEnrico Granata ValueObject::DumpValueObject (s, return_valobj_sp.get()); 198773ca05a2SJim Ingham var_success = true; 198873ca05a2SJim Ingham } 198973ca05a2SJim Ingham } 199073ca05a2SJim Ingham } 1991*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 1992aad8e480SEnrico Granata { 1993aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 1994aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 1995aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1996*0769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name)) 1997aad8e480SEnrico Granata var_success = true; 1998aad8e480SEnrico Granata } 1999aad8e480SEnrico Granata } 2000aad8e480SEnrico Granata } 200173ca05a2SJim Ingham } 2002*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "target.")) 20031b654882SGreg Clayton { 200467cc0636SGreg Clayton // TODO: hookup properties 200567cc0636SGreg Clayton // if (!target_properties_sp) 200667cc0636SGreg Clayton // { 200767cc0636SGreg Clayton // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 200867cc0636SGreg Clayton // if (target) 200967cc0636SGreg Clayton // target_properties_sp = target->GetProperties(); 201067cc0636SGreg Clayton // } 201167cc0636SGreg Clayton // 201267cc0636SGreg Clayton // if (target_properties_sp) 201367cc0636SGreg Clayton // { 201467cc0636SGreg Clayton // var_name_begin += ::strlen ("target."); 201567cc0636SGreg Clayton // const char *end_property = strchr(var_name_begin, '}'); 201667cc0636SGreg Clayton // if (end_property) 201767cc0636SGreg Clayton // { 201867cc0636SGreg Clayton // ConstString property_name(var_name_begin, end_property - var_name_begin); 201967cc0636SGreg Clayton // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 202067cc0636SGreg Clayton // if (!property_value.empty()) 202167cc0636SGreg Clayton // { 202267cc0636SGreg Clayton // s.PutCString (property_value.c_str()); 202367cc0636SGreg Clayton // var_success = true; 202467cc0636SGreg Clayton // } 202567cc0636SGreg Clayton // } 202667cc0636SGreg Clayton // } 20270603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 20280603aa9dSGreg Clayton if (target) 20291b654882SGreg Clayton { 20301b654882SGreg Clayton var_name_begin += ::strlen ("target."); 2031*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "arch}")) 20321b654882SGreg Clayton { 20331b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 20341b654882SGreg Clayton if (arch.IsValid()) 20351b654882SGreg Clayton { 203664195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 20371b654882SGreg Clayton var_success = true; 20381b654882SGreg Clayton } 20391b654882SGreg Clayton } 2040*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 2041aad8e480SEnrico Granata { 2042aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2043aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2044aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2045*0769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, target, script_name)) 2046aad8e480SEnrico Granata var_success = true; 2047aad8e480SEnrico Granata } 20481b654882SGreg Clayton } 20491b654882SGreg Clayton } 20501b654882SGreg Clayton break; 20511b654882SGreg Clayton 20521b654882SGreg Clayton 20531b654882SGreg Clayton case 'm': 2054*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "module.")) 20551b654882SGreg Clayton { 20560603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 20571b654882SGreg Clayton { 20580603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 20591b654882SGreg Clayton var_name_begin += ::strlen ("module."); 20601b654882SGreg Clayton 2061*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 20621b654882SGreg Clayton { 20631b654882SGreg Clayton if (module->GetFileSpec()) 20641b654882SGreg Clayton { 20651b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20661b654882SGreg Clayton 2067*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 20681b654882SGreg Clayton { 20691b654882SGreg Clayton format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 20701b654882SGreg Clayton var_success = format_file_spec; 20711b654882SGreg Clayton } 2072*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 20731b654882SGreg Clayton { 20741b654882SGreg Clayton format_file_spec = module->GetFileSpec(); 20751b654882SGreg Clayton var_success = format_file_spec; 20761b654882SGreg Clayton } 20771b654882SGreg Clayton } 20781b654882SGreg Clayton } 20791b654882SGreg Clayton } 20801b654882SGreg Clayton } 20811b654882SGreg Clayton break; 20821b654882SGreg Clayton 20831b654882SGreg Clayton 20841b654882SGreg Clayton case 'f': 2085*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 20861b654882SGreg Clayton { 20871b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 20881b654882SGreg Clayton { 20891b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20901b654882SGreg Clayton 2091*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 20921b654882SGreg Clayton { 20931b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 20941b654882SGreg Clayton var_success = format_file_spec; 20951b654882SGreg Clayton } 2096*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 20971b654882SGreg Clayton { 20981b654882SGreg Clayton format_file_spec = *sc->comp_unit; 20991b654882SGreg Clayton var_success = format_file_spec; 21001b654882SGreg Clayton } 21011b654882SGreg Clayton } 21021b654882SGreg Clayton } 2103*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "frame.")) 21041b654882SGreg Clayton { 2105c14ee32dSGreg Clayton if (exe_ctx) 2106c14ee32dSGreg Clayton { 2107c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2108c14ee32dSGreg Clayton if (frame) 21091b654882SGreg Clayton { 21101b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 2111*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "index}")) 21121b654882SGreg Clayton { 2113c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 21141b654882SGreg Clayton var_success = true; 21151b654882SGreg Clayton } 2116*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "pc}")) 21171b654882SGreg Clayton { 21181b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21191b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 21201b654882SGreg Clayton var_success = true; 21211b654882SGreg Clayton } 2122*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "sp}")) 21231b654882SGreg Clayton { 21241b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21251b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 21261b654882SGreg Clayton var_success = true; 21271b654882SGreg Clayton } 2128*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fp}")) 21291b654882SGreg Clayton { 21301b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21311b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 21321b654882SGreg Clayton var_success = true; 21331b654882SGreg Clayton } 2134*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "flags}")) 21351b654882SGreg Clayton { 21361b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 21371b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 21381b654882SGreg Clayton var_success = true; 21391b654882SGreg Clayton } 2140*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "reg.")) 21411b654882SGreg Clayton { 2142c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 21431b654882SGreg Clayton if (reg_ctx) 21441b654882SGreg Clayton { 21451b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 21461b654882SGreg Clayton if (var_name_begin < var_name_end) 21471b654882SGreg Clayton { 21481b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 21491b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 21501b654882SGreg Clayton if (reg_info) 21511b654882SGreg Clayton var_success = true; 21521b654882SGreg Clayton } 21531b654882SGreg Clayton } 21541b654882SGreg Clayton } 2155*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 2156aad8e480SEnrico Granata { 2157aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2158aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2159aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2160*0769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name)) 2161aad8e480SEnrico Granata var_success = true; 2162aad8e480SEnrico Granata } 2163aad8e480SEnrico Granata } 2164aad8e480SEnrico Granata } 21651b654882SGreg Clayton } 2166*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "function.")) 21671b654882SGreg Clayton { 21681b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 21691b654882SGreg Clayton { 21701b654882SGreg Clayton var_name_begin += ::strlen ("function."); 2171*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "id}")) 21721b654882SGreg Clayton { 21731b654882SGreg Clayton if (sc->function) 2174d01b2953SDaniel Malea s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 21751b654882SGreg Clayton else 21761b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 21771b654882SGreg Clayton 21781b654882SGreg Clayton var_success = true; 21791b654882SGreg Clayton } 2180*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name}")) 21811b654882SGreg Clayton { 21821b654882SGreg Clayton if (sc->function) 21831b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21841b654882SGreg Clayton else if (sc->symbol) 21851b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 21861b654882SGreg Clayton if (cstr) 21871b654882SGreg Clayton { 21881b654882SGreg Clayton s.PutCString(cstr); 21890d9c9934SGreg Clayton 21900d9c9934SGreg Clayton if (sc->block) 21910d9c9934SGreg Clayton { 21920d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 21930d9c9934SGreg Clayton if (inline_block) 21940d9c9934SGreg Clayton { 21950d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 21960d9c9934SGreg Clayton if (inline_info) 21970d9c9934SGreg Clayton { 21980d9c9934SGreg Clayton s.PutCString(" [inlined] "); 21990d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 22000d9c9934SGreg Clayton } 22010d9c9934SGreg Clayton } 22020d9c9934SGreg Clayton } 22031b654882SGreg Clayton var_success = true; 22041b654882SGreg Clayton } 22051b654882SGreg Clayton } 2206*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name-with-args}")) 22076d3dbf51SGreg Clayton { 22086d3dbf51SGreg Clayton // Print the function name with arguments in it 22096d3dbf51SGreg Clayton 22106d3dbf51SGreg Clayton if (sc->function) 22116d3dbf51SGreg Clayton { 22126d3dbf51SGreg Clayton var_success = true; 22136d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 22146d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 22156d3dbf51SGreg Clayton if (cstr) 22166d3dbf51SGreg Clayton { 22176d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 22186d3dbf51SGreg Clayton VariableListSP variable_list_sp; 22196d3dbf51SGreg Clayton bool get_function_vars = true; 22206d3dbf51SGreg Clayton if (sc->block) 22216d3dbf51SGreg Clayton { 22226d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 22236d3dbf51SGreg Clayton 22246d3dbf51SGreg Clayton if (inline_block) 22256d3dbf51SGreg Clayton { 22266d3dbf51SGreg Clayton get_function_vars = false; 22276d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 22286d3dbf51SGreg Clayton if (inline_info) 22296d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 22306d3dbf51SGreg Clayton } 22316d3dbf51SGreg Clayton } 22326d3dbf51SGreg Clayton 22336d3dbf51SGreg Clayton if (get_function_vars) 22346d3dbf51SGreg Clayton { 22356d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 22366d3dbf51SGreg Clayton } 22376d3dbf51SGreg Clayton 22386d3dbf51SGreg Clayton if (inline_info) 22396d3dbf51SGreg Clayton { 22406d3dbf51SGreg Clayton s.PutCString (cstr); 22416d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 22426d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 22436d3dbf51SGreg Clayton } 22446d3dbf51SGreg Clayton 22456d3dbf51SGreg Clayton VariableList args; 22466d3dbf51SGreg Clayton if (variable_list_sp) 2247cc7f9bf5SEnrico Granata variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 22486d3dbf51SGreg Clayton if (args.GetSize() > 0) 22496d3dbf51SGreg Clayton { 22506d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 22516d3dbf51SGreg Clayton const char *close_paren = NULL; 22526d3dbf51SGreg Clayton if (open_paren) 2253855958caSGreg Clayton { 2254*0769b2b1SMichael Sartain if (IsToken (open_paren, "(anonymous namespace)")) 2255855958caSGreg Clayton { 2256855958caSGreg Clayton open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2257855958caSGreg Clayton if (open_paren) 22586d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 2259855958caSGreg Clayton } 2260855958caSGreg Clayton else 2261855958caSGreg Clayton close_paren = strchr (open_paren, ')'); 2262855958caSGreg Clayton } 22636d3dbf51SGreg Clayton 22646d3dbf51SGreg Clayton if (open_paren) 22656d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 22666d3dbf51SGreg Clayton else 22676d3dbf51SGreg Clayton { 22686d3dbf51SGreg Clayton s.PutCString (cstr); 22696d3dbf51SGreg Clayton s.PutChar ('('); 22706d3dbf51SGreg Clayton } 22715b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 22726d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 22736d3dbf51SGreg Clayton { 22746d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 22756d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 22766d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 22776d3dbf51SGreg Clayton const char *var_value = var_value_sp->GetValueAsCString(); 22786d3dbf51SGreg Clayton if (arg_idx > 0) 22796d3dbf51SGreg Clayton s.PutCString (", "); 22803b188b17SGreg Clayton if (var_value_sp->GetError().Success()) 2281cc7f9bf5SEnrico Granata { 2282cc7f9bf5SEnrico Granata if (var_value) 22836d3dbf51SGreg Clayton s.Printf ("%s=%s", var_name, var_value); 22843b188b17SGreg Clayton else 2285cc7f9bf5SEnrico Granata s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2286cc7f9bf5SEnrico Granata } 2287cc7f9bf5SEnrico Granata else 22883b188b17SGreg Clayton s.Printf ("%s=<unavailable>", var_name); 22896d3dbf51SGreg Clayton } 22906d3dbf51SGreg Clayton 22916d3dbf51SGreg Clayton if (close_paren) 22926d3dbf51SGreg Clayton s.PutCString (close_paren); 22936d3dbf51SGreg Clayton else 22946d3dbf51SGreg Clayton s.PutChar(')'); 22956d3dbf51SGreg Clayton 22966d3dbf51SGreg Clayton } 22976d3dbf51SGreg Clayton else 22986d3dbf51SGreg Clayton { 22996d3dbf51SGreg Clayton s.PutCString(cstr); 23006d3dbf51SGreg Clayton } 23016d3dbf51SGreg Clayton } 23026d3dbf51SGreg Clayton } 23036d3dbf51SGreg Clayton else if (sc->symbol) 23046d3dbf51SGreg Clayton { 23056d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 23066d3dbf51SGreg Clayton if (cstr) 23076d3dbf51SGreg Clayton { 23086d3dbf51SGreg Clayton s.PutCString(cstr); 23096d3dbf51SGreg Clayton var_success = true; 23106d3dbf51SGreg Clayton } 23116d3dbf51SGreg Clayton } 23126d3dbf51SGreg Clayton } 2313*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "addr-offset}")) 23141b654882SGreg Clayton { 23151b654882SGreg Clayton var_success = addr != NULL; 23161b654882SGreg Clayton if (var_success) 23171b654882SGreg Clayton { 23181b654882SGreg Clayton format_addr = *addr; 23191b654882SGreg Clayton calculate_format_addr_function_offset = true; 23201b654882SGreg Clayton } 23211b654882SGreg Clayton } 2322*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "line-offset}")) 23231b654882SGreg Clayton { 23241b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 23251b654882SGreg Clayton if (var_success) 23261b654882SGreg Clayton { 23271b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23281b654882SGreg Clayton calculate_format_addr_function_offset = true; 23291b654882SGreg Clayton } 23301b654882SGreg Clayton } 2331*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "pc-offset}")) 23321b654882SGreg Clayton { 2333c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2334c14ee32dSGreg Clayton var_success = frame != NULL; 23351b654882SGreg Clayton if (var_success) 23361b654882SGreg Clayton { 2337c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23381b654882SGreg Clayton calculate_format_addr_function_offset = true; 23391b654882SGreg Clayton } 23401b654882SGreg Clayton } 23411b654882SGreg Clayton } 23421b654882SGreg Clayton } 23431b654882SGreg Clayton break; 23441b654882SGreg Clayton 23451b654882SGreg Clayton case 'l': 2346*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "line.")) 23471b654882SGreg Clayton { 23481b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 23491b654882SGreg Clayton { 23501b654882SGreg Clayton var_name_begin += ::strlen ("line."); 2351*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 23521b654882SGreg Clayton { 23531b654882SGreg Clayton var_name_begin += ::strlen ("file."); 23541b654882SGreg Clayton 2355*0769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 23561b654882SGreg Clayton { 23571b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 23581b654882SGreg Clayton var_success = format_file_spec; 23591b654882SGreg Clayton } 2360*0769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 23611b654882SGreg Clayton { 23621b654882SGreg Clayton format_file_spec = sc->line_entry.file; 23631b654882SGreg Clayton var_success = format_file_spec; 23641b654882SGreg Clayton } 23651b654882SGreg Clayton } 2366*0769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc)) 23671b654882SGreg Clayton { 23681b654882SGreg Clayton var_success = true; 2369*0769b2b1SMichael Sartain s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line); 23701b654882SGreg Clayton } 2371*0769b2b1SMichael Sartain else if ((IsToken (var_name_begin, "start-addr}")) || 2372*0769b2b1SMichael Sartain (IsToken (var_name_begin, "end-addr}"))) 23731b654882SGreg Clayton { 23741b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 23751b654882SGreg Clayton if (var_success) 23761b654882SGreg Clayton { 23771b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23781b654882SGreg Clayton if (var_name_begin[0] == 'e') 23791b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 23801b654882SGreg Clayton } 23811b654882SGreg Clayton } 23821b654882SGreg Clayton } 23831b654882SGreg Clayton } 23841b654882SGreg Clayton break; 23851b654882SGreg Clayton } 23861b654882SGreg Clayton 23871b654882SGreg Clayton if (var_success) 23881b654882SGreg Clayton { 23891b654882SGreg Clayton // If format addr is valid, then we need to print an address 23901b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 23911b654882SGreg Clayton { 2392c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 23931b654882SGreg Clayton // We have a register value to display... 23941b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 23951b654882SGreg Clayton { 2396c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23971b654882SGreg Clayton } 23981b654882SGreg Clayton else 23991b654882SGreg Clayton { 24001b654882SGreg Clayton if (reg_ctx == NULL) 2401c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 24021b654882SGreg Clayton 24031b654882SGreg Clayton if (reg_ctx) 24041b654882SGreg Clayton { 24051b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 24061b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 24071b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 24081b654882SGreg Clayton var_success = reg_info != NULL; 24091b654882SGreg Clayton } 24101b654882SGreg Clayton } 24111b654882SGreg Clayton } 24121b654882SGreg Clayton 24131b654882SGreg Clayton if (reg_info != NULL) 24141b654882SGreg Clayton { 24157349bd90SGreg Clayton RegisterValue reg_value; 24167349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 24177349bd90SGreg Clayton if (var_success) 24181b654882SGreg Clayton { 24199a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 24201b654882SGreg Clayton } 24211b654882SGreg Clayton } 24221b654882SGreg Clayton 24231b654882SGreg Clayton if (format_file_spec) 24241b654882SGreg Clayton { 24251b654882SGreg Clayton s << format_file_spec; 24261b654882SGreg Clayton } 24271b654882SGreg Clayton 24281b654882SGreg Clayton // If format addr is valid, then we need to print an address 24291b654882SGreg Clayton if (format_addr.IsValid()) 24301b654882SGreg Clayton { 24310603aa9dSGreg Clayton var_success = false; 24320603aa9dSGreg Clayton 24331b654882SGreg Clayton if (calculate_format_addr_function_offset) 24341b654882SGreg Clayton { 24351b654882SGreg Clayton Address func_addr; 24360603aa9dSGreg Clayton 24370603aa9dSGreg Clayton if (sc) 24380603aa9dSGreg Clayton { 24391b654882SGreg Clayton if (sc->function) 24400d9c9934SGreg Clayton { 24411b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 24420d9c9934SGreg Clayton if (sc->block) 24430d9c9934SGreg Clayton { 24440d9c9934SGreg Clayton // Check to make sure we aren't in an inline 24450d9c9934SGreg Clayton // function. If we are, use the inline block 24460d9c9934SGreg Clayton // range that contains "format_addr" since 24470d9c9934SGreg Clayton // blocks can be discontiguous. 24480d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 24490d9c9934SGreg Clayton AddressRange inline_range; 24500d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 24510d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 24520d9c9934SGreg Clayton } 24530d9c9934SGreg Clayton } 2454e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2455e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 24560603aa9dSGreg Clayton } 24571b654882SGreg Clayton 24580603aa9dSGreg Clayton if (func_addr.IsValid()) 24591b654882SGreg Clayton { 24601b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 24611b654882SGreg Clayton { 24621b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 24631b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 24641b654882SGreg Clayton if (addr_file_addr > func_file_addr) 2465d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 24661b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 2467d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 24680603aa9dSGreg Clayton var_success = true; 24691b654882SGreg Clayton } 24701b654882SGreg Clayton else 24710603aa9dSGreg Clayton { 24720603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24730603aa9dSGreg Clayton if (target) 24740603aa9dSGreg Clayton { 24750603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 24760603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 24770603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 2478d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 24790603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 2480d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 24810603aa9dSGreg Clayton var_success = true; 24820603aa9dSGreg Clayton } 24830603aa9dSGreg Clayton } 24841b654882SGreg Clayton } 24851b654882SGreg Clayton } 24861b654882SGreg Clayton else 24871b654882SGreg Clayton { 24880603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24891b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 24900603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 24910603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 24921b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 24931b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 24941b654882SGreg Clayton 24951b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 24960603aa9dSGreg Clayton { 2497514487e8SGreg Clayton int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 249835f1a0d5SGreg Clayton if (addr_width == 0) 249935f1a0d5SGreg Clayton addr_width = 16; 2500d01b2953SDaniel Malea s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 25010603aa9dSGreg Clayton var_success = true; 25020603aa9dSGreg Clayton } 25031b654882SGreg Clayton } 25041b654882SGreg Clayton } 25051b654882SGreg Clayton } 25061b654882SGreg Clayton 25071b654882SGreg Clayton if (var_success == false) 25081b654882SGreg Clayton success = false; 25091b654882SGreg Clayton } 25101b654882SGreg Clayton p = var_name_end; 25111b654882SGreg Clayton } 25121b654882SGreg Clayton else 25131b654882SGreg Clayton break; 25141b654882SGreg Clayton } 25151b654882SGreg Clayton else 25161b654882SGreg Clayton { 25171b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 25181b654882SGreg Clayton s.PutChar(*p); 25191b654882SGreg Clayton } 25201b654882SGreg Clayton } 25211b654882SGreg Clayton else if (*p == '\\') 25221b654882SGreg Clayton { 25231b654882SGreg Clayton ++p; // skip the slash 25241b654882SGreg Clayton switch (*p) 25251b654882SGreg Clayton { 25261b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 25271b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 25281b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 25291b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 25301b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 25311b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 25321b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 25331b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 25341b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 25351b654882SGreg Clayton case '0': 25361b654882SGreg Clayton // 1 to 3 octal chars 25371b654882SGreg Clayton { 25380603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 25390603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 25400603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 25410603aa9dSGreg Clayton 25420603aa9dSGreg Clayton int i; 25430603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 25440603aa9dSGreg Clayton oct_str[i] = p[i]; 25450603aa9dSGreg Clayton 25460603aa9dSGreg Clayton // We don't want to consume the last octal character since 25470603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 25480603aa9dSGreg Clayton // one less than i (even if i is zero) 25490603aa9dSGreg Clayton p += i - 1; 25500603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 25510603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 25521b654882SGreg Clayton { 2553c7bece56SGreg Clayton s.PutChar((char)octal_value); 25541b654882SGreg Clayton } 25551b654882SGreg Clayton } 25561b654882SGreg Clayton break; 25571b654882SGreg Clayton 25581b654882SGreg Clayton case 'x': 25591b654882SGreg Clayton // hex number in the format 25600603aa9dSGreg Clayton if (isxdigit(p[1])) 25611b654882SGreg Clayton { 25620603aa9dSGreg Clayton ++p; // Skip the 'x' 25631b654882SGreg Clayton 25640603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 25650603aa9dSGreg Clayton // NULL terminator 25661b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 25671b654882SGreg Clayton hex_str[0] = *p; 25680603aa9dSGreg Clayton if (isxdigit(p[1])) 25690603aa9dSGreg Clayton { 25700603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 25711b654882SGreg Clayton hex_str[1] = *p; 25720603aa9dSGreg Clayton } 25730603aa9dSGreg Clayton 25741b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 25750603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 2576c7bece56SGreg Clayton s.PutChar ((char)hex_value); 25771b654882SGreg Clayton } 25781b654882SGreg Clayton else 25791b654882SGreg Clayton { 25800603aa9dSGreg Clayton s.PutChar('x'); 25811b654882SGreg Clayton } 25821b654882SGreg Clayton break; 25831b654882SGreg Clayton 25841b654882SGreg Clayton default: 25850603aa9dSGreg Clayton // Just desensitize any other character by just printing what 25860603aa9dSGreg Clayton // came after the '\' 25870603aa9dSGreg Clayton s << *p; 25881b654882SGreg Clayton break; 25891b654882SGreg Clayton 25901b654882SGreg Clayton } 25911b654882SGreg Clayton 25921b654882SGreg Clayton } 25931b654882SGreg Clayton } 25941b654882SGreg Clayton if (end) 25951b654882SGreg Clayton *end = p; 25961b654882SGreg Clayton return success; 25971b654882SGreg Clayton } 25981b654882SGreg Clayton 2599c3ce7f27SMichael Sartain bool 2600c3ce7f27SMichael Sartain Debugger::FormatPrompt 2601c3ce7f27SMichael Sartain ( 2602c3ce7f27SMichael Sartain const char *format, 2603c3ce7f27SMichael Sartain const SymbolContext *sc, 2604c3ce7f27SMichael Sartain const ExecutionContext *exe_ctx, 2605c3ce7f27SMichael Sartain const Address *addr, 2606c3ce7f27SMichael Sartain Stream &s, 2607c3ce7f27SMichael Sartain ValueObject* valobj 2608c3ce7f27SMichael Sartain ) 2609c3ce7f27SMichael Sartain { 2610c3ce7f27SMichael Sartain bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true; 2611c3ce7f27SMichael Sartain std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color); 2612c3ce7f27SMichael Sartain if (format_str.length()) 2613c3ce7f27SMichael Sartain format = format_str.c_str(); 2614c3ce7f27SMichael Sartain return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj); 2615c3ce7f27SMichael Sartain } 2616c3ce7f27SMichael Sartain 2617228063cdSJim Ingham void 2618228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2619228063cdSJim Ingham { 26204f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 26214f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 26224f02b22dSJim Ingham // callback. 2623228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2624228063cdSJim Ingham } 2625228063cdSJim Ingham 2626228063cdSJim Ingham bool 2627228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2628228063cdSJim Ingham { 2629228063cdSJim Ingham Log::Callbacks log_callbacks; 2630228063cdSJim Ingham 2631228063cdSJim Ingham StreamSP log_stream_sp; 26329a028519SSean Callanan if (m_log_callback_stream_sp) 2633228063cdSJim Ingham { 2634228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2635228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2636228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2637228063cdSJim Ingham } 2638228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2639228063cdSJim Ingham { 2640228063cdSJim Ingham log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false)); 2641228063cdSJim Ingham } 2642228063cdSJim Ingham else 2643228063cdSJim Ingham { 2644228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2645c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 2646c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 2647c1b2ccfdSGreg Clayton if (!log_stream_sp) 2648228063cdSJim Ingham { 2649228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2650228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2651228063cdSJim Ingham } 2652228063cdSJim Ingham } 2653228063cdSJim Ingham assert (log_stream_sp.get()); 2654228063cdSJim Ingham 2655228063cdSJim Ingham if (log_options == 0) 2656228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2657228063cdSJim Ingham 265857abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 2659228063cdSJim Ingham { 2660228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2661228063cdSJim Ingham return true; 2662228063cdSJim Ingham } 2663228063cdSJim Ingham else 2664228063cdSJim Ingham { 2665228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2666228063cdSJim Ingham if (log_channel_sp) 2667228063cdSJim Ingham { 2668228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2669228063cdSJim Ingham { 2670228063cdSJim Ingham return true; 2671228063cdSJim Ingham } 2672228063cdSJim Ingham else 2673228063cdSJim Ingham { 2674228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2675228063cdSJim Ingham return false; 2676228063cdSJim Ingham } 2677228063cdSJim Ingham } 2678228063cdSJim Ingham else 2679228063cdSJim Ingham { 2680228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2681228063cdSJim Ingham return false; 2682228063cdSJim Ingham } 2683228063cdSJim Ingham } 2684228063cdSJim Ingham return false; 2685228063cdSJim Ingham } 2686228063cdSJim Ingham 26879585fbfcSGreg Clayton SourceManager & 26889585fbfcSGreg Clayton Debugger::GetSourceManager () 26899585fbfcSGreg Clayton { 26909585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 26919585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 26929585fbfcSGreg Clayton return *m_source_manager_ap; 26939585fbfcSGreg Clayton } 26949585fbfcSGreg Clayton 26959585fbfcSGreg Clayton 2696