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 10267cc0636SGreg Clayton #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 10367cc0636SGreg Clayton "{, ${frame.pc}}"\ 10467cc0636SGreg Clayton MODULE_WITH_FUNC\ 10567cc0636SGreg Clayton FILE_AND_LINE\ 10685d0c57bSGreg Clayton "{, name = '${thread.name}}"\ 10785d0c57bSGreg Clayton "{, 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); 41621dfcd9dSEnrico Granata // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays 41721dfcd9dSEnrico Granata LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); 41821dfcd9dSEnrico Granata if (!init_func) 419e743c782SEnrico Granata { 420e743c782SEnrico Granata error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)"); 42121dfcd9dSEnrico Granata return false; 422e743c782SEnrico Granata } 42321dfcd9dSEnrico Granata if (init_func(debugger_sb)) 42421dfcd9dSEnrico Granata { 42521dfcd9dSEnrico Granata m_loaded_plugins.push_back(dynlib_sp); 42621dfcd9dSEnrico Granata return true; 42721dfcd9dSEnrico Granata } 428e743c782SEnrico Granata error.SetErrorString("dylib refused to be loaded"); 42921dfcd9dSEnrico Granata return false; 43021dfcd9dSEnrico Granata } 43121dfcd9dSEnrico Granata 43221dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 43321dfcd9dSEnrico Granata LoadPluginCallback 43421dfcd9dSEnrico Granata ( 43521dfcd9dSEnrico Granata void *baton, 43621dfcd9dSEnrico Granata FileSpec::FileType file_type, 43721dfcd9dSEnrico Granata const FileSpec &file_spec 43821dfcd9dSEnrico Granata ) 43921dfcd9dSEnrico Granata { 44021dfcd9dSEnrico Granata Error error; 44121dfcd9dSEnrico Granata 44221dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 44321dfcd9dSEnrico Granata 44421dfcd9dSEnrico Granata if (!baton) 44521dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 44621dfcd9dSEnrico Granata 44721dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 44821dfcd9dSEnrico Granata 44921dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 45021dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 45121dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 45221dfcd9dSEnrico Granata // file type information. 45321dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 45421dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 45521dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 45621dfcd9dSEnrico Granata { 45721dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 45821dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 45921dfcd9dSEnrico Granata 46021dfcd9dSEnrico Granata if (plugin_file_spec.GetFileNameExtension() != g_dylibext) 46121dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 46221dfcd9dSEnrico Granata 463e743c782SEnrico Granata Error plugin_load_error; 464e743c782SEnrico Granata debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 46521dfcd9dSEnrico Granata 46621dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 46721dfcd9dSEnrico Granata } 46821dfcd9dSEnrico Granata 46921dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 47021dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 47121dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 47221dfcd9dSEnrico Granata { 47321dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 47421dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 47521dfcd9dSEnrico Granata // might be enurating a file system that doesn't have correct file type 47621dfcd9dSEnrico Granata // information. 47721dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 47821dfcd9dSEnrico Granata } 47921dfcd9dSEnrico Granata 48021dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 48121dfcd9dSEnrico Granata } 48221dfcd9dSEnrico Granata 48321dfcd9dSEnrico Granata void 48421dfcd9dSEnrico Granata Debugger::InstanceInitialize () 48521dfcd9dSEnrico Granata { 48621dfcd9dSEnrico Granata FileSpec dir_spec; 48721dfcd9dSEnrico Granata const bool find_directories = true; 48821dfcd9dSEnrico Granata const bool find_files = true; 48921dfcd9dSEnrico Granata const bool find_other = true; 49021dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 49121dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) 49221dfcd9dSEnrico Granata { 49321dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 49421dfcd9dSEnrico Granata { 49521dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 49621dfcd9dSEnrico Granata find_directories, 49721dfcd9dSEnrico Granata find_files, 49821dfcd9dSEnrico Granata find_other, 49921dfcd9dSEnrico Granata LoadPluginCallback, 50021dfcd9dSEnrico Granata this); 50121dfcd9dSEnrico Granata } 50221dfcd9dSEnrico Granata } 50321dfcd9dSEnrico Granata 50421dfcd9dSEnrico Granata if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) 50521dfcd9dSEnrico Granata { 50621dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 50721dfcd9dSEnrico Granata { 50821dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 50921dfcd9dSEnrico Granata find_directories, 51021dfcd9dSEnrico Granata find_files, 51121dfcd9dSEnrico Granata find_other, 51221dfcd9dSEnrico Granata LoadPluginCallback, 51321dfcd9dSEnrico Granata this); 51421dfcd9dSEnrico Granata } 51521dfcd9dSEnrico Granata } 516e8cd0c98SGreg Clayton 517e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 51821dfcd9dSEnrico Granata } 51921dfcd9dSEnrico Granata 5206611103cSGreg Clayton DebuggerSP 521228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 5226611103cSGreg Clayton { 523228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 524c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 5256611103cSGreg Clayton { 5266611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5276611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 5286611103cSGreg Clayton } 52921dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 5306611103cSGreg Clayton return debugger_sp; 5316611103cSGreg Clayton } 5326611103cSGreg Clayton 533e02657b1SCaroline Tice void 5344d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 535e02657b1SCaroline Tice { 536e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 537e02657b1SCaroline Tice return; 538e02657b1SCaroline Tice 5398314c525SJim Ingham debugger_sp->Clear(); 5408314c525SJim Ingham 541c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 542c15f55e2SGreg Clayton { 543e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 544e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 545e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 546e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 547e02657b1SCaroline Tice { 548e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 549e02657b1SCaroline Tice { 550e02657b1SCaroline Tice debugger_list.erase (pos); 551e02657b1SCaroline Tice return; 552e02657b1SCaroline Tice } 553e02657b1SCaroline Tice } 554e02657b1SCaroline Tice } 555c15f55e2SGreg Clayton } 556e02657b1SCaroline Tice 5574d122c40SGreg Clayton DebuggerSP 5583df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 5593df9a8dfSCaroline Tice { 5604d122c40SGreg Clayton DebuggerSP debugger_sp; 5616920b52bSGreg Clayton if (g_shared_debugger_refcount > 0) 5626920b52bSGreg Clayton { 5636920b52bSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5646920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5656920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5666920b52bSGreg Clayton 5676920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5686920b52bSGreg Clayton { 5696920b52bSGreg Clayton if ((*pos).get()->m_instance_name == instance_name) 5706920b52bSGreg Clayton { 5716920b52bSGreg Clayton debugger_sp = *pos; 5726920b52bSGreg Clayton break; 5736920b52bSGreg Clayton } 5746920b52bSGreg Clayton } 5756920b52bSGreg Clayton } 5763df9a8dfSCaroline Tice return debugger_sp; 5773df9a8dfSCaroline Tice } 5786611103cSGreg Clayton 5796611103cSGreg Clayton TargetSP 5806611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 5816611103cSGreg Clayton { 5824d122c40SGreg Clayton TargetSP target_sp; 583c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 584c15f55e2SGreg Clayton { 5856611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5866611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5876611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5886611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 5896611103cSGreg Clayton { 5906611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 5916611103cSGreg Clayton if (target_sp) 5926611103cSGreg Clayton break; 5936611103cSGreg Clayton } 594c15f55e2SGreg Clayton } 5956611103cSGreg Clayton return target_sp; 5966611103cSGreg Clayton } 5976611103cSGreg Clayton 598e4e45924SGreg Clayton TargetSP 599e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 600e4e45924SGreg Clayton { 601e4e45924SGreg Clayton TargetSP target_sp; 602c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 603c15f55e2SGreg Clayton { 604e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 605e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 606e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 607e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 608e4e45924SGreg Clayton { 609e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 610e4e45924SGreg Clayton if (target_sp) 611e4e45924SGreg Clayton break; 612e4e45924SGreg Clayton } 613c15f55e2SGreg Clayton } 614e4e45924SGreg Clayton return target_sp; 615e4e45924SGreg Clayton } 616e4e45924SGreg Clayton 617228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 618ebc1bb27SCaroline Tice UserID (g_unique_id++), 61967cc0636SGreg Clayton Properties(OptionValuePropertiesSP(new OptionValueProperties())), 620d46c87a1SGreg Clayton m_input_comm("debugger.input"), 62130fdc8d8SChris Lattner m_input_file (), 62230fdc8d8SChris Lattner m_output_file (), 62330fdc8d8SChris Lattner m_error_file (), 624c5917d9aSJim Ingham m_terminal_state (), 6254bddaeb5SJim Ingham m_target_list (*this), 626ded470d3SGreg Clayton m_platform_list (), 62730fdc8d8SChris Lattner m_listener ("lldb.Debugger"), 6289585fbfcSGreg Clayton m_source_manager_ap(), 629e37d605eSJim Ingham m_source_file_cache(), 6306611103cSGreg Clayton m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 631d5a0a01bSCaroline Tice m_input_reader_stack (), 63267cc0636SGreg Clayton m_input_reader_data (), 63367cc0636SGreg Clayton m_instance_name() 63430fdc8d8SChris Lattner { 63567cc0636SGreg Clayton char instance_cstr[256]; 63667cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 63767cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 638228063cdSJim Ingham if (log_callback) 639228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 6406611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 641ded470d3SGreg Clayton // Always add our default platform to the platform list 642ded470d3SGreg Clayton PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 643ded470d3SGreg Clayton assert (default_platform_sp.get()); 644ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 64567cc0636SGreg Clayton 646754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 64767cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 64867cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 64967cc0636SGreg Clayton true, 65067cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 651754a9369SGreg Clayton if (m_command_interpreter_ap.get()) 652754a9369SGreg Clayton { 653754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 654754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 655754a9369SGreg Clayton true, 656754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 657754a9369SGreg Clayton } 65867cc0636SGreg Clayton OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 65967cc0636SGreg Clayton term_width->SetMinimumValue(10); 66067cc0636SGreg Clayton term_width->SetMaximumValue(1024); 661c3ce7f27SMichael Sartain 662c3ce7f27SMichael Sartain // Turn off use-color if this is a dumb terminal. 663c3ce7f27SMichael Sartain const char *term = getenv ("TERM"); 664c3ce7f27SMichael Sartain if (term && !strcmp (term, "dumb")) 665c3ce7f27SMichael Sartain SetUseColor (false); 66630fdc8d8SChris Lattner } 66730fdc8d8SChris Lattner 66830fdc8d8SChris Lattner Debugger::~Debugger () 66930fdc8d8SChris Lattner { 6708314c525SJim Ingham Clear(); 6718314c525SJim Ingham } 6728314c525SJim Ingham 6738314c525SJim Ingham void 6748314c525SJim Ingham Debugger::Clear() 6758314c525SJim Ingham { 6763d6086f6SCaroline Tice CleanUpInputReaders(); 6771ed54f50SGreg Clayton m_listener.Clear(); 6786611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 6796611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 6806611103cSGreg Clayton { 681ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 682ccbc08e6SGreg Clayton if (target_sp) 683ccbc08e6SGreg Clayton { 684ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 6856611103cSGreg Clayton if (process_sp) 6861fd07059SJim Ingham process_sp->Finalize(); 687ccbc08e6SGreg Clayton target_sp->Destroy(); 6886611103cSGreg Clayton } 68930fdc8d8SChris Lattner } 6904bddaeb5SJim Ingham BroadcasterManager::Clear (); 69130fdc8d8SChris Lattner 6920d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 6930d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 694c5917d9aSJim Ingham m_terminal_state.Clear(); 6950d69a3a4SGreg Clayton GetInputFile().Close (); 6960d69a3a4SGreg Clayton // Now that we have closed m_input_file, we can now tell our input communication 6970d69a3a4SGreg Clayton // class to close down. Its read thread should quickly exit after we close 6980d69a3a4SGreg Clayton // the input file handle above. 6990d69a3a4SGreg Clayton m_input_comm.Clear (); 7008314c525SJim Ingham } 70130fdc8d8SChris Lattner 70230fdc8d8SChris Lattner bool 703fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 704fc3f027dSGreg Clayton { 705fc3f027dSGreg Clayton return m_input_comm.GetCloseOnEOF(); 706fc3f027dSGreg Clayton } 707fc3f027dSGreg Clayton 708fc3f027dSGreg Clayton void 709fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 710fc3f027dSGreg Clayton { 711fc3f027dSGreg Clayton m_input_comm.SetCloseOnEOF(b); 712fc3f027dSGreg Clayton } 713fc3f027dSGreg Clayton 714fc3f027dSGreg Clayton bool 71530fdc8d8SChris Lattner Debugger::GetAsyncExecution () 71630fdc8d8SChris Lattner { 7176611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 71830fdc8d8SChris Lattner } 71930fdc8d8SChris Lattner 72030fdc8d8SChris Lattner void 72130fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 72230fdc8d8SChris Lattner { 7236611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 72430fdc8d8SChris Lattner } 72530fdc8d8SChris Lattner 72630fdc8d8SChris Lattner 72730fdc8d8SChris Lattner void 72830fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 72930fdc8d8SChris Lattner { 73051b1e2d2SGreg Clayton File &in_file = GetInputFile(); 73151b1e2d2SGreg Clayton in_file.SetStream (fh, tranfer_ownership); 73251b1e2d2SGreg Clayton if (in_file.IsValid() == false) 73351b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 73430fdc8d8SChris Lattner 73530fdc8d8SChris Lattner // Disconnect from any old connection if we had one 73630fdc8d8SChris Lattner m_input_comm.Disconnect (); 73732720b51SGreg Clayton // Pass false as the second argument to ConnectionFileDescriptor below because 73832720b51SGreg Clayton // our "in_file" above will already take ownership if requested and we don't 73932720b51SGreg Clayton // want to objects trying to own and close a file descriptor. 74032720b51SGreg Clayton m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false)); 74130fdc8d8SChris Lattner m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); 74230fdc8d8SChris Lattner 743c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 744c5917d9aSJim Ingham SaveInputTerminalState (); 745c5917d9aSJim Ingham 74630fdc8d8SChris Lattner Error error; 74730fdc8d8SChris Lattner if (m_input_comm.StartReadThread (&error) == false) 74830fdc8d8SChris Lattner { 74951b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 75051b1e2d2SGreg Clayton 75151b1e2d2SGreg Clayton err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); 75230fdc8d8SChris Lattner exit(1); 75330fdc8d8SChris Lattner } 75430fdc8d8SChris Lattner } 75530fdc8d8SChris Lattner 75630fdc8d8SChris Lattner void 75730fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 75830fdc8d8SChris Lattner { 75951b1e2d2SGreg Clayton File &out_file = GetOutputFile(); 76051b1e2d2SGreg Clayton out_file.SetStream (fh, tranfer_ownership); 76151b1e2d2SGreg Clayton if (out_file.IsValid() == false) 76251b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 7632f88aadfSCaroline Tice 764b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 765b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 766b588726eSEnrico Granata const bool can_create = false; 767b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 768b588726eSEnrico Granata if (script_interpreter) 769b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 77030fdc8d8SChris Lattner } 77130fdc8d8SChris Lattner 77230fdc8d8SChris Lattner void 77330fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 77430fdc8d8SChris Lattner { 77551b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 77651b1e2d2SGreg Clayton err_file.SetStream (fh, tranfer_ownership); 77751b1e2d2SGreg Clayton if (err_file.IsValid() == false) 77851b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 77930fdc8d8SChris Lattner } 78030fdc8d8SChris Lattner 781c5917d9aSJim Ingham void 782c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 783c5917d9aSJim Ingham { 784c5917d9aSJim Ingham File &in_file = GetInputFile(); 785c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 786c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 787c5917d9aSJim Ingham } 788c5917d9aSJim Ingham 789c5917d9aSJim Ingham void 790c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 791c5917d9aSJim Ingham { 792c5917d9aSJim Ingham m_terminal_state.Restore(); 793c5917d9aSJim Ingham } 794c5917d9aSJim Ingham 79530fdc8d8SChris Lattner ExecutionContext 7962976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 79730fdc8d8SChris Lattner { 79830fdc8d8SChris Lattner ExecutionContext exe_ctx; 799c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 800c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 80130fdc8d8SChris Lattner 80230fdc8d8SChris Lattner if (target_sp) 80330fdc8d8SChris Lattner { 804c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 805c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 806c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 80730fdc8d8SChris Lattner { 808c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 809c14ee32dSGreg Clayton if (thread_sp) 81030fdc8d8SChris Lattner { 811c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 812c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 813c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 814c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 81530fdc8d8SChris Lattner } 81630fdc8d8SChris Lattner } 81730fdc8d8SChris Lattner } 81830fdc8d8SChris Lattner return exe_ctx; 81930fdc8d8SChris Lattner 82030fdc8d8SChris Lattner } 82130fdc8d8SChris Lattner 822b44880caSCaroline Tice InputReaderSP 823b44880caSCaroline Tice Debugger::GetCurrentInputReader () 824b44880caSCaroline Tice { 825b44880caSCaroline Tice InputReaderSP reader_sp; 826b44880caSCaroline Tice 827d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 828b44880caSCaroline Tice { 829b44880caSCaroline Tice // Clear any finished readers from the stack 830b44880caSCaroline Tice while (CheckIfTopInputReaderIsDone()) ; 831b44880caSCaroline Tice 832d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 833d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 834b44880caSCaroline Tice } 835b44880caSCaroline Tice 836b44880caSCaroline Tice return reader_sp; 837b44880caSCaroline Tice } 838b44880caSCaroline Tice 83930fdc8d8SChris Lattner void 84030fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len) 84130fdc8d8SChris Lattner { 842efed6131SCaroline Tice if (bytes_len > 0) 84330fdc8d8SChris Lattner ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len); 844efed6131SCaroline Tice else 845efed6131SCaroline Tice ((Debugger *)baton)->DispatchInputEndOfFile (); 84630fdc8d8SChris Lattner } 84730fdc8d8SChris Lattner 84830fdc8d8SChris Lattner 84930fdc8d8SChris Lattner void 85030fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len) 85130fdc8d8SChris Lattner { 852efed6131SCaroline Tice if (bytes == NULL || bytes_len == 0) 853efed6131SCaroline Tice return; 85430fdc8d8SChris Lattner 85530fdc8d8SChris Lattner WriteToDefaultReader (bytes, bytes_len); 85630fdc8d8SChris Lattner } 85730fdc8d8SChris Lattner 85830fdc8d8SChris Lattner void 859efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 860efed6131SCaroline Tice { 861efed6131SCaroline Tice m_input_reader_data.clear(); 862efed6131SCaroline Tice 863b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 864efed6131SCaroline Tice if (reader_sp) 865b44880caSCaroline Tice { 866efed6131SCaroline Tice reader_sp->Notify (eInputReaderInterrupt); 867efed6131SCaroline Tice 868b44880caSCaroline Tice // If notifying the reader of the interrupt finished the reader, we should pop it off the stack. 869efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 870efed6131SCaroline Tice } 871efed6131SCaroline Tice } 872efed6131SCaroline Tice 873efed6131SCaroline Tice void 874efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 875efed6131SCaroline Tice { 876efed6131SCaroline Tice m_input_reader_data.clear(); 877efed6131SCaroline Tice 878b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 879efed6131SCaroline Tice if (reader_sp) 880b44880caSCaroline Tice { 881efed6131SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 882efed6131SCaroline Tice 883b44880caSCaroline Tice // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack. 884efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 885efed6131SCaroline Tice } 886efed6131SCaroline Tice } 887efed6131SCaroline Tice 888efed6131SCaroline Tice void 8893d6086f6SCaroline Tice Debugger::CleanUpInputReaders () 8903d6086f6SCaroline Tice { 8913d6086f6SCaroline Tice m_input_reader_data.clear(); 8923d6086f6SCaroline Tice 893b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 894d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 8953d6086f6SCaroline Tice { 896b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 8973d6086f6SCaroline Tice if (reader_sp) 8983d6086f6SCaroline Tice { 8993d6086f6SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 9003d6086f6SCaroline Tice reader_sp->SetIsDone (true); 9013d6086f6SCaroline Tice } 9023d6086f6SCaroline Tice } 9033d6086f6SCaroline Tice } 9043d6086f6SCaroline Tice 9053d6086f6SCaroline Tice void 906969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification) 907969ed3d1SCaroline Tice { 908969ed3d1SCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader()); 909969ed3d1SCaroline Tice if (reader_sp) 910969ed3d1SCaroline Tice { 911969ed3d1SCaroline Tice reader_sp->Notify (notification); 912969ed3d1SCaroline Tice 913969ed3d1SCaroline Tice // Flush out any input readers that are done. 914969ed3d1SCaroline Tice while (CheckIfTopInputReaderIsDone ()) 915969ed3d1SCaroline Tice /* Do nothing. */; 916969ed3d1SCaroline Tice } 917969ed3d1SCaroline Tice } 918969ed3d1SCaroline Tice 9199088b068SCaroline Tice bool 9204d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp) 9219088b068SCaroline Tice { 9229088b068SCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader()); 9239088b068SCaroline Tice 924d61c10bcSCaroline Tice return (reader_sp.get() == top_reader_sp.get()); 9259088b068SCaroline Tice } 9269088b068SCaroline Tice 9279088b068SCaroline Tice 928969ed3d1SCaroline Tice void 92930fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) 93030fdc8d8SChris Lattner { 93130fdc8d8SChris Lattner if (bytes && bytes_len) 93230fdc8d8SChris Lattner m_input_reader_data.append (bytes, bytes_len); 93330fdc8d8SChris Lattner 93430fdc8d8SChris Lattner if (m_input_reader_data.empty()) 93530fdc8d8SChris Lattner return; 93630fdc8d8SChris Lattner 937d5a0a01bSCaroline Tice while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty()) 93830fdc8d8SChris Lattner { 93930fdc8d8SChris Lattner // Get the input reader from the top of the stack 940b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 94130fdc8d8SChris Lattner if (!reader_sp) 94230fdc8d8SChris Lattner break; 94330fdc8d8SChris Lattner 944471b31ceSGreg Clayton size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 94530fdc8d8SChris Lattner m_input_reader_data.size()); 94630fdc8d8SChris Lattner if (bytes_handled) 94730fdc8d8SChris Lattner { 94830fdc8d8SChris Lattner m_input_reader_data.erase (0, bytes_handled); 94930fdc8d8SChris Lattner } 95030fdc8d8SChris Lattner else 95130fdc8d8SChris Lattner { 95230fdc8d8SChris Lattner // No bytes were handled, we might not have reached our 95330fdc8d8SChris Lattner // granularity, just return and wait for more data 95430fdc8d8SChris Lattner break; 95530fdc8d8SChris Lattner } 95630fdc8d8SChris Lattner } 95730fdc8d8SChris Lattner 958b44880caSCaroline Tice // Flush out any input readers that are done. 95930fdc8d8SChris Lattner while (CheckIfTopInputReaderIsDone ()) 96030fdc8d8SChris Lattner /* Do nothing. */; 96130fdc8d8SChris Lattner 96230fdc8d8SChris Lattner } 96330fdc8d8SChris Lattner 96430fdc8d8SChris Lattner void 96530fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp) 96630fdc8d8SChris Lattner { 96730fdc8d8SChris Lattner if (!reader_sp) 96830fdc8d8SChris Lattner return; 969b44880caSCaroline Tice 97030fdc8d8SChris Lattner // Deactivate the old top reader 971b44880caSCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader ()); 972b44880caSCaroline Tice 97330fdc8d8SChris Lattner if (top_reader_sp) 97430fdc8d8SChris Lattner top_reader_sp->Notify (eInputReaderDeactivate); 975b44880caSCaroline Tice 976d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 97730fdc8d8SChris Lattner reader_sp->Notify (eInputReaderActivate); 97830fdc8d8SChris Lattner ActivateInputReader (reader_sp); 97930fdc8d8SChris Lattner } 98030fdc8d8SChris Lattner 98130fdc8d8SChris Lattner bool 9824d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp) 98330fdc8d8SChris Lattner { 98430fdc8d8SChris Lattner bool result = false; 98530fdc8d8SChris Lattner 98630fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 98730fdc8d8SChris Lattner // read on the stack referesh its prompt and if there is one... 988d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 98930fdc8d8SChris Lattner { 990b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 991d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 99230fdc8d8SChris Lattner 99330fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 99430fdc8d8SChris Lattner { 995d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 99630fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDeactivate); 99730fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDone); 99830fdc8d8SChris Lattner result = true; 99930fdc8d8SChris Lattner 1000d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 100130fdc8d8SChris Lattner { 1002d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 100330fdc8d8SChris Lattner if (reader_sp) 100430fdc8d8SChris Lattner { 100530fdc8d8SChris Lattner ActivateInputReader (reader_sp); 100630fdc8d8SChris Lattner reader_sp->Notify (eInputReaderReactivate); 100730fdc8d8SChris Lattner } 100830fdc8d8SChris Lattner } 100930fdc8d8SChris Lattner } 101030fdc8d8SChris Lattner } 101130fdc8d8SChris Lattner return result; 101230fdc8d8SChris Lattner } 101330fdc8d8SChris Lattner 101430fdc8d8SChris Lattner bool 101530fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone () 101630fdc8d8SChris Lattner { 101730fdc8d8SChris Lattner bool result = false; 1018d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 101930fdc8d8SChris Lattner { 1020b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 1021d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 102230fdc8d8SChris Lattner 102330fdc8d8SChris Lattner if (reader_sp && reader_sp->IsDone()) 102430fdc8d8SChris Lattner { 102530fdc8d8SChris Lattner result = true; 102630fdc8d8SChris Lattner PopInputReader (reader_sp); 102730fdc8d8SChris Lattner } 102830fdc8d8SChris Lattner } 102930fdc8d8SChris Lattner return result; 103030fdc8d8SChris Lattner } 103130fdc8d8SChris Lattner 103230fdc8d8SChris Lattner void 103330fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 103430fdc8d8SChris Lattner { 103551b1e2d2SGreg Clayton int input_fd = m_input_file.GetFile().GetDescriptor(); 103630fdc8d8SChris Lattner 103751b1e2d2SGreg Clayton if (input_fd >= 0) 103830fdc8d8SChris Lattner { 103951b1e2d2SGreg Clayton Terminal tty(input_fd); 1040a3406614SGreg Clayton 1041a3406614SGreg Clayton tty.SetEcho(reader_sp->GetEcho()); 104230fdc8d8SChris Lattner 104330fdc8d8SChris Lattner switch (reader_sp->GetGranularity()) 104430fdc8d8SChris Lattner { 104530fdc8d8SChris Lattner case eInputReaderGranularityByte: 104630fdc8d8SChris Lattner case eInputReaderGranularityWord: 1047a3406614SGreg Clayton tty.SetCanonical (false); 104830fdc8d8SChris Lattner break; 104930fdc8d8SChris Lattner 105030fdc8d8SChris Lattner case eInputReaderGranularityLine: 105130fdc8d8SChris Lattner case eInputReaderGranularityAll: 1052a3406614SGreg Clayton tty.SetCanonical (true); 105330fdc8d8SChris Lattner break; 105430fdc8d8SChris Lattner 105530fdc8d8SChris Lattner default: 105630fdc8d8SChris Lattner break; 105730fdc8d8SChris Lattner } 105830fdc8d8SChris Lattner } 105930fdc8d8SChris Lattner } 10606611103cSGreg Clayton 10615b52f0c7SJim Ingham StreamSP 10625b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 10635b52f0c7SJim Ingham { 10645b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10655b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 10665b52f0c7SJim Ingham } 10675b52f0c7SJim Ingham 10685b52f0c7SJim Ingham StreamSP 10695b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 10705b52f0c7SJim Ingham { 10715b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10725b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 10735b52f0c7SJim Ingham } 10745b52f0c7SJim Ingham 1075c7bece56SGreg Clayton size_t 1076061858ceSEnrico Granata Debugger::GetNumDebuggers() 1077061858ceSEnrico Granata { 1078c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1079c15f55e2SGreg Clayton { 1080061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1081061858ceSEnrico Granata return GetDebuggerList().size(); 1082061858ceSEnrico Granata } 1083c15f55e2SGreg Clayton return 0; 1084c15f55e2SGreg Clayton } 1085061858ceSEnrico Granata 1086061858ceSEnrico Granata lldb::DebuggerSP 1087c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1088061858ceSEnrico Granata { 1089061858ceSEnrico Granata DebuggerSP debugger_sp; 1090061858ceSEnrico Granata 1091c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1092c15f55e2SGreg Clayton { 1093061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1094061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1095061858ceSEnrico Granata 1096061858ceSEnrico Granata if (index < debugger_list.size()) 1097061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1098c15f55e2SGreg Clayton } 1099061858ceSEnrico Granata 1100061858ceSEnrico Granata return debugger_sp; 1101061858ceSEnrico Granata } 1102061858ceSEnrico Granata 1103ebc1bb27SCaroline Tice DebuggerSP 1104ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1105ebc1bb27SCaroline Tice { 11064d122c40SGreg Clayton DebuggerSP debugger_sp; 1107ebc1bb27SCaroline Tice 1108c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1109c15f55e2SGreg Clayton { 1110ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 1111ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1112ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1113ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1114ebc1bb27SCaroline Tice { 1115ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 1116ebc1bb27SCaroline Tice { 1117ebc1bb27SCaroline Tice debugger_sp = *pos; 1118ebc1bb27SCaroline Tice break; 1119ebc1bb27SCaroline Tice } 1120ebc1bb27SCaroline Tice } 1121c15f55e2SGreg Clayton } 1122ebc1bb27SCaroline Tice return debugger_sp; 1123ebc1bb27SCaroline Tice } 11243df9a8dfSCaroline Tice 11251b654882SGreg Clayton static void 11261b654882SGreg Clayton TestPromptFormats (StackFrame *frame) 11271b654882SGreg Clayton { 11281b654882SGreg Clayton if (frame == NULL) 11291b654882SGreg Clayton return; 11301b654882SGreg Clayton 11311b654882SGreg Clayton StreamString s; 11321b654882SGreg Clayton const char *prompt_format = 11331b654882SGreg Clayton "{addr = '${addr}'\n}" 11341b654882SGreg Clayton "{process.id = '${process.id}'\n}" 11351b654882SGreg Clayton "{process.name = '${process.name}'\n}" 11361b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 11371b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 11381b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 11391b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 11401b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 11411b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 11421b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 11431b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 11441b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 11451b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 11461b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 11471b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 11481b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 11491b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 11501b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 11511b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 11521b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 11531b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 11541b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 11551b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 11561b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 11571b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 11581b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 11591b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 11601b654882SGreg Clayton "{function.id = '${function.id}'\n}" 11611b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1162ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 11631b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 11641b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 11651b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 11661b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 11671b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 11681b654882SGreg Clayton "{line.number = '${line.number}'\n}" 11691b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 11701b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 11711b654882SGreg Clayton ; 11721b654882SGreg Clayton 11731b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 11741b654882SGreg Clayton ExecutionContext exe_ctx; 11750603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 1176c3ce7f27SMichael Sartain if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 11771b654882SGreg Clayton { 11781b654882SGreg Clayton printf("%s\n", s.GetData()); 11791b654882SGreg Clayton } 11801b654882SGreg Clayton else 11811b654882SGreg Clayton { 11821b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 11831b654882SGreg Clayton } 11841b654882SGreg Clayton } 11851b654882SGreg Clayton 11869fc1944eSEnrico Granata static bool 11879fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin, 11889fc1944eSEnrico Granata const char* var_name_end, 11899fc1944eSEnrico Granata const char** var_name_final, 11909fc1944eSEnrico Granata const char** percent_position, 11914d122c40SGreg Clayton Format* custom_format, 11929fc1944eSEnrico Granata ValueObject::ValueObjectRepresentationStyle* val_obj_display) 11939fc1944eSEnrico Granata { 11945160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 11959fc1944eSEnrico Granata *percent_position = ::strchr(var_name_begin,'%'); 11969fc1944eSEnrico Granata if (!*percent_position || *percent_position > var_name_end) 1197e992a089SEnrico Granata { 1198e992a089SEnrico Granata if (log) 1199d228483dSEnrico Granata log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 12009fc1944eSEnrico Granata *var_name_final = var_name_end; 1201e992a089SEnrico Granata } 12029fc1944eSEnrico Granata else 12039fc1944eSEnrico Granata { 12049fc1944eSEnrico Granata *var_name_final = *percent_position; 120536aa5ae6SEnrico Granata std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1); 1206e992a089SEnrico Granata if (log) 120768ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str()); 120836aa5ae6SEnrico Granata if ( !FormatManager::GetFormatFromCString(format_name.c_str(), 12099fc1944eSEnrico Granata true, 12109fc1944eSEnrico Granata *custom_format) ) 12119fc1944eSEnrico Granata { 1212e992a089SEnrico Granata if (log) 121368ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str()); 121436aa5ae6SEnrico Granata 121536aa5ae6SEnrico Granata switch (format_name.front()) 121636aa5ae6SEnrico Granata { 121736aa5ae6SEnrico Granata case '@': // if this is an @ sign, print ObjC description 121886cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 121936aa5ae6SEnrico Granata break; 122036aa5ae6SEnrico Granata case 'V': // if this is a V, print the value using the default format 122186cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 122236aa5ae6SEnrico Granata break; 122336aa5ae6SEnrico Granata case 'L': // if this is an L, print the location of the value 122486cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 122536aa5ae6SEnrico Granata break; 122636aa5ae6SEnrico Granata case 'S': // if this is an S, print the summary after all 122786cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 122836aa5ae6SEnrico Granata break; 122936aa5ae6SEnrico Granata case '#': // if this is a '#', print the number of children 123086cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 123136aa5ae6SEnrico Granata break; 123236aa5ae6SEnrico Granata case 'T': // if this is a 'T', print the type 123386cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 123436aa5ae6SEnrico Granata break; 1235*2c75f11eSEnrico Granata case 'N': // if this is a 'N', print the name 1236*2c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleName; 1237*2c75f11eSEnrico Granata break; 1238*2c75f11eSEnrico Granata case '>': // if this is a '>', print the name 1239*2c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath; 1240*2c75f11eSEnrico Granata break; 124136aa5ae6SEnrico Granata default: 12425c42d8a8SJim Ingham if (log) 124336aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 124436aa5ae6SEnrico Granata break; 124536aa5ae6SEnrico Granata } 12469fc1944eSEnrico Granata } 12479fc1944eSEnrico Granata // a good custom format tells us to print the value using it 12489fc1944eSEnrico Granata else 1249e992a089SEnrico Granata { 1250e992a089SEnrico Granata if (log) 125168ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] will display value for this VO"); 125286cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1253e992a089SEnrico Granata } 12549fc1944eSEnrico Granata } 1255e992a089SEnrico Granata if (log) 125668ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1257e992a089SEnrico Granata *custom_format, 1258e992a089SEnrico Granata *val_obj_display); 12599fc1944eSEnrico Granata return true; 12609fc1944eSEnrico Granata } 12619fc1944eSEnrico Granata 12629fc1944eSEnrico Granata static bool 12639fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 12649fc1944eSEnrico Granata const char* var_name_end, 12659fc1944eSEnrico Granata const char* var_name_final, 12669fc1944eSEnrico Granata const char** open_bracket_position, 12679fc1944eSEnrico Granata const char** separator_position, 12689fc1944eSEnrico Granata const char** close_bracket_position, 12699fc1944eSEnrico Granata const char** var_name_final_if_array_range, 12709fc1944eSEnrico Granata int64_t* index_lower, 12719fc1944eSEnrico Granata int64_t* index_higher) 12729fc1944eSEnrico Granata { 12735160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12749fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 12759fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 12769fc1944eSEnrico Granata { 12779fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 12789fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 12799fc1944eSEnrico Granata // as usual, we assume that [] will come before % 12809fc1944eSEnrico Granata //printf("trying to expand a []\n"); 12819fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 12829fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 12839fc1944eSEnrico Granata { 1284e992a089SEnrico Granata if (log) 1285d228483dSEnrico Granata log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 12869fc1944eSEnrico Granata *index_lower = 0; 12879fc1944eSEnrico Granata } 12889fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 12899fc1944eSEnrico Granata { 12909fc1944eSEnrico Granata char *end = NULL; 12919fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 12929fc1944eSEnrico Granata *index_higher = *index_lower; 1293e992a089SEnrico Granata if (log) 1294d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 12959fc1944eSEnrico Granata } 12969fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 12979fc1944eSEnrico Granata { 12989fc1944eSEnrico Granata char *end = NULL; 12999fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 13009fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 1301e992a089SEnrico Granata if (log) 1302d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 13039fc1944eSEnrico Granata } 13049fc1944eSEnrico Granata else 1305e992a089SEnrico Granata { 1306e992a089SEnrico Granata if (log) 1307d228483dSEnrico Granata log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 13089fc1944eSEnrico Granata return false; 1309e992a089SEnrico Granata } 13109fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 13119fc1944eSEnrico Granata { 1312e992a089SEnrico Granata if (log) 1313d228483dSEnrico Granata log->Printf("[ScanBracketedRange] swapping indices"); 1314c7bece56SGreg Clayton int64_t temp = *index_lower; 13159fc1944eSEnrico Granata *index_lower = *index_higher; 13169fc1944eSEnrico Granata *index_higher = temp; 13179fc1944eSEnrico Granata } 13189fc1944eSEnrico Granata } 1319e992a089SEnrico Granata else if (log) 1320d228483dSEnrico Granata log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 13219fc1944eSEnrico Granata return true; 13229fc1944eSEnrico Granata } 13239fc1944eSEnrico Granata 13249fc1944eSEnrico Granata static ValueObjectSP 1325c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 1326c7bece56SGreg Clayton size_t index, 13279fc1944eSEnrico Granata StackFrame* frame, 1328fc7a7f3bSEnrico Granata bool deref_pointer) 13299fc1944eSEnrico Granata { 13305160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1331fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1332599171adSEnrico Granata std::string ptr_deref_buffer(10,0); 1333599171adSEnrico Granata ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1334e992a089SEnrico Granata if (log) 1335599171adSEnrico Granata log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1336fc7a7f3bSEnrico Granata const char* first_unparsed; 1337fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1338fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1339fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 134086cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1341599171adSEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1342fc7a7f3bSEnrico Granata &first_unparsed, 1343fc7a7f3bSEnrico Granata &reason_to_stop, 1344fc7a7f3bSEnrico Granata &final_value_type, 1345fc7a7f3bSEnrico Granata options, 1346fc7a7f3bSEnrico Granata &what_next); 1347fc7a7f3bSEnrico Granata if (!item) 1348fc7a7f3bSEnrico Granata { 1349e992a089SEnrico Granata if (log) 1350d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1351e992a089SEnrico Granata " final_value_type %d", 1352fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1353fc7a7f3bSEnrico Granata } 13549fc1944eSEnrico Granata else 13559fc1944eSEnrico Granata { 1356e992a089SEnrico Granata if (log) 1357d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1358e992a089SEnrico Granata " final_value_type %d", 1359fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 13609fc1944eSEnrico Granata } 13619fc1944eSEnrico Granata return item; 13629fc1944eSEnrico Granata } 13639fc1944eSEnrico Granata 1364c3ce7f27SMichael Sartain static bool 1365c3ce7f27SMichael Sartain FormatPromptRecurse 13661b654882SGreg Clayton ( 13671b654882SGreg Clayton const char *format, 13681b654882SGreg Clayton const SymbolContext *sc, 13691b654882SGreg Clayton const ExecutionContext *exe_ctx, 13701b654882SGreg Clayton const Address *addr, 13711b654882SGreg Clayton Stream &s, 13724becb37eSEnrico Granata const char **end, 1373c482a192SEnrico Granata ValueObject* valobj 13741b654882SGreg Clayton ) 13751b654882SGreg Clayton { 1376c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 13771b654882SGreg Clayton bool success = true; 13781b654882SGreg Clayton const char *p; 13795160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1380c3ce7f27SMichael Sartain 13811b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 13821b654882SGreg Clayton { 1383c482a192SEnrico Granata if (realvalobj) 13844becb37eSEnrico Granata { 1385c482a192SEnrico Granata valobj = realvalobj; 1386c482a192SEnrico Granata realvalobj = NULL; 13874becb37eSEnrico Granata } 13881b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 13891b654882SGreg Clayton if (non_special_chars > 0) 13901b654882SGreg Clayton { 13911b654882SGreg Clayton if (success) 13921b654882SGreg Clayton s.Write (p, non_special_chars); 13931b654882SGreg Clayton p += non_special_chars; 13941b654882SGreg Clayton } 13951b654882SGreg Clayton 13961b654882SGreg Clayton if (*p == '\0') 13971b654882SGreg Clayton { 13981b654882SGreg Clayton break; 13991b654882SGreg Clayton } 14001b654882SGreg Clayton else if (*p == '{') 14011b654882SGreg Clayton { 14021b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 14031b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 14041b654882SGreg Clayton // a format that only prints out the function or symbol name if there 14051b654882SGreg Clayton // is one in the symbol context you can use: 14061b654882SGreg Clayton // "{function =${function.name}}" 14071b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 14081b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 14091b654882SGreg Clayton // will then be evaluated and only be output if there is a function 14101b654882SGreg Clayton // or symbol with a valid name. 14111b654882SGreg Clayton StreamString sub_strm; 14121b654882SGreg Clayton 14131b654882SGreg Clayton ++p; // Skip the '{' 14141b654882SGreg Clayton 1415c3ce7f27SMichael Sartain if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 14161b654882SGreg Clayton { 14171b654882SGreg Clayton // The stream had all it needed 14181b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 14191b654882SGreg Clayton } 14201b654882SGreg Clayton if (*p != '}') 14211b654882SGreg Clayton { 14221b654882SGreg Clayton success = false; 14231b654882SGreg Clayton break; 14241b654882SGreg Clayton } 14251b654882SGreg Clayton } 14261b654882SGreg Clayton else if (*p == '}') 14271b654882SGreg Clayton { 14281b654882SGreg Clayton // End of a enclosing scope 14291b654882SGreg Clayton break; 14301b654882SGreg Clayton } 14311b654882SGreg Clayton else if (*p == '$') 14321b654882SGreg Clayton { 14331b654882SGreg Clayton // We have a prompt variable to print 14341b654882SGreg Clayton ++p; 14351b654882SGreg Clayton if (*p == '{') 14361b654882SGreg Clayton { 14371b654882SGreg Clayton ++p; 14381b654882SGreg Clayton const char *var_name_begin = p; 14391b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 14401b654882SGreg Clayton 14411b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 14421b654882SGreg Clayton { 14431b654882SGreg Clayton // if we have already failed to parse, skip this variable 14441b654882SGreg Clayton if (success) 14451b654882SGreg Clayton { 14461b654882SGreg Clayton const char *cstr = NULL; 14471b654882SGreg Clayton Address format_addr; 14481b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 14491b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 14501b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 14511b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 14521b654882SGreg Clayton FileSpec format_file_spec; 1453e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 14541b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 14559fc1944eSEnrico Granata bool do_deref_pointer = false; 145686cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 145786cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 14581b654882SGreg Clayton 14591b654882SGreg Clayton // Each variable must set success to true below... 14601b654882SGreg Clayton bool var_success = false; 14611b654882SGreg Clayton switch (var_name_begin[0]) 14621b654882SGreg Clayton { 14634becb37eSEnrico Granata case '*': 14646f3533fbSEnrico Granata case 'v': 14656f3533fbSEnrico Granata case 's': 14664becb37eSEnrico Granata { 1467c482a192SEnrico Granata if (!valobj) 146834132754SGreg Clayton break; 14696f3533fbSEnrico Granata 1470c3e320a7SEnrico Granata if (log) 1471d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1472c3e320a7SEnrico Granata 14736f3533fbSEnrico Granata // check for *var and *svar 14746f3533fbSEnrico Granata if (*var_name_begin == '*') 14756f3533fbSEnrico Granata { 14769fc1944eSEnrico Granata do_deref_pointer = true; 14779fc1944eSEnrico Granata var_name_begin++; 1478c3e320a7SEnrico Granata if (log) 147968ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin); 148068ae4117SEnrico Granata } 1481c3e320a7SEnrico Granata 14826f3533fbSEnrico Granata if (*var_name_begin == 's') 14834becb37eSEnrico Granata { 1484c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 148586cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 148686cc9829SEnrico Granata if (!valobj) 148786cc9829SEnrico Granata break; 14886f3533fbSEnrico Granata var_name_begin++; 1489c3e320a7SEnrico Granata if (log) 149068ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin); 149168ae4117SEnrico Granata } 1492c3e320a7SEnrico Granata 14936f3533fbSEnrico Granata // should be a 'v' by now 14946f3533fbSEnrico Granata if (*var_name_begin != 'v') 14956f3533fbSEnrico Granata break; 14966f3533fbSEnrico Granata 1497c3e320a7SEnrico Granata if (log) 149868ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin); 1499c3e320a7SEnrico Granata 1500fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 150186cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1502fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 15038c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 150486cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 150534132754SGreg Clayton ValueObject* target = NULL; 15064d122c40SGreg Clayton Format custom_format = eFormatInvalid; 150734132754SGreg Clayton const char* var_name_final = NULL; 15089fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 150934132754SGreg Clayton const char* close_bracket_position = NULL; 151034132754SGreg Clayton int64_t index_lower = -1; 151134132754SGreg Clayton int64_t index_higher = -1; 15129fc1944eSEnrico Granata bool is_array_range = false; 1513fc7a7f3bSEnrico Granata const char* first_unparsed; 151485933ed4SEnrico Granata bool was_plain_var = false; 151585933ed4SEnrico Granata bool was_var_format = false; 1516a777dc2aSEnrico Granata bool was_var_indexed = false; 1517fc7a7f3bSEnrico Granata 1518c482a192SEnrico Granata if (!valobj) break; 1519c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 15209fc1944eSEnrico Granata if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) 15210a3958e0SEnrico Granata { 152285933ed4SEnrico Granata was_plain_var = true; 1523c482a192SEnrico Granata target = valobj; 152486cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 15250a3958e0SEnrico Granata } 15269fc1944eSEnrico Granata else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) 15279fc1944eSEnrico Granata { 152885933ed4SEnrico Granata was_var_format = true; 15299fc1944eSEnrico Granata // this is a variable with some custom format applied to it 15309fc1944eSEnrico Granata const char* percent_position; 1531c482a192SEnrico Granata target = valobj; 153286cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 15339fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 15349fc1944eSEnrico Granata var_name_end, 15359fc1944eSEnrico Granata &var_name_final, 15369fc1944eSEnrico Granata &percent_position, 15379fc1944eSEnrico Granata &custom_format, 15389fc1944eSEnrico Granata &val_obj_display); 15390a3958e0SEnrico Granata } 15409fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 15419fc1944eSEnrico Granata else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) 15429fc1944eSEnrico Granata { 1543a777dc2aSEnrico Granata if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0) 1544a777dc2aSEnrico Granata was_var_indexed = true; 15459fc1944eSEnrico Granata const char* percent_position; 15469fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 15479fc1944eSEnrico Granata var_name_end, 15489fc1944eSEnrico Granata &var_name_final, 15499fc1944eSEnrico Granata &percent_position, 15509fc1944eSEnrico Granata &custom_format, 15519fc1944eSEnrico Granata &val_obj_display); 15529fc1944eSEnrico Granata 15539fc1944eSEnrico Granata const char* open_bracket_position; 15549fc1944eSEnrico Granata const char* separator_position; 15559fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 15569fc1944eSEnrico Granata var_name_end, 15579fc1944eSEnrico Granata var_name_final, 15589fc1944eSEnrico Granata &open_bracket_position, 15599fc1944eSEnrico Granata &separator_position, 15609fc1944eSEnrico Granata &close_bracket_position, 15619fc1944eSEnrico Granata &var_name_final_if_array_range, 15629fc1944eSEnrico Granata &index_lower, 15639fc1944eSEnrico Granata &index_higher); 15649fc1944eSEnrico Granata 15659fc1944eSEnrico Granata Error error; 15669fc1944eSEnrico Granata 1567599171adSEnrico Granata std::string expr_path(var_name_final-var_name_begin-1,0); 1568599171adSEnrico Granata memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1569fc7a7f3bSEnrico Granata 1570e992a089SEnrico Granata if (log) 1571599171adSEnrico Granata log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1572fc7a7f3bSEnrico Granata 1573599171adSEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1574fc7a7f3bSEnrico Granata &first_unparsed, 1575fc7a7f3bSEnrico Granata &reason_to_stop, 1576fc7a7f3bSEnrico Granata &final_value_type, 1577fc7a7f3bSEnrico Granata options, 1578fc7a7f3bSEnrico Granata &what_next).get(); 1579fc7a7f3bSEnrico Granata 1580fc7a7f3bSEnrico Granata if (!target) 15819fc1944eSEnrico Granata { 1582e992a089SEnrico Granata if (log) 1583d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1584e992a089SEnrico Granata " final_value_type %d", 1585fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1586fc7a7f3bSEnrico Granata break; 15870a3958e0SEnrico Granata } 1588a7187d00SEnrico Granata else 1589fc7a7f3bSEnrico Granata { 1590e992a089SEnrico Granata if (log) 1591d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1592e992a089SEnrico Granata " final_value_type %d", 1593fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1594a7187d00SEnrico Granata } 15950a3958e0SEnrico Granata } 15960a3958e0SEnrico Granata else 15970a3958e0SEnrico Granata break; 15989fc1944eSEnrico Granata 159986cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 160086cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1601fc7a7f3bSEnrico Granata 160286cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1603fc7a7f3bSEnrico Granata 1604a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 16050a3958e0SEnrico Granata { 16069fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 16079fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 16089fc1944eSEnrico Granata // to get to the target ValueObject 16099fc1944eSEnrico Granata Error error; 16109fc1944eSEnrico Granata target = target->Dereference(error).get(); 1611dc940730SEnrico Granata if (error.Fail()) 1612dc940730SEnrico Granata { 1613dc940730SEnrico Granata if (log) 1614d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1615dc940730SEnrico Granata break; 1616dc940730SEnrico Granata } 16179fc1944eSEnrico Granata do_deref_pointer = false; 16180a3958e0SEnrico Granata } 16190a3958e0SEnrico Granata 1620a777dc2aSEnrico Granata // <rdar://problem/11338654> 1621a777dc2aSEnrico Granata // we do not want to use the summary for a bitfield of type T:n 1622a777dc2aSEnrico Granata // if we were originally dealing with just a T - that would get 1623a777dc2aSEnrico Granata // us into an endless recursion 1624a777dc2aSEnrico Granata if (target->IsBitfield() && was_var_indexed) 1625a777dc2aSEnrico Granata { 1626a777dc2aSEnrico Granata // TODO: check for a (T:n)-specific summary - we should still obey that 1627a777dc2aSEnrico Granata StreamString bitfield_name; 1628a777dc2aSEnrico Granata bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1629a777dc2aSEnrico Granata lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1630a777dc2aSEnrico Granata if (!DataVisualization::GetSummaryForType(type_sp)) 1631a777dc2aSEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1632a777dc2aSEnrico Granata } 1633a777dc2aSEnrico Granata 163485933ed4SEnrico Granata // TODO use flags for these 16354ef877f5SGreg Clayton bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL); 1636f4efecd9SEnrico Granata bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); 163785933ed4SEnrico Granata bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType()); 1638f4efecd9SEnrico Granata 163986cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1640f4efecd9SEnrico Granata { 164185933ed4SEnrico Granata StreamString str_temp; 1642e992a089SEnrico Granata if (log) 1643d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1644d64d0bc0SEnrico Granata 16455088c486SGreg Clayton if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1646d64d0bc0SEnrico Granata { 1647f4efecd9SEnrico Granata // try to use the special cases 164885933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 164985933ed4SEnrico Granata val_obj_display, 165085933ed4SEnrico Granata custom_format); 1651e992a089SEnrico Granata if (log) 1652d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1653d64d0bc0SEnrico Granata 1654d64d0bc0SEnrico Granata // should not happen 16555088c486SGreg Clayton if (var_success) 165685933ed4SEnrico Granata s << str_temp.GetData(); 1657d64d0bc0SEnrico Granata var_success = true; 1658d64d0bc0SEnrico Granata break; 1659d64d0bc0SEnrico Granata } 1660d64d0bc0SEnrico Granata else 1661d64d0bc0SEnrico Granata { 166288da35f8SEnrico Granata if (was_plain_var) // if ${var} 1663d64d0bc0SEnrico Granata { 1664d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1665d64d0bc0SEnrico Granata } 166688da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 166788da35f8SEnrico Granata { 166823f59509SGreg Clayton target->DumpPrintableRepresentation (s, 166988da35f8SEnrico Granata val_obj_display, 167086cc9829SEnrico Granata custom_format, 167186cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 167288da35f8SEnrico Granata } 1673d64d0bc0SEnrico Granata var_success = true; 1674d64d0bc0SEnrico Granata break; 1675d64d0bc0SEnrico Granata } 1676d64d0bc0SEnrico Granata } 1677d64d0bc0SEnrico Granata 1678d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1679d64d0bc0SEnrico Granata // type @ location message 1680d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1681d64d0bc0SEnrico Granata { 1682d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1683d64d0bc0SEnrico Granata var_success = true; 168485933ed4SEnrico Granata break; 168585933ed4SEnrico Granata } 168685933ed4SEnrico Granata 1687d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 168886cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 168985933ed4SEnrico Granata { 169085933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 169185933ed4SEnrico Granata var_success = true; 1692f4efecd9SEnrico Granata break; 1693f4efecd9SEnrico Granata } 1694f4efecd9SEnrico Granata 16959fc1944eSEnrico Granata if (!is_array_range) 1696e992a089SEnrico Granata { 1697e992a089SEnrico Granata if (log) 1698d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 16999fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1700e992a089SEnrico Granata } 17019fc1944eSEnrico Granata else 17029fc1944eSEnrico Granata { 1703e992a089SEnrico Granata if (log) 1704d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 17059fc1944eSEnrico Granata if (!is_array && !is_pointer) 17069fc1944eSEnrico Granata break; 1707e992a089SEnrico Granata if (log) 1708d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] handle as array"); 1709fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1710fc7a7f3bSEnrico Granata StreamString special_directions_writer; 17110a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 17120a3958e0SEnrico Granata { 1713fc7a7f3bSEnrico Granata ConstString additional_data; 1714fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1715fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1716fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1717fc7a7f3bSEnrico Granata additional_data.GetCString()); 1718fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 17190a3958e0SEnrico Granata } 17200a3958e0SEnrico Granata 17210a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 17220a3958e0SEnrico Granata s.PutChar('['); 17230a3958e0SEnrico Granata var_success = true; 17240a3958e0SEnrico Granata 17259fc1944eSEnrico Granata if (index_higher < 0) 1726c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 17270a3958e0SEnrico Granata 1728cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 172922c55d18SEnrico Granata 17300a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 17310a3958e0SEnrico Granata { 1732fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 17339fc1944eSEnrico Granata index_lower, 1734c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1735fc7a7f3bSEnrico Granata false).get(); 17360a3958e0SEnrico Granata 1737fc7a7f3bSEnrico Granata if (!item) 1738fc7a7f3bSEnrico Granata { 1739e992a089SEnrico Granata if (log) 1740d01b2953SDaniel Malea log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1741fc7a7f3bSEnrico Granata } 1742fc7a7f3bSEnrico Granata else 1743fc7a7f3bSEnrico Granata { 1744e992a089SEnrico Granata if (log) 1745d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1746fc7a7f3bSEnrico Granata } 1747fc7a7f3bSEnrico Granata 17480a3958e0SEnrico Granata if (!special_directions) 17499fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 17500a3958e0SEnrico Granata else 1751c3ce7f27SMichael Sartain var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item); 17520a3958e0SEnrico Granata 175322c55d18SEnrico Granata if (--max_num_children == 0) 175422c55d18SEnrico Granata { 175522c55d18SEnrico Granata s.PutCString(", ..."); 175622c55d18SEnrico Granata break; 175722c55d18SEnrico Granata } 175822c55d18SEnrico Granata 17590a3958e0SEnrico Granata if (index_lower < index_higher) 17600a3958e0SEnrico Granata s.PutChar(','); 17610a3958e0SEnrico Granata } 17620a3958e0SEnrico Granata s.PutChar(']'); 17634becb37eSEnrico Granata } 17644becb37eSEnrico Granata } 176534132754SGreg Clayton break; 17661b654882SGreg Clayton case 'a': 17671b654882SGreg Clayton if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 17681b654882SGreg Clayton { 17691b654882SGreg Clayton if (addr && addr->IsValid()) 17701b654882SGreg Clayton { 17711b654882SGreg Clayton var_success = true; 17721b654882SGreg Clayton format_addr = *addr; 17731b654882SGreg Clayton } 17741b654882SGreg Clayton } 17751b654882SGreg Clayton break; 17761b654882SGreg Clayton 17771b654882SGreg Clayton case 'p': 17781b654882SGreg Clayton if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 17791b654882SGreg Clayton { 1780c14ee32dSGreg Clayton if (exe_ctx) 1781c14ee32dSGreg Clayton { 1782c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 1783c14ee32dSGreg Clayton if (process) 17841b654882SGreg Clayton { 17851b654882SGreg Clayton var_name_begin += ::strlen ("process."); 17861b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 17871b654882SGreg Clayton { 1788d01b2953SDaniel Malea s.Printf("%" PRIu64, process->GetID()); 17891b654882SGreg Clayton var_success = true; 17901b654882SGreg Clayton } 17911b654882SGreg Clayton else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 17921b654882SGreg Clayton (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 17931b654882SGreg Clayton (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 17941b654882SGreg Clayton { 1795c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1796aa149cbdSGreg Clayton if (exe_module) 17971b654882SGreg Clayton { 17981b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 17991b654882SGreg Clayton { 1800aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 18011b654882SGreg Clayton var_success = format_file_spec; 18021b654882SGreg Clayton } 18031b654882SGreg Clayton else 18041b654882SGreg Clayton { 1805aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 18061b654882SGreg Clayton var_success = format_file_spec; 18071b654882SGreg Clayton } 18081b654882SGreg Clayton } 18091b654882SGreg Clayton } 1810aad8e480SEnrico Granata else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 1811aad8e480SEnrico Granata { 1812aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 1813aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 1814aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1815aad8e480SEnrico Granata if (script_interpreter) 1816aad8e480SEnrico Granata { 1817aad8e480SEnrico Granata std::string script_output; 1818aad8e480SEnrico Granata Error script_error; 1819aad8e480SEnrico Granata if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), process,script_output,script_error) && script_error.Success()) 1820aad8e480SEnrico Granata { 1821aad8e480SEnrico Granata s.Printf("%s", script_output.c_str()); 1822aad8e480SEnrico Granata var_success = true; 1823aad8e480SEnrico Granata } 1824aad8e480SEnrico Granata else 1825aad8e480SEnrico Granata s.Printf("<error: %s>",script_error.AsCString()); 1826aad8e480SEnrico Granata } 1827aad8e480SEnrico Granata } 18281b654882SGreg Clayton } 18291b654882SGreg Clayton } 1830c14ee32dSGreg Clayton } 18311b654882SGreg Clayton break; 18321b654882SGreg Clayton 18331b654882SGreg Clayton case 't': 18341b654882SGreg Clayton if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 18351b654882SGreg Clayton { 1836c14ee32dSGreg Clayton if (exe_ctx) 1837c14ee32dSGreg Clayton { 1838c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 1839c14ee32dSGreg Clayton if (thread) 18401b654882SGreg Clayton { 18411b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 18421b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 18431b654882SGreg Clayton { 1844d01b2953SDaniel Malea s.Printf("0x%4.4" PRIx64, thread->GetID()); 18451b654882SGreg Clayton var_success = true; 18461b654882SGreg Clayton } 1847160c9d81SGreg Clayton else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0) 1848160c9d81SGreg Clayton { 1849160c9d81SGreg Clayton s.Printf("0x%4.4" PRIx64, thread->GetProtocolID()); 1850160c9d81SGreg Clayton var_success = true; 1851160c9d81SGreg Clayton } 18521b654882SGreg Clayton else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 18531b654882SGreg Clayton { 1854c14ee32dSGreg Clayton s.Printf("%u", thread->GetIndexID()); 18551b654882SGreg Clayton var_success = true; 18561b654882SGreg Clayton } 18571b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 18581b654882SGreg Clayton { 1859c14ee32dSGreg Clayton cstr = thread->GetName(); 18601b654882SGreg Clayton var_success = cstr && cstr[0]; 18611b654882SGreg Clayton if (var_success) 18621b654882SGreg Clayton s.PutCString(cstr); 18631b654882SGreg Clayton } 18641b654882SGreg Clayton else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 18651b654882SGreg Clayton { 1866c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 18671b654882SGreg Clayton var_success = cstr && cstr[0]; 18681b654882SGreg Clayton if (var_success) 18691b654882SGreg Clayton s.PutCString(cstr); 18701b654882SGreg Clayton } 18711b654882SGreg Clayton else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 18721b654882SGreg Clayton { 1873c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 18745d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 18751b654882SGreg Clayton { 1876b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 18771b654882SGreg Clayton if (cstr && cstr[0]) 18781b654882SGreg Clayton { 18791b654882SGreg Clayton s.PutCString(cstr); 18801b654882SGreg Clayton var_success = true; 18811b654882SGreg Clayton } 18821b654882SGreg Clayton } 18831b654882SGreg Clayton } 188473ca05a2SJim Ingham else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0) 188573ca05a2SJim Ingham { 188673ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 18875d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 188873ca05a2SJim Ingham { 188973ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 189073ca05a2SJim Ingham if (return_valobj_sp) 189173ca05a2SJim Ingham { 18929fb5ab55SEnrico Granata ValueObject::DumpValueObject (s, return_valobj_sp.get()); 189373ca05a2SJim Ingham var_success = true; 189473ca05a2SJim Ingham } 189573ca05a2SJim Ingham } 189673ca05a2SJim Ingham } 1897aad8e480SEnrico Granata else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 1898aad8e480SEnrico Granata { 1899aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 1900aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 1901aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1902aad8e480SEnrico Granata if (script_interpreter) 1903aad8e480SEnrico Granata { 1904aad8e480SEnrico Granata std::string script_output; 1905aad8e480SEnrico Granata Error script_error; 1906aad8e480SEnrico Granata if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), thread,script_output,script_error) && script_error.Success()) 1907aad8e480SEnrico Granata { 1908aad8e480SEnrico Granata s.Printf("%s", script_output.c_str()); 1909aad8e480SEnrico Granata var_success = true; 1910aad8e480SEnrico Granata } 1911aad8e480SEnrico Granata else 1912aad8e480SEnrico Granata s.Printf("<error: %s>",script_error.AsCString()); 1913aad8e480SEnrico Granata } 1914aad8e480SEnrico Granata } 191573ca05a2SJim Ingham } 19161b654882SGreg Clayton } 19171b654882SGreg Clayton } 19181b654882SGreg Clayton else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 19191b654882SGreg Clayton { 192067cc0636SGreg Clayton // TODO: hookup properties 192167cc0636SGreg Clayton // if (!target_properties_sp) 192267cc0636SGreg Clayton // { 192367cc0636SGreg Clayton // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 192467cc0636SGreg Clayton // if (target) 192567cc0636SGreg Clayton // target_properties_sp = target->GetProperties(); 192667cc0636SGreg Clayton // } 192767cc0636SGreg Clayton // 192867cc0636SGreg Clayton // if (target_properties_sp) 192967cc0636SGreg Clayton // { 193067cc0636SGreg Clayton // var_name_begin += ::strlen ("target."); 193167cc0636SGreg Clayton // const char *end_property = strchr(var_name_begin, '}'); 193267cc0636SGreg Clayton // if (end_property) 193367cc0636SGreg Clayton // { 193467cc0636SGreg Clayton // ConstString property_name(var_name_begin, end_property - var_name_begin); 193567cc0636SGreg Clayton // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 193667cc0636SGreg Clayton // if (!property_value.empty()) 193767cc0636SGreg Clayton // { 193867cc0636SGreg Clayton // s.PutCString (property_value.c_str()); 193967cc0636SGreg Clayton // var_success = true; 194067cc0636SGreg Clayton // } 194167cc0636SGreg Clayton // } 194267cc0636SGreg Clayton // } 19430603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 19440603aa9dSGreg Clayton if (target) 19451b654882SGreg Clayton { 19461b654882SGreg Clayton var_name_begin += ::strlen ("target."); 19471b654882SGreg Clayton if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 19481b654882SGreg Clayton { 19491b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 19501b654882SGreg Clayton if (arch.IsValid()) 19511b654882SGreg Clayton { 195264195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 19531b654882SGreg Clayton var_success = true; 19541b654882SGreg Clayton } 19551b654882SGreg Clayton } 1956aad8e480SEnrico Granata else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 1957aad8e480SEnrico Granata { 1958aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 1959aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 1960aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1961aad8e480SEnrico Granata if (script_interpreter) 1962aad8e480SEnrico Granata { 1963aad8e480SEnrico Granata std::string script_output; 1964aad8e480SEnrico Granata Error script_error; 1965aad8e480SEnrico Granata if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), target,script_output,script_error) && script_error.Success()) 1966aad8e480SEnrico Granata { 1967aad8e480SEnrico Granata s.Printf("%s", script_output.c_str()); 1968aad8e480SEnrico Granata var_success = true; 1969aad8e480SEnrico Granata } 1970aad8e480SEnrico Granata else 1971aad8e480SEnrico Granata s.Printf("<error: %s>",script_error.AsCString()); 1972aad8e480SEnrico Granata } 1973aad8e480SEnrico Granata } 19741b654882SGreg Clayton } 19751b654882SGreg Clayton } 19761b654882SGreg Clayton break; 19771b654882SGreg Clayton 19781b654882SGreg Clayton 19791b654882SGreg Clayton case 'm': 19801b654882SGreg Clayton if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 19811b654882SGreg Clayton { 19820603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 19831b654882SGreg Clayton { 19840603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 19851b654882SGreg Clayton var_name_begin += ::strlen ("module."); 19861b654882SGreg Clayton 19871b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 19881b654882SGreg Clayton { 19891b654882SGreg Clayton if (module->GetFileSpec()) 19901b654882SGreg Clayton { 19911b654882SGreg Clayton var_name_begin += ::strlen ("file."); 19921b654882SGreg Clayton 19931b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 19941b654882SGreg Clayton { 19951b654882SGreg Clayton format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 19961b654882SGreg Clayton var_success = format_file_spec; 19971b654882SGreg Clayton } 19981b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 19991b654882SGreg Clayton { 20001b654882SGreg Clayton format_file_spec = module->GetFileSpec(); 20011b654882SGreg Clayton var_success = format_file_spec; 20021b654882SGreg Clayton } 20031b654882SGreg Clayton } 20041b654882SGreg Clayton } 20051b654882SGreg Clayton } 20061b654882SGreg Clayton } 20071b654882SGreg Clayton break; 20081b654882SGreg Clayton 20091b654882SGreg Clayton 20101b654882SGreg Clayton case 'f': 20111b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 20121b654882SGreg Clayton { 20131b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 20141b654882SGreg Clayton { 20151b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20161b654882SGreg Clayton 20171b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 20181b654882SGreg Clayton { 20191b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 20201b654882SGreg Clayton var_success = format_file_spec; 20211b654882SGreg Clayton } 20221b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 20231b654882SGreg Clayton { 20241b654882SGreg Clayton format_file_spec = *sc->comp_unit; 20251b654882SGreg Clayton var_success = format_file_spec; 20261b654882SGreg Clayton } 20271b654882SGreg Clayton } 20281b654882SGreg Clayton } 20291b654882SGreg Clayton else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 20301b654882SGreg Clayton { 2031c14ee32dSGreg Clayton if (exe_ctx) 2032c14ee32dSGreg Clayton { 2033c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2034c14ee32dSGreg Clayton if (frame) 20351b654882SGreg Clayton { 20361b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 20371b654882SGreg Clayton if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 20381b654882SGreg Clayton { 2039c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 20401b654882SGreg Clayton var_success = true; 20411b654882SGreg Clayton } 20421b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 20431b654882SGreg Clayton { 20441b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20451b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 20461b654882SGreg Clayton var_success = true; 20471b654882SGreg Clayton } 20481b654882SGreg Clayton else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 20491b654882SGreg Clayton { 20501b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20511b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 20521b654882SGreg Clayton var_success = true; 20531b654882SGreg Clayton } 20541b654882SGreg Clayton else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 20551b654882SGreg Clayton { 20561b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20571b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 20581b654882SGreg Clayton var_success = true; 20591b654882SGreg Clayton } 20601b654882SGreg Clayton else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 20611b654882SGreg Clayton { 20621b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 20631b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 20641b654882SGreg Clayton var_success = true; 20651b654882SGreg Clayton } 20661b654882SGreg Clayton else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 20671b654882SGreg Clayton { 2068c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 20691b654882SGreg Clayton if (reg_ctx) 20701b654882SGreg Clayton { 20711b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 20721b654882SGreg Clayton if (var_name_begin < var_name_end) 20731b654882SGreg Clayton { 20741b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 20751b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 20761b654882SGreg Clayton if (reg_info) 20771b654882SGreg Clayton var_success = true; 20781b654882SGreg Clayton } 20791b654882SGreg Clayton } 20801b654882SGreg Clayton } 2081aad8e480SEnrico Granata else if (::strncmp(var_name_begin, "script:", strlen("script:")) == 0) 2082aad8e480SEnrico Granata { 2083aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2084aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2085aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 2086aad8e480SEnrico Granata if (script_interpreter) 2087aad8e480SEnrico Granata { 2088aad8e480SEnrico Granata std::string script_output; 2089aad8e480SEnrico Granata Error script_error; 2090aad8e480SEnrico Granata if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), frame,script_output,script_error) && script_error.Success()) 2091aad8e480SEnrico Granata { 2092aad8e480SEnrico Granata s.Printf("%s", script_output.c_str()); 2093aad8e480SEnrico Granata var_success = true; 2094aad8e480SEnrico Granata } 2095aad8e480SEnrico Granata else 2096aad8e480SEnrico Granata s.Printf("<error: %s>",script_error.AsCString()); 2097aad8e480SEnrico Granata } 2098aad8e480SEnrico Granata } 20991b654882SGreg Clayton } 21001b654882SGreg Clayton } 2101c14ee32dSGreg Clayton } 21021b654882SGreg Clayton else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 21031b654882SGreg Clayton { 21041b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 21051b654882SGreg Clayton { 21061b654882SGreg Clayton var_name_begin += ::strlen ("function."); 21071b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 21081b654882SGreg Clayton { 21091b654882SGreg Clayton if (sc->function) 2110d01b2953SDaniel Malea s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 21111b654882SGreg Clayton else 21121b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 21131b654882SGreg Clayton 21141b654882SGreg Clayton var_success = true; 21151b654882SGreg Clayton } 21161b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 21171b654882SGreg Clayton { 21181b654882SGreg Clayton if (sc->function) 21191b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21201b654882SGreg Clayton else if (sc->symbol) 21211b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 21221b654882SGreg Clayton if (cstr) 21231b654882SGreg Clayton { 21241b654882SGreg Clayton s.PutCString(cstr); 21250d9c9934SGreg Clayton 21260d9c9934SGreg Clayton if (sc->block) 21270d9c9934SGreg Clayton { 21280d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 21290d9c9934SGreg Clayton if (inline_block) 21300d9c9934SGreg Clayton { 21310d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 21320d9c9934SGreg Clayton if (inline_info) 21330d9c9934SGreg Clayton { 21340d9c9934SGreg Clayton s.PutCString(" [inlined] "); 21350d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 21360d9c9934SGreg Clayton } 21370d9c9934SGreg Clayton } 21380d9c9934SGreg Clayton } 21391b654882SGreg Clayton var_success = true; 21401b654882SGreg Clayton } 21411b654882SGreg Clayton } 21426d3dbf51SGreg Clayton else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0) 21436d3dbf51SGreg Clayton { 21446d3dbf51SGreg Clayton // Print the function name with arguments in it 21456d3dbf51SGreg Clayton 21466d3dbf51SGreg Clayton if (sc->function) 21476d3dbf51SGreg Clayton { 21486d3dbf51SGreg Clayton var_success = true; 21496d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 21506d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 21516d3dbf51SGreg Clayton if (cstr) 21526d3dbf51SGreg Clayton { 21536d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 21546d3dbf51SGreg Clayton VariableListSP variable_list_sp; 21556d3dbf51SGreg Clayton bool get_function_vars = true; 21566d3dbf51SGreg Clayton if (sc->block) 21576d3dbf51SGreg Clayton { 21586d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 21596d3dbf51SGreg Clayton 21606d3dbf51SGreg Clayton if (inline_block) 21616d3dbf51SGreg Clayton { 21626d3dbf51SGreg Clayton get_function_vars = false; 21636d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 21646d3dbf51SGreg Clayton if (inline_info) 21656d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 21666d3dbf51SGreg Clayton } 21676d3dbf51SGreg Clayton } 21686d3dbf51SGreg Clayton 21696d3dbf51SGreg Clayton if (get_function_vars) 21706d3dbf51SGreg Clayton { 21716d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 21726d3dbf51SGreg Clayton } 21736d3dbf51SGreg Clayton 21746d3dbf51SGreg Clayton if (inline_info) 21756d3dbf51SGreg Clayton { 21766d3dbf51SGreg Clayton s.PutCString (cstr); 21776d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 21786d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 21796d3dbf51SGreg Clayton } 21806d3dbf51SGreg Clayton 21816d3dbf51SGreg Clayton VariableList args; 21826d3dbf51SGreg Clayton if (variable_list_sp) 2183cc7f9bf5SEnrico Granata variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 21846d3dbf51SGreg Clayton if (args.GetSize() > 0) 21856d3dbf51SGreg Clayton { 21866d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 21876d3dbf51SGreg Clayton const char *close_paren = NULL; 21886d3dbf51SGreg Clayton if (open_paren) 2189855958caSGreg Clayton { 2190855958caSGreg Clayton if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0) 2191855958caSGreg Clayton { 2192855958caSGreg Clayton open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2193855958caSGreg Clayton if (open_paren) 21946d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 2195855958caSGreg Clayton } 2196855958caSGreg Clayton else 2197855958caSGreg Clayton close_paren = strchr (open_paren, ')'); 2198855958caSGreg Clayton } 21996d3dbf51SGreg Clayton 22006d3dbf51SGreg Clayton if (open_paren) 22016d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 22026d3dbf51SGreg Clayton else 22036d3dbf51SGreg Clayton { 22046d3dbf51SGreg Clayton s.PutCString (cstr); 22056d3dbf51SGreg Clayton s.PutChar ('('); 22066d3dbf51SGreg Clayton } 22075b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 22086d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 22096d3dbf51SGreg Clayton { 22106d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 22116d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 22126d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 22136d3dbf51SGreg Clayton const char *var_value = var_value_sp->GetValueAsCString(); 22146d3dbf51SGreg Clayton if (arg_idx > 0) 22156d3dbf51SGreg Clayton s.PutCString (", "); 22163b188b17SGreg Clayton if (var_value_sp->GetError().Success()) 2217cc7f9bf5SEnrico Granata { 2218cc7f9bf5SEnrico Granata if (var_value) 22196d3dbf51SGreg Clayton s.Printf ("%s=%s", var_name, var_value); 22203b188b17SGreg Clayton else 2221cc7f9bf5SEnrico Granata s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2222cc7f9bf5SEnrico Granata } 2223cc7f9bf5SEnrico Granata else 22243b188b17SGreg Clayton s.Printf ("%s=<unavailable>", var_name); 22256d3dbf51SGreg Clayton } 22266d3dbf51SGreg Clayton 22276d3dbf51SGreg Clayton if (close_paren) 22286d3dbf51SGreg Clayton s.PutCString (close_paren); 22296d3dbf51SGreg Clayton else 22306d3dbf51SGreg Clayton s.PutChar(')'); 22316d3dbf51SGreg Clayton 22326d3dbf51SGreg Clayton } 22336d3dbf51SGreg Clayton else 22346d3dbf51SGreg Clayton { 22356d3dbf51SGreg Clayton s.PutCString(cstr); 22366d3dbf51SGreg Clayton } 22376d3dbf51SGreg Clayton } 22386d3dbf51SGreg Clayton } 22396d3dbf51SGreg Clayton else if (sc->symbol) 22406d3dbf51SGreg Clayton { 22416d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 22426d3dbf51SGreg Clayton if (cstr) 22436d3dbf51SGreg Clayton { 22446d3dbf51SGreg Clayton s.PutCString(cstr); 22456d3dbf51SGreg Clayton var_success = true; 22466d3dbf51SGreg Clayton } 22476d3dbf51SGreg Clayton } 22486d3dbf51SGreg Clayton } 22491b654882SGreg Clayton else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 22501b654882SGreg Clayton { 22511b654882SGreg Clayton var_success = addr != NULL; 22521b654882SGreg Clayton if (var_success) 22531b654882SGreg Clayton { 22541b654882SGreg Clayton format_addr = *addr; 22551b654882SGreg Clayton calculate_format_addr_function_offset = true; 22561b654882SGreg Clayton } 22571b654882SGreg Clayton } 22581b654882SGreg Clayton else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 22591b654882SGreg Clayton { 22601b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 22611b654882SGreg Clayton if (var_success) 22621b654882SGreg Clayton { 22631b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 22641b654882SGreg Clayton calculate_format_addr_function_offset = true; 22651b654882SGreg Clayton } 22661b654882SGreg Clayton } 22671b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 22681b654882SGreg Clayton { 2269c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2270c14ee32dSGreg Clayton var_success = frame != NULL; 22711b654882SGreg Clayton if (var_success) 22721b654882SGreg Clayton { 2273c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 22741b654882SGreg Clayton calculate_format_addr_function_offset = true; 22751b654882SGreg Clayton } 22761b654882SGreg Clayton } 22771b654882SGreg Clayton } 22781b654882SGreg Clayton } 22791b654882SGreg Clayton break; 22801b654882SGreg Clayton 22811b654882SGreg Clayton case 'l': 22821b654882SGreg Clayton if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 22831b654882SGreg Clayton { 22841b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 22851b654882SGreg Clayton { 22861b654882SGreg Clayton var_name_begin += ::strlen ("line."); 22871b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 22881b654882SGreg Clayton { 22891b654882SGreg Clayton var_name_begin += ::strlen ("file."); 22901b654882SGreg Clayton 22911b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 22921b654882SGreg Clayton { 22931b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 22941b654882SGreg Clayton var_success = format_file_spec; 22951b654882SGreg Clayton } 22961b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 22971b654882SGreg Clayton { 22981b654882SGreg Clayton format_file_spec = sc->line_entry.file; 22991b654882SGreg Clayton var_success = format_file_spec; 23001b654882SGreg Clayton } 23011b654882SGreg Clayton } 23021b654882SGreg Clayton else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 23031b654882SGreg Clayton { 23041b654882SGreg Clayton var_success = true; 23051b654882SGreg Clayton s.Printf("%u", sc->line_entry.line); 23061b654882SGreg Clayton } 23071b654882SGreg Clayton else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 23081b654882SGreg Clayton (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 23091b654882SGreg Clayton { 23101b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 23111b654882SGreg Clayton if (var_success) 23121b654882SGreg Clayton { 23131b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 23141b654882SGreg Clayton if (var_name_begin[0] == 'e') 23151b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 23161b654882SGreg Clayton } 23171b654882SGreg Clayton } 23181b654882SGreg Clayton } 23191b654882SGreg Clayton } 23201b654882SGreg Clayton break; 23211b654882SGreg Clayton } 23221b654882SGreg Clayton 23231b654882SGreg Clayton if (var_success) 23241b654882SGreg Clayton { 23251b654882SGreg Clayton // If format addr is valid, then we need to print an address 23261b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 23271b654882SGreg Clayton { 2328c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 23291b654882SGreg Clayton // We have a register value to display... 23301b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 23311b654882SGreg Clayton { 2332c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 23331b654882SGreg Clayton } 23341b654882SGreg Clayton else 23351b654882SGreg Clayton { 23361b654882SGreg Clayton if (reg_ctx == NULL) 2337c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 23381b654882SGreg Clayton 23391b654882SGreg Clayton if (reg_ctx) 23401b654882SGreg Clayton { 23411b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 23421b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 23431b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 23441b654882SGreg Clayton var_success = reg_info != NULL; 23451b654882SGreg Clayton } 23461b654882SGreg Clayton } 23471b654882SGreg Clayton } 23481b654882SGreg Clayton 23491b654882SGreg Clayton if (reg_info != NULL) 23501b654882SGreg Clayton { 23517349bd90SGreg Clayton RegisterValue reg_value; 23527349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 23537349bd90SGreg Clayton if (var_success) 23541b654882SGreg Clayton { 23559a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 23561b654882SGreg Clayton } 23571b654882SGreg Clayton } 23581b654882SGreg Clayton 23591b654882SGreg Clayton if (format_file_spec) 23601b654882SGreg Clayton { 23611b654882SGreg Clayton s << format_file_spec; 23621b654882SGreg Clayton } 23631b654882SGreg Clayton 23641b654882SGreg Clayton // If format addr is valid, then we need to print an address 23651b654882SGreg Clayton if (format_addr.IsValid()) 23661b654882SGreg Clayton { 23670603aa9dSGreg Clayton var_success = false; 23680603aa9dSGreg Clayton 23691b654882SGreg Clayton if (calculate_format_addr_function_offset) 23701b654882SGreg Clayton { 23711b654882SGreg Clayton Address func_addr; 23720603aa9dSGreg Clayton 23730603aa9dSGreg Clayton if (sc) 23740603aa9dSGreg Clayton { 23751b654882SGreg Clayton if (sc->function) 23760d9c9934SGreg Clayton { 23771b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 23780d9c9934SGreg Clayton if (sc->block) 23790d9c9934SGreg Clayton { 23800d9c9934SGreg Clayton // Check to make sure we aren't in an inline 23810d9c9934SGreg Clayton // function. If we are, use the inline block 23820d9c9934SGreg Clayton // range that contains "format_addr" since 23830d9c9934SGreg Clayton // blocks can be discontiguous. 23840d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 23850d9c9934SGreg Clayton AddressRange inline_range; 23860d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 23870d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 23880d9c9934SGreg Clayton } 23890d9c9934SGreg Clayton } 2390e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2391e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 23920603aa9dSGreg Clayton } 23931b654882SGreg Clayton 23940603aa9dSGreg Clayton if (func_addr.IsValid()) 23951b654882SGreg Clayton { 23961b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 23971b654882SGreg Clayton { 23981b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 23991b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 24001b654882SGreg Clayton if (addr_file_addr > func_file_addr) 2401d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr); 24021b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 2403d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr); 24040603aa9dSGreg Clayton var_success = true; 24051b654882SGreg Clayton } 24061b654882SGreg Clayton else 24070603aa9dSGreg Clayton { 24080603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24090603aa9dSGreg Clayton if (target) 24100603aa9dSGreg Clayton { 24110603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 24120603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 24130603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 2414d01b2953SDaniel Malea s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr); 24150603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 2416d01b2953SDaniel Malea s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr); 24170603aa9dSGreg Clayton var_success = true; 24180603aa9dSGreg Clayton } 24190603aa9dSGreg Clayton } 24201b654882SGreg Clayton } 24211b654882SGreg Clayton } 24221b654882SGreg Clayton else 24231b654882SGreg Clayton { 24240603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 24251b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 24260603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 24270603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 24281b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 24291b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 24301b654882SGreg Clayton 24311b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 24320603aa9dSGreg Clayton { 2433514487e8SGreg Clayton int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 243435f1a0d5SGreg Clayton if (addr_width == 0) 243535f1a0d5SGreg Clayton addr_width = 16; 2436d01b2953SDaniel Malea s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 24370603aa9dSGreg Clayton var_success = true; 24380603aa9dSGreg Clayton } 24391b654882SGreg Clayton } 24401b654882SGreg Clayton } 24411b654882SGreg Clayton } 24421b654882SGreg Clayton 24431b654882SGreg Clayton if (var_success == false) 24441b654882SGreg Clayton success = false; 24451b654882SGreg Clayton } 24461b654882SGreg Clayton p = var_name_end; 24471b654882SGreg Clayton } 24481b654882SGreg Clayton else 24491b654882SGreg Clayton break; 24501b654882SGreg Clayton } 24511b654882SGreg Clayton else 24521b654882SGreg Clayton { 24531b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 24541b654882SGreg Clayton s.PutChar(*p); 24551b654882SGreg Clayton } 24561b654882SGreg Clayton } 24571b654882SGreg Clayton else if (*p == '\\') 24581b654882SGreg Clayton { 24591b654882SGreg Clayton ++p; // skip the slash 24601b654882SGreg Clayton switch (*p) 24611b654882SGreg Clayton { 24621b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 24631b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 24641b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 24651b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 24661b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 24671b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 24681b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 24691b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 24701b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 24711b654882SGreg Clayton case '0': 24721b654882SGreg Clayton // 1 to 3 octal chars 24731b654882SGreg Clayton { 24740603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 24750603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 24760603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 24770603aa9dSGreg Clayton 24780603aa9dSGreg Clayton int i; 24790603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 24800603aa9dSGreg Clayton oct_str[i] = p[i]; 24810603aa9dSGreg Clayton 24820603aa9dSGreg Clayton // We don't want to consume the last octal character since 24830603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 24840603aa9dSGreg Clayton // one less than i (even if i is zero) 24850603aa9dSGreg Clayton p += i - 1; 24860603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 24870603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 24881b654882SGreg Clayton { 2489c7bece56SGreg Clayton s.PutChar((char)octal_value); 24901b654882SGreg Clayton } 24911b654882SGreg Clayton } 24921b654882SGreg Clayton break; 24931b654882SGreg Clayton 24941b654882SGreg Clayton case 'x': 24951b654882SGreg Clayton // hex number in the format 24960603aa9dSGreg Clayton if (isxdigit(p[1])) 24971b654882SGreg Clayton { 24980603aa9dSGreg Clayton ++p; // Skip the 'x' 24991b654882SGreg Clayton 25000603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 25010603aa9dSGreg Clayton // NULL terminator 25021b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 25031b654882SGreg Clayton hex_str[0] = *p; 25040603aa9dSGreg Clayton if (isxdigit(p[1])) 25050603aa9dSGreg Clayton { 25060603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 25071b654882SGreg Clayton hex_str[1] = *p; 25080603aa9dSGreg Clayton } 25090603aa9dSGreg Clayton 25101b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 25110603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 2512c7bece56SGreg Clayton s.PutChar ((char)hex_value); 25131b654882SGreg Clayton } 25141b654882SGreg Clayton else 25151b654882SGreg Clayton { 25160603aa9dSGreg Clayton s.PutChar('x'); 25171b654882SGreg Clayton } 25181b654882SGreg Clayton break; 25191b654882SGreg Clayton 25201b654882SGreg Clayton default: 25210603aa9dSGreg Clayton // Just desensitize any other character by just printing what 25220603aa9dSGreg Clayton // came after the '\' 25230603aa9dSGreg Clayton s << *p; 25241b654882SGreg Clayton break; 25251b654882SGreg Clayton 25261b654882SGreg Clayton } 25271b654882SGreg Clayton 25281b654882SGreg Clayton } 25291b654882SGreg Clayton } 25301b654882SGreg Clayton if (end) 25311b654882SGreg Clayton *end = p; 25321b654882SGreg Clayton return success; 25331b654882SGreg Clayton } 25341b654882SGreg Clayton 2535c3ce7f27SMichael Sartain bool 2536c3ce7f27SMichael Sartain Debugger::FormatPrompt 2537c3ce7f27SMichael Sartain ( 2538c3ce7f27SMichael Sartain const char *format, 2539c3ce7f27SMichael Sartain const SymbolContext *sc, 2540c3ce7f27SMichael Sartain const ExecutionContext *exe_ctx, 2541c3ce7f27SMichael Sartain const Address *addr, 2542c3ce7f27SMichael Sartain Stream &s, 2543c3ce7f27SMichael Sartain ValueObject* valobj 2544c3ce7f27SMichael Sartain ) 2545c3ce7f27SMichael Sartain { 2546c3ce7f27SMichael Sartain bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true; 2547c3ce7f27SMichael Sartain std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color); 2548c3ce7f27SMichael Sartain if (format_str.length()) 2549c3ce7f27SMichael Sartain format = format_str.c_str(); 2550c3ce7f27SMichael Sartain return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj); 2551c3ce7f27SMichael Sartain } 2552c3ce7f27SMichael Sartain 2553228063cdSJim Ingham void 2554228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2555228063cdSJim Ingham { 25564f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 25574f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 25584f02b22dSJim Ingham // callback. 2559228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2560228063cdSJim Ingham } 2561228063cdSJim Ingham 2562228063cdSJim Ingham bool 2563228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2564228063cdSJim Ingham { 2565228063cdSJim Ingham Log::Callbacks log_callbacks; 2566228063cdSJim Ingham 2567228063cdSJim Ingham StreamSP log_stream_sp; 25689a028519SSean Callanan if (m_log_callback_stream_sp) 2569228063cdSJim Ingham { 2570228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2571228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2572228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2573228063cdSJim Ingham } 2574228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2575228063cdSJim Ingham { 2576228063cdSJim Ingham log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false)); 2577228063cdSJim Ingham } 2578228063cdSJim Ingham else 2579228063cdSJim Ingham { 2580228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2581c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 2582c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 2583c1b2ccfdSGreg Clayton if (!log_stream_sp) 2584228063cdSJim Ingham { 2585228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2586228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2587228063cdSJim Ingham } 2588228063cdSJim Ingham } 2589228063cdSJim Ingham assert (log_stream_sp.get()); 2590228063cdSJim Ingham 2591228063cdSJim Ingham if (log_options == 0) 2592228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2593228063cdSJim Ingham 259457abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 2595228063cdSJim Ingham { 2596228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2597228063cdSJim Ingham return true; 2598228063cdSJim Ingham } 2599228063cdSJim Ingham else 2600228063cdSJim Ingham { 2601228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2602228063cdSJim Ingham if (log_channel_sp) 2603228063cdSJim Ingham { 2604228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2605228063cdSJim Ingham { 2606228063cdSJim Ingham return true; 2607228063cdSJim Ingham } 2608228063cdSJim Ingham else 2609228063cdSJim Ingham { 2610228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2611228063cdSJim Ingham return false; 2612228063cdSJim Ingham } 2613228063cdSJim Ingham } 2614228063cdSJim Ingham else 2615228063cdSJim Ingham { 2616228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2617228063cdSJim Ingham return false; 2618228063cdSJim Ingham } 2619228063cdSJim Ingham } 2620228063cdSJim Ingham return false; 2621228063cdSJim Ingham } 2622228063cdSJim Ingham 26239585fbfcSGreg Clayton SourceManager & 26249585fbfcSGreg Clayton Debugger::GetSourceManager () 26259585fbfcSGreg Clayton { 26269585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 26279585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 26289585fbfcSGreg Clayton return *m_source_manager_ap; 26299585fbfcSGreg Clayton } 26309585fbfcSGreg Clayton 26319585fbfcSGreg Clayton 2632