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 124a33d318SGreg Clayton #include "lldb/Core/Debugger.h" 134a33d318SGreg Clayton 144a33d318SGreg Clayton #include <map> 154a33d318SGreg Clayton 164becb37eSEnrico Granata #include "clang/AST/DeclCXX.h" 174becb37eSEnrico Granata #include "clang/AST/Type.h" 18705b1809SJason Molenda #include "llvm/ADT/StringRef.h" 194becb37eSEnrico Granata 2030fdc8d8SChris Lattner #include "lldb/lldb-private.h" 211f746071SGreg Clayton #include "lldb/Core/Module.h" 22e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h" 237349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 2430fdc8d8SChris Lattner #include "lldb/Core/State.h" 255b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h" 26228063cdSJim Ingham #include "lldb/Core/StreamCallback.h" 2744d93782SGreg Clayton #include "lldb/Core/StreamFile.h" 281b654882SGreg Clayton #include "lldb/Core/StreamString.h" 29705b1809SJason Molenda #include "lldb/Core/StructuredData.h" 3030fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 314becb37eSEnrico Granata #include "lldb/Core/ValueObject.h" 326d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 335548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 345548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h" 35894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h" 3693a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h" 3742ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h" 38a3406614SGreg Clayton #include "lldb/Host/Terminal.h" 3939de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h" 406611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 4167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h" 4267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 431f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h" 441f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 451f746071SGreg Clayton #include "lldb/Symbol/Function.h" 461f746071SGreg Clayton #include "lldb/Symbol/Symbol.h" 476d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h" 48aff1b357SJason Molenda #include "lldb/Target/CPPLanguageRuntime.h" 49aff1b357SJason Molenda #include "lldb/Target/ObjCLanguageRuntime.h" 5030fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 5130fdc8d8SChris Lattner #include "lldb/Target/Process.h" 521b654882SGreg Clayton #include "lldb/Target/RegisterContext.h" 535fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h" 541b654882SGreg Clayton #include "lldb/Target/StopInfo.h" 5584a53dfbSEnrico Granata #include "lldb/Target/Target.h" 5630fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 575a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h" 5830fdc8d8SChris Lattner 5958a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h" 6058a559c0SZachary Turner 6130fdc8d8SChris Lattner using namespace lldb; 6230fdc8d8SChris Lattner using namespace lldb_private; 6330fdc8d8SChris Lattner 6430fdc8d8SChris Lattner 651b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0; 66ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1; 677c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024; 68ebc1bb27SCaroline Tice 691b654882SGreg Clayton #pragma mark Static Functions 701b654882SGreg Clayton 711b654882SGreg Clayton static Mutex & 721b654882SGreg Clayton GetDebuggerListMutex () 731b654882SGreg Clayton { 741b654882SGreg Clayton static Mutex g_mutex(Mutex::eMutexTypeRecursive); 751b654882SGreg Clayton return g_mutex; 761b654882SGreg Clayton } 771b654882SGreg Clayton 781b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList; 791b654882SGreg Clayton 801b654882SGreg Clayton static DebuggerList & 811b654882SGreg Clayton GetDebuggerList() 821b654882SGreg Clayton { 831b654882SGreg Clayton // hide the static debugger list inside a singleton accessor to avoid 846a7f3338SBruce Mitchener // global init constructors 851b654882SGreg Clayton static DebuggerList g_list; 861b654882SGreg Clayton return g_list; 871b654882SGreg Clayton } 88e372b98dSGreg Clayton 89e372b98dSGreg Clayton OptionEnumValueElement 9067cc0636SGreg Clayton g_show_disassembly_enum_values[] = 91e372b98dSGreg Clayton { 9267cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, 9367cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, 9467cc0636SGreg Clayton { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, 95e372b98dSGreg Clayton { 0, NULL, NULL } 96e372b98dSGreg Clayton }; 97e372b98dSGreg Clayton 9867cc0636SGreg Clayton OptionEnumValueElement 9967cc0636SGreg Clayton g_language_enumerators[] = 10067cc0636SGreg Clayton { 10167cc0636SGreg Clayton { eScriptLanguageNone, "none", "Disable scripting languages."}, 10267cc0636SGreg Clayton { eScriptLanguagePython, "python", "Select python as the default scripting language."}, 10367cc0636SGreg Clayton { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."}, 104a12993c9SGreg Clayton { 0, NULL, NULL } 10567cc0636SGreg Clayton }; 106e372b98dSGreg Clayton 10767cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" 10867cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 10967cc0636SGreg Clayton 1100769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ 11167cc0636SGreg Clayton "{, ${frame.pc}}"\ 11267cc0636SGreg Clayton MODULE_WITH_FUNC\ 11367cc0636SGreg Clayton FILE_AND_LINE\ 1140769b2b1SMichael Sartain "{, name = '${thread.name}'}"\ 1150769b2b1SMichael Sartain "{, queue = '${thread.queue}'}"\ 116705b1809SJason Molenda "{, activity = '${thread.info.activity.name}'}" \ 117705b1809SJason Molenda "{, ${thread.info.trace_messages} messages}" \ 11867cc0636SGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 11967cc0636SGreg Clayton "{\\nReturn value: ${thread.return-value}}"\ 12030fadafeSJim Ingham "{\\nCompleted expression: ${thread.completed-expression}}"\ 12167cc0636SGreg Clayton "\\n" 12267cc0636SGreg Clayton 12367cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 12467cc0636SGreg Clayton MODULE_WITH_FUNC\ 12567cc0636SGreg Clayton FILE_AND_LINE\ 12667cc0636SGreg Clayton "\\n" 12767cc0636SGreg Clayton 1280abae879SJason Molenda #define DEFAULT_DISASSEMBLY_FORMAT "${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: " 12967cc0636SGreg Clayton 130754a9369SGreg Clayton static PropertyDefinition 131754a9369SGreg Clayton g_properties[] = 13267cc0636SGreg Clayton { 13367cc0636SGreg Clayton { "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." }, 134aff1b357SJason Molenda { "disassembly-format", OptionValue::eTypeString , true, 0 , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." }, 13567cc0636SGreg 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." }, 13667cc0636SGreg Clayton { "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." }, 1374c05410fSGreg Clayton { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, 13867cc0636SGreg Clayton { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, 13967cc0636SGreg Clayton { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, 14067cc0636SGreg 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." }, 14167cc0636SGreg 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." }, 14267cc0636SGreg 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." }, 14367cc0636SGreg Clayton { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, 14467cc0636SGreg Clayton { "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." }, 14567cc0636SGreg Clayton { "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." }, 146c3ce7f27SMichael Sartain { "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." }, 14790a8db30SEnrico Granata { "auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." }, 148ebdc1ac0SEnrico Granata { "escape-non-printables", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." }, 149e8cd0c98SGreg Clayton 15067cc0636SGreg Clayton { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 15167cc0636SGreg Clayton }; 15267cc0636SGreg Clayton 15367cc0636SGreg Clayton enum 15467cc0636SGreg Clayton { 15567cc0636SGreg Clayton ePropertyAutoConfirm = 0, 156aff1b357SJason Molenda ePropertyDisassemblyFormat, 15767cc0636SGreg Clayton ePropertyFrameFormat, 15867cc0636SGreg Clayton ePropertyNotiftVoid, 15967cc0636SGreg Clayton ePropertyPrompt, 16067cc0636SGreg Clayton ePropertyScriptLanguage, 16167cc0636SGreg Clayton ePropertyStopDisassemblyCount, 16267cc0636SGreg Clayton ePropertyStopDisassemblyDisplay, 16367cc0636SGreg Clayton ePropertyStopLineCountAfter, 16467cc0636SGreg Clayton ePropertyStopLineCountBefore, 16567cc0636SGreg Clayton ePropertyTerminalWidth, 16667cc0636SGreg Clayton ePropertyThreadFormat, 167c3ce7f27SMichael Sartain ePropertyUseExternalEditor, 168c3ce7f27SMichael Sartain ePropertyUseColor, 169ebdc1ac0SEnrico Granata ePropertyAutoOneLineSummaries, 170ebdc1ac0SEnrico Granata ePropertyEscapeNonPrintables 17167cc0636SGreg Clayton }; 17267cc0636SGreg Clayton 1735fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL; 1744c05410fSGreg Clayton 1754c05410fSGreg Clayton Error 1764c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx, 1774c05410fSGreg Clayton VarSetOperationType op, 1784c05410fSGreg Clayton const char *property_path, 1794c05410fSGreg Clayton const char *value) 1804c05410fSGreg Clayton { 18184a53dfbSEnrico Granata bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0; 182ebdc1ac0SEnrico Granata bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0; 18384a53dfbSEnrico Granata TargetSP target_sp; 184397ddd5fSEnrico Granata LoadScriptFromSymFile load_script_old_value; 18584a53dfbSEnrico Granata if (is_load_script && exe_ctx->GetTargetSP()) 18684a53dfbSEnrico Granata { 18784a53dfbSEnrico Granata target_sp = exe_ctx->GetTargetSP(); 18884a53dfbSEnrico Granata load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); 18984a53dfbSEnrico Granata } 1904c05410fSGreg Clayton Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value)); 1914c05410fSGreg Clayton if (error.Success()) 1924c05410fSGreg Clayton { 19384a53dfbSEnrico Granata // FIXME it would be nice to have "on-change" callbacks for properties 1944c05410fSGreg Clayton if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) 1954c05410fSGreg Clayton { 1964c05410fSGreg Clayton const char *new_prompt = GetPrompt(); 197c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 198c3ce7f27SMichael Sartain if (str.length()) 199c3ce7f27SMichael Sartain new_prompt = str.c_str(); 20044d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 2014c05410fSGreg Clayton EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt))); 2024c05410fSGreg Clayton GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp); 2034c05410fSGreg Clayton } 204c3ce7f27SMichael Sartain else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0) 205c3ce7f27SMichael Sartain { 206c3ce7f27SMichael Sartain // use-color changed. Ping the prompt so it can reset the ansi terminal codes. 207c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 208c3ce7f27SMichael Sartain } 209397ddd5fSEnrico Granata else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) 21084a53dfbSEnrico Granata { 211397ddd5fSEnrico Granata if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue) 21284a53dfbSEnrico Granata { 21384a53dfbSEnrico Granata std::list<Error> errors; 2149730339bSEnrico Granata StreamString feedback_stream; 2159730339bSEnrico Granata if (!target_sp->LoadScriptingResources(errors,&feedback_stream)) 21684a53dfbSEnrico Granata { 21744d93782SGreg Clayton StreamFileSP stream_sp (GetErrorFile()); 21844d93782SGreg Clayton if (stream_sp) 21944d93782SGreg Clayton { 22084a53dfbSEnrico Granata for (auto error : errors) 22184a53dfbSEnrico Granata { 22244d93782SGreg Clayton stream_sp->Printf("%s\n",error.AsCString()); 22384a53dfbSEnrico Granata } 2249730339bSEnrico Granata if (feedback_stream.GetSize()) 22544d93782SGreg Clayton stream_sp->Printf("%s",feedback_stream.GetData()); 22644d93782SGreg Clayton } 22784a53dfbSEnrico Granata } 22884a53dfbSEnrico Granata } 22984a53dfbSEnrico Granata } 230ebdc1ac0SEnrico Granata else if (is_escape_non_printables) 231ebdc1ac0SEnrico Granata { 232ebdc1ac0SEnrico Granata DataVisualization::ForceUpdate(); 233ebdc1ac0SEnrico Granata } 2344c05410fSGreg Clayton } 2354c05410fSGreg Clayton return error; 2364c05410fSGreg Clayton } 2374c05410fSGreg Clayton 23867cc0636SGreg Clayton bool 23967cc0636SGreg Clayton Debugger::GetAutoConfirm () const 24067cc0636SGreg Clayton { 24167cc0636SGreg Clayton const uint32_t idx = ePropertyAutoConfirm; 242754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 24367cc0636SGreg Clayton } 24467cc0636SGreg Clayton 24567cc0636SGreg Clayton const char * 246aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const 247aff1b357SJason Molenda { 248aff1b357SJason Molenda const uint32_t idx = ePropertyDisassemblyFormat; 249aff1b357SJason Molenda return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 250aff1b357SJason Molenda } 251aff1b357SJason Molenda 252aff1b357SJason Molenda const char * 25367cc0636SGreg Clayton Debugger::GetFrameFormat() const 25467cc0636SGreg Clayton { 25567cc0636SGreg Clayton const uint32_t idx = ePropertyFrameFormat; 256754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 25767cc0636SGreg Clayton } 25867cc0636SGreg Clayton 25967cc0636SGreg Clayton bool 26067cc0636SGreg Clayton Debugger::GetNotifyVoid () const 26167cc0636SGreg Clayton { 26267cc0636SGreg Clayton const uint32_t idx = ePropertyNotiftVoid; 263754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 26467cc0636SGreg Clayton } 26567cc0636SGreg Clayton 26667cc0636SGreg Clayton const char * 26767cc0636SGreg Clayton Debugger::GetPrompt() const 26867cc0636SGreg Clayton { 26967cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 270754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 27167cc0636SGreg Clayton } 27267cc0636SGreg Clayton 27367cc0636SGreg Clayton void 27467cc0636SGreg Clayton Debugger::SetPrompt(const char *p) 27567cc0636SGreg Clayton { 27667cc0636SGreg Clayton const uint32_t idx = ePropertyPrompt; 27767cc0636SGreg Clayton m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p); 27867cc0636SGreg Clayton const char *new_prompt = GetPrompt(); 279c3ce7f27SMichael Sartain std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor()); 280c3ce7f27SMichael Sartain if (str.length()) 281c3ce7f27SMichael Sartain new_prompt = str.c_str(); 28244d93782SGreg Clayton GetCommandInterpreter().UpdatePrompt(new_prompt); 28367cc0636SGreg Clayton } 28467cc0636SGreg Clayton 28567cc0636SGreg Clayton const char * 28667cc0636SGreg Clayton Debugger::GetThreadFormat() const 28767cc0636SGreg Clayton { 28867cc0636SGreg Clayton const uint32_t idx = ePropertyThreadFormat; 289754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value); 29067cc0636SGreg Clayton } 29167cc0636SGreg Clayton 29267cc0636SGreg Clayton lldb::ScriptLanguage 29367cc0636SGreg Clayton Debugger::GetScriptLanguage() const 29467cc0636SGreg Clayton { 29567cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 296754a9369SGreg Clayton return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 29767cc0636SGreg Clayton } 29867cc0636SGreg Clayton 29967cc0636SGreg Clayton bool 30067cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang) 30167cc0636SGreg Clayton { 30267cc0636SGreg Clayton const uint32_t idx = ePropertyScriptLanguage; 30367cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang); 30467cc0636SGreg Clayton } 30567cc0636SGreg Clayton 30667cc0636SGreg Clayton uint32_t 30767cc0636SGreg Clayton Debugger::GetTerminalWidth () const 30867cc0636SGreg Clayton { 30967cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 310754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 31167cc0636SGreg Clayton } 31267cc0636SGreg Clayton 31367cc0636SGreg Clayton bool 31467cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width) 31567cc0636SGreg Clayton { 31667cc0636SGreg Clayton const uint32_t idx = ePropertyTerminalWidth; 31767cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width); 31867cc0636SGreg Clayton } 31967cc0636SGreg Clayton 32067cc0636SGreg Clayton bool 32167cc0636SGreg Clayton Debugger::GetUseExternalEditor () const 32267cc0636SGreg Clayton { 32367cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 324754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 32567cc0636SGreg Clayton } 32667cc0636SGreg Clayton 32767cc0636SGreg Clayton bool 32867cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b) 32967cc0636SGreg Clayton { 33067cc0636SGreg Clayton const uint32_t idx = ePropertyUseExternalEditor; 33167cc0636SGreg Clayton return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 33267cc0636SGreg Clayton } 33367cc0636SGreg Clayton 334c3ce7f27SMichael Sartain bool 335c3ce7f27SMichael Sartain Debugger::GetUseColor () const 336c3ce7f27SMichael Sartain { 337c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 338c3ce7f27SMichael Sartain return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 339c3ce7f27SMichael Sartain } 340c3ce7f27SMichael Sartain 341c3ce7f27SMichael Sartain bool 342c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b) 343c3ce7f27SMichael Sartain { 344c3ce7f27SMichael Sartain const uint32_t idx = ePropertyUseColor; 345c3ce7f27SMichael Sartain bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); 346c3ce7f27SMichael Sartain SetPrompt (GetPrompt()); 347c3ce7f27SMichael Sartain return ret; 348c3ce7f27SMichael Sartain } 349c3ce7f27SMichael Sartain 35067cc0636SGreg Clayton uint32_t 35167cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const 35267cc0636SGreg Clayton { 35367cc0636SGreg Clayton const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; 354754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 35567cc0636SGreg Clayton } 35667cc0636SGreg Clayton 35767cc0636SGreg Clayton Debugger::StopDisassemblyType 35867cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const 35967cc0636SGreg Clayton { 36067cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyDisplay; 361754a9369SGreg Clayton return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value); 36267cc0636SGreg Clayton } 36367cc0636SGreg Clayton 36467cc0636SGreg Clayton uint32_t 36567cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const 36667cc0636SGreg Clayton { 36767cc0636SGreg Clayton const uint32_t idx = ePropertyStopDisassemblyCount; 368754a9369SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value); 36967cc0636SGreg Clayton } 370e372b98dSGreg Clayton 371553fad5cSEnrico Granata bool 37290a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const 373553fad5cSEnrico Granata { 37490a8db30SEnrico Granata const uint32_t idx = ePropertyAutoOneLineSummaries; 375553fad5cSEnrico Granata return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); 376ebdc1ac0SEnrico Granata } 377553fad5cSEnrico Granata 378ebdc1ac0SEnrico Granata bool 379ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const 380ebdc1ac0SEnrico Granata { 381ebdc1ac0SEnrico Granata const uint32_t idx = ePropertyEscapeNonPrintables; 382ebdc1ac0SEnrico Granata return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); 383553fad5cSEnrico Granata } 384553fad5cSEnrico Granata 3851b654882SGreg Clayton #pragma mark Debugger 3861b654882SGreg Clayton 38767cc0636SGreg Clayton //const DebuggerPropertiesSP & 38867cc0636SGreg Clayton //Debugger::GetSettings() const 38967cc0636SGreg Clayton //{ 39067cc0636SGreg Clayton // return m_properties_sp; 39167cc0636SGreg Clayton //} 39267cc0636SGreg Clayton // 39399d0faf2SGreg Clayton 3942f88aadfSCaroline Tice int 3952f88aadfSCaroline Tice Debugger::TestDebuggerRefCount () 3962f88aadfSCaroline Tice { 3972f88aadfSCaroline Tice return g_shared_debugger_refcount; 3982f88aadfSCaroline Tice } 3992f88aadfSCaroline Tice 40030fdc8d8SChris Lattner void 4015fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback) 40230fdc8d8SChris Lattner { 4035fb8f797SGreg Clayton g_load_plugin_callback = load_plugin_callback; 404c15f55e2SGreg Clayton if (g_shared_debugger_refcount++ == 0) 405dbe54508SGreg Clayton lldb_private::Initialize(); 40699d0faf2SGreg Clayton } 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner void 40930fdc8d8SChris Lattner Debugger::Terminate () 41030fdc8d8SChris Lattner { 4116611103cSGreg Clayton if (g_shared_debugger_refcount > 0) 4126611103cSGreg Clayton { 41330fdc8d8SChris Lattner g_shared_debugger_refcount--; 41430fdc8d8SChris Lattner if (g_shared_debugger_refcount == 0) 41530fdc8d8SChris Lattner { 416dbe54508SGreg Clayton lldb_private::WillTerminate(); 417dbe54508SGreg Clayton lldb_private::Terminate(); 4186760a517SCaroline Tice 41999d0faf2SGreg Clayton // Clear our master list of debugger objects 42099d0faf2SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 42199d0faf2SGreg Clayton GetDebuggerList().clear(); 42230fdc8d8SChris Lattner } 4236760a517SCaroline Tice } 4246760a517SCaroline Tice } 42530fdc8d8SChris Lattner 42620bd37f7SCaroline Tice void 42720bd37f7SCaroline Tice Debugger::SettingsInitialize () 42820bd37f7SCaroline Tice { 4296920b52bSGreg Clayton Target::SettingsInitialize (); 43020bd37f7SCaroline Tice } 43120bd37f7SCaroline Tice 43220bd37f7SCaroline Tice void 43320bd37f7SCaroline Tice Debugger::SettingsTerminate () 43420bd37f7SCaroline Tice { 4356920b52bSGreg Clayton Target::SettingsTerminate (); 43620bd37f7SCaroline Tice } 43720bd37f7SCaroline Tice 43821dfcd9dSEnrico Granata bool 439e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error) 44021dfcd9dSEnrico Granata { 4415fb8f797SGreg Clayton if (g_load_plugin_callback) 442e743c782SEnrico Granata { 44358a559c0SZachary Turner llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error); 44458a559c0SZachary Turner if (dynlib.isValid()) 44521dfcd9dSEnrico Granata { 44658a559c0SZachary Turner m_loaded_plugins.push_back(dynlib); 44721dfcd9dSEnrico Granata return true; 44821dfcd9dSEnrico Granata } 4495fb8f797SGreg Clayton } 4505fb8f797SGreg Clayton else 4515fb8f797SGreg Clayton { 4525fb8f797SGreg Clayton // The g_load_plugin_callback is registered in SBDebugger::Initialize() 4535fb8f797SGreg Clayton // and if the public API layer isn't available (code is linking against 4545fb8f797SGreg Clayton // all of the internal LLDB static libraries), then we can't load plugins 4555fb8f797SGreg Clayton error.SetErrorString("Public API layer is not available"); 4565fb8f797SGreg Clayton } 45721dfcd9dSEnrico Granata return false; 45821dfcd9dSEnrico Granata } 45921dfcd9dSEnrico Granata 46021dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult 46121dfcd9dSEnrico Granata LoadPluginCallback 46221dfcd9dSEnrico Granata ( 46321dfcd9dSEnrico Granata void *baton, 46421dfcd9dSEnrico Granata FileSpec::FileType file_type, 46521dfcd9dSEnrico Granata const FileSpec &file_spec 46621dfcd9dSEnrico Granata ) 46721dfcd9dSEnrico Granata { 46821dfcd9dSEnrico Granata Error error; 46921dfcd9dSEnrico Granata 47021dfcd9dSEnrico Granata static ConstString g_dylibext("dylib"); 4713cf443ddSMichael Sartain static ConstString g_solibext("so"); 47221dfcd9dSEnrico Granata 47321dfcd9dSEnrico Granata if (!baton) 47421dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultQuit; 47521dfcd9dSEnrico Granata 47621dfcd9dSEnrico Granata Debugger *debugger = (Debugger*)baton; 47721dfcd9dSEnrico Granata 47821dfcd9dSEnrico Granata // If we have a regular file, a symbolic link or unknown file type, try 47921dfcd9dSEnrico Granata // and process the file. We must handle unknown as sometimes the directory 48021dfcd9dSEnrico Granata // enumeration might be enumerating a file system that doesn't have correct 48121dfcd9dSEnrico Granata // file type information. 48221dfcd9dSEnrico Granata if (file_type == FileSpec::eFileTypeRegular || 48321dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink || 48421dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeUnknown ) 48521dfcd9dSEnrico Granata { 48621dfcd9dSEnrico Granata FileSpec plugin_file_spec (file_spec); 48721dfcd9dSEnrico Granata plugin_file_spec.ResolvePath (); 48821dfcd9dSEnrico Granata 4893cf443ddSMichael Sartain if (plugin_file_spec.GetFileNameExtension() != g_dylibext && 4903cf443ddSMichael Sartain plugin_file_spec.GetFileNameExtension() != g_solibext) 4913cf443ddSMichael Sartain { 49221dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 4933cf443ddSMichael Sartain } 49421dfcd9dSEnrico Granata 495e743c782SEnrico Granata Error plugin_load_error; 496e743c782SEnrico Granata debugger->LoadPlugin (plugin_file_spec, plugin_load_error); 49721dfcd9dSEnrico Granata 49821dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 49921dfcd9dSEnrico Granata } 50021dfcd9dSEnrico Granata 50121dfcd9dSEnrico Granata else if (file_type == FileSpec::eFileTypeUnknown || 50221dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeDirectory || 50321dfcd9dSEnrico Granata file_type == FileSpec::eFileTypeSymbolicLink ) 50421dfcd9dSEnrico Granata { 50521dfcd9dSEnrico Granata // Try and recurse into anything that a directory or symbolic link. 50621dfcd9dSEnrico Granata // We must also do this for unknown as sometimes the directory enumeration 5076a7f3338SBruce Mitchener // might be enumerating a file system that doesn't have correct file type 50821dfcd9dSEnrico Granata // information. 50921dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultEnter; 51021dfcd9dSEnrico Granata } 51121dfcd9dSEnrico Granata 51221dfcd9dSEnrico Granata return FileSpec::eEnumerateDirectoryResultNext; 51321dfcd9dSEnrico Granata } 51421dfcd9dSEnrico Granata 51521dfcd9dSEnrico Granata void 51621dfcd9dSEnrico Granata Debugger::InstanceInitialize () 51721dfcd9dSEnrico Granata { 51821dfcd9dSEnrico Granata FileSpec dir_spec; 51921dfcd9dSEnrico Granata const bool find_directories = true; 52021dfcd9dSEnrico Granata const bool find_files = true; 52121dfcd9dSEnrico Granata const bool find_other = true; 52221dfcd9dSEnrico Granata char dir_path[PATH_MAX]; 52342ff0ad8SZachary Turner if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) 52421dfcd9dSEnrico Granata { 52521dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 52621dfcd9dSEnrico Granata { 52721dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 52821dfcd9dSEnrico Granata find_directories, 52921dfcd9dSEnrico Granata find_files, 53021dfcd9dSEnrico Granata find_other, 53121dfcd9dSEnrico Granata LoadPluginCallback, 53221dfcd9dSEnrico Granata this); 53321dfcd9dSEnrico Granata } 53421dfcd9dSEnrico Granata } 53521dfcd9dSEnrico Granata 53642ff0ad8SZachary Turner if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) 53721dfcd9dSEnrico Granata { 53821dfcd9dSEnrico Granata if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) 53921dfcd9dSEnrico Granata { 54021dfcd9dSEnrico Granata FileSpec::EnumerateDirectory (dir_path, 54121dfcd9dSEnrico Granata find_directories, 54221dfcd9dSEnrico Granata find_files, 54321dfcd9dSEnrico Granata find_other, 54421dfcd9dSEnrico Granata LoadPluginCallback, 54521dfcd9dSEnrico Granata this); 54621dfcd9dSEnrico Granata } 54721dfcd9dSEnrico Granata } 548e8cd0c98SGreg Clayton 549e8cd0c98SGreg Clayton PluginManager::DebuggerInitialize (*this); 55021dfcd9dSEnrico Granata } 55121dfcd9dSEnrico Granata 5526611103cSGreg Clayton DebuggerSP 553228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 5546611103cSGreg Clayton { 555228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 556c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 5576611103cSGreg Clayton { 5586611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5596611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 5606611103cSGreg Clayton } 56121dfcd9dSEnrico Granata debugger_sp->InstanceInitialize (); 5626611103cSGreg Clayton return debugger_sp; 5636611103cSGreg Clayton } 5646611103cSGreg Clayton 565e02657b1SCaroline Tice void 5664d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 567e02657b1SCaroline Tice { 568e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 569e02657b1SCaroline Tice return; 570e02657b1SCaroline Tice 5718314c525SJim Ingham debugger_sp->Clear(); 5728314c525SJim Ingham 573c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 574c15f55e2SGreg Clayton { 575e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 576e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 577e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 578e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 579e02657b1SCaroline Tice { 580e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 581e02657b1SCaroline Tice { 582e02657b1SCaroline Tice debugger_list.erase (pos); 583e02657b1SCaroline Tice return; 584e02657b1SCaroline Tice } 585e02657b1SCaroline Tice } 586e02657b1SCaroline Tice } 587c15f55e2SGreg Clayton } 588e02657b1SCaroline Tice 5894d122c40SGreg Clayton DebuggerSP 5903df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 5913df9a8dfSCaroline Tice { 5924d122c40SGreg Clayton DebuggerSP debugger_sp; 5936920b52bSGreg Clayton if (g_shared_debugger_refcount > 0) 5946920b52bSGreg Clayton { 5956920b52bSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 5966920b52bSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 5976920b52bSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 5986920b52bSGreg Clayton 5996920b52bSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 6006920b52bSGreg Clayton { 6016920b52bSGreg Clayton if ((*pos).get()->m_instance_name == instance_name) 6026920b52bSGreg Clayton { 6036920b52bSGreg Clayton debugger_sp = *pos; 6046920b52bSGreg Clayton break; 6056920b52bSGreg Clayton } 6066920b52bSGreg Clayton } 6076920b52bSGreg Clayton } 6083df9a8dfSCaroline Tice return debugger_sp; 6093df9a8dfSCaroline Tice } 6106611103cSGreg Clayton 6116611103cSGreg Clayton TargetSP 6126611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 6136611103cSGreg Clayton { 6144d122c40SGreg Clayton TargetSP target_sp; 615c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 616c15f55e2SGreg Clayton { 6176611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 6186611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 6196611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 6206611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 6216611103cSGreg Clayton { 6226611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 6236611103cSGreg Clayton if (target_sp) 6246611103cSGreg Clayton break; 6256611103cSGreg Clayton } 626c15f55e2SGreg Clayton } 6276611103cSGreg Clayton return target_sp; 6286611103cSGreg Clayton } 6296611103cSGreg Clayton 630e4e45924SGreg Clayton TargetSP 631e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 632e4e45924SGreg Clayton { 633e4e45924SGreg Clayton TargetSP target_sp; 634c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 635c15f55e2SGreg Clayton { 636e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 637e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 638e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 639e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 640e4e45924SGreg Clayton { 641e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 642e4e45924SGreg Clayton if (target_sp) 643e4e45924SGreg Clayton break; 644e4e45924SGreg Clayton } 645c15f55e2SGreg Clayton } 646e4e45924SGreg Clayton return target_sp; 647e4e45924SGreg Clayton } 648e4e45924SGreg Clayton 649e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) : 650e6481c7eSJason Molenda UserID(g_unique_id++), 651e6481c7eSJason Molenda Properties(OptionValuePropertiesSP(new OptionValueProperties())), 652e6481c7eSJason Molenda m_input_file_sp(new StreamFile(stdin, false)), 653e6481c7eSJason Molenda m_output_file_sp(new StreamFile(stdout, false)), 654e6481c7eSJason Molenda m_error_file_sp(new StreamFile(stderr, false)), 655e6481c7eSJason Molenda m_terminal_state(), 656e6481c7eSJason Molenda m_target_list(*this), 657e6481c7eSJason Molenda m_platform_list(), 658e6481c7eSJason Molenda m_listener("lldb.Debugger"), 659e6481c7eSJason Molenda m_source_manager_ap(), 660e6481c7eSJason Molenda m_source_file_cache(), 661e6481c7eSJason Molenda m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)), 662e6481c7eSJason Molenda m_input_reader_stack(), 663e6481c7eSJason Molenda m_instance_name(), 664e6481c7eSJason Molenda m_loaded_plugins() 66530fdc8d8SChris Lattner { 66667cc0636SGreg Clayton char instance_cstr[256]; 66767cc0636SGreg Clayton snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); 66867cc0636SGreg Clayton m_instance_name.SetCString(instance_cstr); 669228063cdSJim Ingham if (log_callback) 670228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 6716611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 672ded470d3SGreg Clayton // Always add our default platform to the platform list 673615eb7e6SGreg Clayton PlatformSP default_platform_sp (Platform::GetHostPlatform()); 674ded470d3SGreg Clayton assert (default_platform_sp.get()); 675ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 67667cc0636SGreg Clayton 677754a9369SGreg Clayton m_collection_sp->Initialize (g_properties); 67867cc0636SGreg Clayton m_collection_sp->AppendProperty (ConstString("target"), 67967cc0636SGreg Clayton ConstString("Settings specify to debugging targets."), 68067cc0636SGreg Clayton true, 68167cc0636SGreg Clayton Target::GetGlobalProperties()->GetValueProperties()); 682754a9369SGreg Clayton if (m_command_interpreter_ap.get()) 683754a9369SGreg Clayton { 684754a9369SGreg Clayton m_collection_sp->AppendProperty (ConstString("interpreter"), 685754a9369SGreg Clayton ConstString("Settings specify to the debugger's command interpreter."), 686754a9369SGreg Clayton true, 687754a9369SGreg Clayton m_command_interpreter_ap->GetValueProperties()); 688754a9369SGreg Clayton } 68967cc0636SGreg Clayton OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth); 69067cc0636SGreg Clayton term_width->SetMinimumValue(10); 69167cc0636SGreg Clayton term_width->SetMaximumValue(1024); 692c3ce7f27SMichael Sartain 693c3ce7f27SMichael Sartain // Turn off use-color if this is a dumb terminal. 694c3ce7f27SMichael Sartain const char *term = getenv ("TERM"); 695c3ce7f27SMichael Sartain if (term && !strcmp (term, "dumb")) 696c3ce7f27SMichael Sartain SetUseColor (false); 69730fdc8d8SChris Lattner } 69830fdc8d8SChris Lattner 69930fdc8d8SChris Lattner Debugger::~Debugger () 70030fdc8d8SChris Lattner { 7018314c525SJim Ingham Clear(); 7028314c525SJim Ingham } 7038314c525SJim Ingham 7048314c525SJim Ingham void 7058314c525SJim Ingham Debugger::Clear() 7068314c525SJim Ingham { 70744d93782SGreg Clayton ClearIOHandlers(); 70844d93782SGreg Clayton StopIOHandlerThread(); 70944d93782SGreg Clayton StopEventHandlerThread(); 7101ed54f50SGreg Clayton m_listener.Clear(); 7116611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 7126611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 7136611103cSGreg Clayton { 714ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 715ccbc08e6SGreg Clayton if (target_sp) 716ccbc08e6SGreg Clayton { 717ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 7186611103cSGreg Clayton if (process_sp) 7191fd07059SJim Ingham process_sp->Finalize(); 720ccbc08e6SGreg Clayton target_sp->Destroy(); 7216611103cSGreg Clayton } 72230fdc8d8SChris Lattner } 7234bddaeb5SJim Ingham BroadcasterManager::Clear (); 72430fdc8d8SChris Lattner 7250d69a3a4SGreg Clayton // Close the input file _before_ we close the input read communications class 7260d69a3a4SGreg Clayton // as it does NOT own the input file, our m_input_file does. 727c5917d9aSJim Ingham m_terminal_state.Clear(); 72844d93782SGreg Clayton if (m_input_file_sp) 72944d93782SGreg Clayton m_input_file_sp->GetFile().Close (); 7300c4129f2SGreg Clayton 7310c4129f2SGreg Clayton m_command_interpreter_ap->Clear(); 7328314c525SJim Ingham } 73330fdc8d8SChris Lattner 73430fdc8d8SChris Lattner bool 735fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 736fc3f027dSGreg Clayton { 73744d93782SGreg Clayton // return m_input_comm.GetCloseOnEOF(); 73844d93782SGreg Clayton return false; 739fc3f027dSGreg Clayton } 740fc3f027dSGreg Clayton 741fc3f027dSGreg Clayton void 742fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 743fc3f027dSGreg Clayton { 74444d93782SGreg Clayton // m_input_comm.SetCloseOnEOF(b); 745fc3f027dSGreg Clayton } 746fc3f027dSGreg Clayton 747fc3f027dSGreg Clayton bool 74830fdc8d8SChris Lattner Debugger::GetAsyncExecution () 74930fdc8d8SChris Lattner { 7506611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 75130fdc8d8SChris Lattner } 75230fdc8d8SChris Lattner 75330fdc8d8SChris Lattner void 75430fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 75530fdc8d8SChris Lattner { 7566611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 75730fdc8d8SChris Lattner } 75830fdc8d8SChris Lattner 75930fdc8d8SChris Lattner 76030fdc8d8SChris Lattner void 76130fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 76230fdc8d8SChris Lattner { 76344d93782SGreg Clayton if (m_input_file_sp) 76444d93782SGreg Clayton m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership); 76544d93782SGreg Clayton else 76644d93782SGreg Clayton m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 76744d93782SGreg Clayton 76844d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 76951b1e2d2SGreg Clayton if (in_file.IsValid() == false) 77051b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 77130fdc8d8SChris Lattner 772c5917d9aSJim Ingham // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState. 773c5917d9aSJim Ingham SaveInputTerminalState (); 77430fdc8d8SChris Lattner } 77530fdc8d8SChris Lattner 77630fdc8d8SChris Lattner void 77730fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 77830fdc8d8SChris Lattner { 77944d93782SGreg Clayton if (m_output_file_sp) 78044d93782SGreg Clayton m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership); 78144d93782SGreg Clayton else 78244d93782SGreg Clayton m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 78344d93782SGreg Clayton 78444d93782SGreg Clayton File &out_file = m_output_file_sp->GetFile(); 78551b1e2d2SGreg Clayton if (out_file.IsValid() == false) 78651b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 7872f88aadfSCaroline Tice 788b588726eSEnrico Granata // do not create the ScriptInterpreter just for setting the output file handle 789b588726eSEnrico Granata // as the constructor will know how to do the right thing on its own 790b588726eSEnrico Granata const bool can_create = false; 791b588726eSEnrico Granata ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create); 792b588726eSEnrico Granata if (script_interpreter) 793b588726eSEnrico Granata script_interpreter->ResetOutputFileHandle (fh); 79430fdc8d8SChris Lattner } 79530fdc8d8SChris Lattner 79630fdc8d8SChris Lattner void 79730fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 79830fdc8d8SChris Lattner { 79944d93782SGreg Clayton if (m_error_file_sp) 80044d93782SGreg Clayton m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership); 80144d93782SGreg Clayton else 80244d93782SGreg Clayton m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership)); 80344d93782SGreg Clayton 80444d93782SGreg Clayton File &err_file = m_error_file_sp->GetFile(); 80551b1e2d2SGreg Clayton if (err_file.IsValid() == false) 80651b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 80730fdc8d8SChris Lattner } 80830fdc8d8SChris Lattner 809c5917d9aSJim Ingham void 810c5917d9aSJim Ingham Debugger::SaveInputTerminalState () 811c5917d9aSJim Ingham { 81244d93782SGreg Clayton if (m_input_file_sp) 81344d93782SGreg Clayton { 81444d93782SGreg Clayton File &in_file = m_input_file_sp->GetFile(); 815c5917d9aSJim Ingham if (in_file.GetDescriptor() != File::kInvalidDescriptor) 816c5917d9aSJim Ingham m_terminal_state.Save(in_file.GetDescriptor(), true); 817c5917d9aSJim Ingham } 81844d93782SGreg Clayton } 819c5917d9aSJim Ingham 820c5917d9aSJim Ingham void 821c5917d9aSJim Ingham Debugger::RestoreInputTerminalState () 822c5917d9aSJim Ingham { 823c5917d9aSJim Ingham m_terminal_state.Restore(); 824c5917d9aSJim Ingham } 825c5917d9aSJim Ingham 82630fdc8d8SChris Lattner ExecutionContext 8272976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 82830fdc8d8SChris Lattner { 82930fdc8d8SChris Lattner ExecutionContext exe_ctx; 830c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 831c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 83230fdc8d8SChris Lattner 83330fdc8d8SChris Lattner if (target_sp) 83430fdc8d8SChris Lattner { 835c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 836c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 837c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 83830fdc8d8SChris Lattner { 839c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 840c14ee32dSGreg Clayton if (thread_sp) 84130fdc8d8SChris Lattner { 842c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 843c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 844c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 845c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 84630fdc8d8SChris Lattner } 84730fdc8d8SChris Lattner } 84830fdc8d8SChris Lattner } 84930fdc8d8SChris Lattner return exe_ctx; 85030fdc8d8SChris Lattner } 85130fdc8d8SChris Lattner 85230fdc8d8SChris Lattner void 853efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 854efed6131SCaroline Tice { 85544d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 85644d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 857efed6131SCaroline Tice if (reader_sp) 85844d93782SGreg Clayton reader_sp->Interrupt(); 859efed6131SCaroline Tice } 860efed6131SCaroline Tice 861efed6131SCaroline Tice void 862efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 863efed6131SCaroline Tice { 86444d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 86544d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 866efed6131SCaroline Tice if (reader_sp) 86744d93782SGreg Clayton reader_sp->GotEOF(); 868efed6131SCaroline Tice } 869efed6131SCaroline Tice 870efed6131SCaroline Tice void 87144d93782SGreg Clayton Debugger::ClearIOHandlers () 8723d6086f6SCaroline Tice { 873b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 87444d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 875d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 8763d6086f6SCaroline Tice { 87744d93782SGreg Clayton IOHandlerSP reader_sp (m_input_reader_stack.Top()); 8783d6086f6SCaroline Tice if (reader_sp) 8793d6086f6SCaroline Tice { 88044d93782SGreg Clayton m_input_reader_stack.Pop(); 8813d6086f6SCaroline Tice reader_sp->SetIsDone(true); 882e68f5d6bSGreg Clayton reader_sp->Cancel(); 8833d6086f6SCaroline Tice } 8843d6086f6SCaroline Tice } 8853d6086f6SCaroline Tice } 8863d6086f6SCaroline Tice 8873d6086f6SCaroline Tice void 88844d93782SGreg Clayton Debugger::ExecuteIOHanders() 889969ed3d1SCaroline Tice { 89044d93782SGreg Clayton 89144d93782SGreg Clayton while (1) 892969ed3d1SCaroline Tice { 89344d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 89430fdc8d8SChris Lattner if (!reader_sp) 89530fdc8d8SChris Lattner break; 89630fdc8d8SChris Lattner 89744d93782SGreg Clayton reader_sp->Activate(); 89844d93782SGreg Clayton reader_sp->Run(); 89944d93782SGreg Clayton reader_sp->Deactivate(); 90044d93782SGreg Clayton 90144d93782SGreg Clayton // Remove all input readers that are done from the top of the stack 90244d93782SGreg Clayton while (1) 90330fdc8d8SChris Lattner { 90444d93782SGreg Clayton IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); 90544d93782SGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 90644d93782SGreg Clayton m_input_reader_stack.Pop(); 90730fdc8d8SChris Lattner else 90830fdc8d8SChris Lattner break; 90930fdc8d8SChris Lattner } 91030fdc8d8SChris Lattner } 91144d93782SGreg Clayton ClearIOHandlers(); 91244d93782SGreg Clayton } 91330fdc8d8SChris Lattner 91444d93782SGreg Clayton bool 91544d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp) 91644d93782SGreg Clayton { 91744d93782SGreg Clayton return m_input_reader_stack.IsTop (reader_sp); 91844d93782SGreg Clayton } 91930fdc8d8SChris Lattner 92044d93782SGreg Clayton 92144d93782SGreg Clayton ConstString 92244d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch) 92344d93782SGreg Clayton { 92444d93782SGreg Clayton return m_input_reader_stack.GetTopIOHandlerControlSequence (ch); 92530fdc8d8SChris Lattner } 92630fdc8d8SChris Lattner 92730fdc8d8SChris Lattner void 92844d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp) 92944d93782SGreg Clayton { 93044d93782SGreg Clayton PushIOHandler (reader_sp); 931577508dfSGreg Clayton 932577508dfSGreg Clayton IOHandlerSP top_reader_sp = reader_sp; 933577508dfSGreg Clayton while (top_reader_sp) 934577508dfSGreg Clayton { 935577508dfSGreg Clayton top_reader_sp->Activate(); 936577508dfSGreg Clayton top_reader_sp->Run(); 937577508dfSGreg Clayton top_reader_sp->Deactivate(); 938577508dfSGreg Clayton 939577508dfSGreg Clayton if (top_reader_sp.get() == reader_sp.get()) 940577508dfSGreg Clayton { 941577508dfSGreg Clayton if (PopIOHandler (reader_sp)) 942577508dfSGreg Clayton break; 943577508dfSGreg Clayton } 944577508dfSGreg Clayton 945577508dfSGreg Clayton while (1) 946577508dfSGreg Clayton { 947577508dfSGreg Clayton top_reader_sp = m_input_reader_stack.Top(); 948577508dfSGreg Clayton if (top_reader_sp && top_reader_sp->GetIsDone()) 949577508dfSGreg Clayton m_input_reader_stack.Pop(); 950577508dfSGreg Clayton else 951577508dfSGreg Clayton break; 952577508dfSGreg Clayton } 953577508dfSGreg Clayton } 95444d93782SGreg Clayton } 95544d93782SGreg Clayton 95644d93782SGreg Clayton void 95744d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err) 95844d93782SGreg Clayton { 95944d93782SGreg Clayton // Before an IOHandler runs, it must have in/out/err streams. 96044d93782SGreg Clayton // This function is called when one ore more of the streams 96144d93782SGreg Clayton // are NULL. We use the top input reader's in/out/err streams, 96244d93782SGreg Clayton // or fall back to the debugger file handles, or we fall back 96344d93782SGreg Clayton // onto stdin/stdout/stderr as a last resort. 96444d93782SGreg Clayton 96544d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 96644d93782SGreg Clayton IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 96744d93782SGreg Clayton // If no STDIN has been set, then set it appropriately 96844d93782SGreg Clayton if (!in) 96944d93782SGreg Clayton { 97044d93782SGreg Clayton if (top_reader_sp) 97144d93782SGreg Clayton in = top_reader_sp->GetInputStreamFile(); 97244d93782SGreg Clayton else 97344d93782SGreg Clayton in = GetInputFile(); 97444d93782SGreg Clayton 97544d93782SGreg Clayton // If there is nothing, use stdin 97644d93782SGreg Clayton if (!in) 97744d93782SGreg Clayton in = StreamFileSP(new StreamFile(stdin, false)); 97844d93782SGreg Clayton } 97944d93782SGreg Clayton // If no STDOUT has been set, then set it appropriately 98044d93782SGreg Clayton if (!out) 98144d93782SGreg Clayton { 98244d93782SGreg Clayton if (top_reader_sp) 98344d93782SGreg Clayton out = top_reader_sp->GetOutputStreamFile(); 98444d93782SGreg Clayton else 98544d93782SGreg Clayton out = GetOutputFile(); 98644d93782SGreg Clayton 98744d93782SGreg Clayton // If there is nothing, use stdout 98844d93782SGreg Clayton if (!out) 98944d93782SGreg Clayton out = StreamFileSP(new StreamFile(stdout, false)); 99044d93782SGreg Clayton } 99144d93782SGreg Clayton // If no STDERR has been set, then set it appropriately 99244d93782SGreg Clayton if (!err) 99344d93782SGreg Clayton { 99444d93782SGreg Clayton if (top_reader_sp) 99544d93782SGreg Clayton err = top_reader_sp->GetErrorStreamFile(); 99644d93782SGreg Clayton else 99744d93782SGreg Clayton err = GetErrorFile(); 99844d93782SGreg Clayton 99944d93782SGreg Clayton // If there is nothing, use stderr 100044d93782SGreg Clayton if (!err) 100144d93782SGreg Clayton err = StreamFileSP(new StreamFile(stdout, false)); 100244d93782SGreg Clayton 100344d93782SGreg Clayton } 100444d93782SGreg Clayton } 100544d93782SGreg Clayton 100644d93782SGreg Clayton void 100744d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp) 100830fdc8d8SChris Lattner { 100930fdc8d8SChris Lattner if (!reader_sp) 101030fdc8d8SChris Lattner return; 1011b44880caSCaroline Tice 101244d93782SGreg Clayton // Got the current top input reader... 101344d93782SGreg Clayton IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); 1014b44880caSCaroline Tice 1015b4874f1aSGreg Clayton // Don't push the same IO handler twice... 1016b4874f1aSGreg Clayton if (reader_sp.get() != top_reader_sp.get()) 1017b4874f1aSGreg Clayton { 101844d93782SGreg Clayton // Push our new input reader 1019d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 102044d93782SGreg Clayton 102144d93782SGreg Clayton // Interrupt the top input reader to it will exit its Run() function 102244d93782SGreg Clayton // and let this new input reader take over 102344d93782SGreg Clayton if (top_reader_sp) 102444d93782SGreg Clayton top_reader_sp->Deactivate(); 102530fdc8d8SChris Lattner } 1026b4874f1aSGreg Clayton } 102730fdc8d8SChris Lattner 102830fdc8d8SChris Lattner bool 102944d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp) 103030fdc8d8SChris Lattner { 103130fdc8d8SChris Lattner bool result = false; 103230fdc8d8SChris Lattner 103344d93782SGreg Clayton Mutex::Locker locker (m_input_reader_stack.GetMutex()); 103444d93782SGreg Clayton 103530fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 10366a7f3338SBruce Mitchener // read on the stack refresh its prompt and if there is one... 1037d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 103830fdc8d8SChris Lattner { 103944d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 104030fdc8d8SChris Lattner 104130fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 104230fdc8d8SChris Lattner { 104344d93782SGreg Clayton reader_sp->Deactivate(); 1044b4874f1aSGreg Clayton reader_sp->Cancel(); 1045d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 104630fdc8d8SChris Lattner 1047d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 104830fdc8d8SChris Lattner if (reader_sp) 104944d93782SGreg Clayton reader_sp->Activate(); 105044d93782SGreg Clayton 105144d93782SGreg Clayton result = true; 105230fdc8d8SChris Lattner } 105330fdc8d8SChris Lattner } 105430fdc8d8SChris Lattner return result; 105530fdc8d8SChris Lattner } 105630fdc8d8SChris Lattner 105730fdc8d8SChris Lattner bool 105844d93782SGreg Clayton Debugger::HideTopIOHandler() 105930fdc8d8SChris Lattner { 106044d93782SGreg Clayton Mutex::Locker locker; 106130fdc8d8SChris Lattner 106244d93782SGreg Clayton if (locker.TryLock(m_input_reader_stack.GetMutex())) 106330fdc8d8SChris Lattner { 106444d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 106544d93782SGreg Clayton if (reader_sp) 106644d93782SGreg Clayton reader_sp->Hide(); 106744d93782SGreg Clayton return true; 106830fdc8d8SChris Lattner } 106944d93782SGreg Clayton return false; 107030fdc8d8SChris Lattner } 107130fdc8d8SChris Lattner 107230fdc8d8SChris Lattner void 107344d93782SGreg Clayton Debugger::RefreshTopIOHandler() 107430fdc8d8SChris Lattner { 107544d93782SGreg Clayton IOHandlerSP reader_sp(m_input_reader_stack.Top()); 107644d93782SGreg Clayton if (reader_sp) 107744d93782SGreg Clayton reader_sp->Refresh(); 107830fdc8d8SChris Lattner } 107944d93782SGreg Clayton 10806611103cSGreg Clayton 10815b52f0c7SJim Ingham StreamSP 10825b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 10835b52f0c7SJim Ingham { 10845b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10855b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 10865b52f0c7SJim Ingham } 10875b52f0c7SJim Ingham 10885b52f0c7SJim Ingham StreamSP 10895b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 10905b52f0c7SJim Ingham { 10915b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 10925b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 10935b52f0c7SJim Ingham } 10945b52f0c7SJim Ingham 1095c7bece56SGreg Clayton size_t 1096061858ceSEnrico Granata Debugger::GetNumDebuggers() 1097061858ceSEnrico Granata { 1098c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1099c15f55e2SGreg Clayton { 1100061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1101061858ceSEnrico Granata return GetDebuggerList().size(); 1102061858ceSEnrico Granata } 1103c15f55e2SGreg Clayton return 0; 1104c15f55e2SGreg Clayton } 1105061858ceSEnrico Granata 1106061858ceSEnrico Granata lldb::DebuggerSP 1107c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index) 1108061858ceSEnrico Granata { 1109061858ceSEnrico Granata DebuggerSP debugger_sp; 1110061858ceSEnrico Granata 1111c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1112c15f55e2SGreg Clayton { 1113061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 1114061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 1115061858ceSEnrico Granata 1116061858ceSEnrico Granata if (index < debugger_list.size()) 1117061858ceSEnrico Granata debugger_sp = debugger_list[index]; 1118c15f55e2SGreg Clayton } 1119061858ceSEnrico Granata 1120061858ceSEnrico Granata return debugger_sp; 1121061858ceSEnrico Granata } 1122061858ceSEnrico Granata 1123ebc1bb27SCaroline Tice DebuggerSP 1124ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 1125ebc1bb27SCaroline Tice { 11264d122c40SGreg Clayton DebuggerSP debugger_sp; 1127ebc1bb27SCaroline Tice 1128c15f55e2SGreg Clayton if (g_shared_debugger_refcount > 0) 1129c15f55e2SGreg Clayton { 1130ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 1131ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 1132ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 1133ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 1134ebc1bb27SCaroline Tice { 1135ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 1136ebc1bb27SCaroline Tice { 1137ebc1bb27SCaroline Tice debugger_sp = *pos; 1138ebc1bb27SCaroline Tice break; 1139ebc1bb27SCaroline Tice } 1140ebc1bb27SCaroline Tice } 1141c15f55e2SGreg Clayton } 1142ebc1bb27SCaroline Tice return debugger_sp; 1143ebc1bb27SCaroline Tice } 11443df9a8dfSCaroline Tice 11452643b905SSaleem Abdulrasool #if 0 11461b654882SGreg Clayton static void 1147b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame) 11481b654882SGreg Clayton { 11491b654882SGreg Clayton if (frame == NULL) 11501b654882SGreg Clayton return; 11511b654882SGreg Clayton 11521b654882SGreg Clayton StreamString s; 11531b654882SGreg Clayton const char *prompt_format = 11541b654882SGreg Clayton "{addr = '${addr}'\n}" 1155aff1b357SJason Molenda "{addr-file-or-load = '${addr-file-or-load}'\n}" 1156aff1b357SJason Molenda "{current-pc-arrow = '${current-pc-arrow}'\n}" 11571b654882SGreg Clayton "{process.id = '${process.id}'\n}" 11581b654882SGreg Clayton "{process.name = '${process.name}'\n}" 11591b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 11601b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 11611b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 11621b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 11631b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 11641b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 11651b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 11661b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 11671b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 11681b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 11691b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 11701b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 11711b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 11721b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 11731b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 11741b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 11751b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 11761b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 11771b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 11781b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 11791b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 11801b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 11811b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 11821b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 11831b654882SGreg Clayton "{function.id = '${function.id}'\n}" 1184aff1b357SJason Molenda "{function.changed = '${function.changed}'\n}" 1185aff1b357SJason Molenda "{function.initial-function = '${function.initial-function}'\n}" 11861b654882SGreg Clayton "{function.name = '${function.name}'\n}" 1187aff1b357SJason Molenda "{function.name-without-args = '${function.name-without-args}'\n}" 1188ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 11891b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 1190aff1b357SJason Molenda "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}" 11911b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 11921b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 11931b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 11941b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 11951b654882SGreg Clayton "{line.number = '${line.number}'\n}" 11961b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 11971b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 11981b654882SGreg Clayton ; 11991b654882SGreg Clayton 12001b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 12011b654882SGreg Clayton ExecutionContext exe_ctx; 12020603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 1203c3ce7f27SMichael Sartain if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s)) 12041b654882SGreg Clayton { 12051b654882SGreg Clayton printf("%s\n", s.GetData()); 12061b654882SGreg Clayton } 12071b654882SGreg Clayton else 12081b654882SGreg Clayton { 12091b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 12101b654882SGreg Clayton } 12111b654882SGreg Clayton } 12122643b905SSaleem Abdulrasool #endif 12131b654882SGreg Clayton 12149fc1944eSEnrico Granata static bool 12159fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin, 12169fc1944eSEnrico Granata const char* var_name_end, 12179fc1944eSEnrico Granata const char** var_name_final, 12189fc1944eSEnrico Granata const char** percent_position, 12194d122c40SGreg Clayton Format* custom_format, 12209fc1944eSEnrico Granata ValueObject::ValueObjectRepresentationStyle* val_obj_display) 12219fc1944eSEnrico Granata { 12225160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 12239fc1944eSEnrico Granata *percent_position = ::strchr(var_name_begin,'%'); 12249fc1944eSEnrico Granata if (!*percent_position || *percent_position > var_name_end) 1225e992a089SEnrico Granata { 1226e992a089SEnrico Granata if (log) 1227d228483dSEnrico Granata log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping"); 12289fc1944eSEnrico Granata *var_name_final = var_name_end; 1229e992a089SEnrico Granata } 12309fc1944eSEnrico Granata else 12319fc1944eSEnrico Granata { 12329fc1944eSEnrico Granata *var_name_final = *percent_position; 123336aa5ae6SEnrico Granata std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1); 1234e992a089SEnrico Granata if (log) 123568ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str()); 123636aa5ae6SEnrico Granata if ( !FormatManager::GetFormatFromCString(format_name.c_str(), 12379fc1944eSEnrico Granata true, 12389fc1944eSEnrico Granata *custom_format) ) 12399fc1944eSEnrico Granata { 1240e992a089SEnrico Granata if (log) 124168ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str()); 124236aa5ae6SEnrico Granata 124336aa5ae6SEnrico Granata switch (format_name.front()) 124436aa5ae6SEnrico Granata { 124536aa5ae6SEnrico Granata case '@': // if this is an @ sign, print ObjC description 124686cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 124736aa5ae6SEnrico Granata break; 124836aa5ae6SEnrico Granata case 'V': // if this is a V, print the value using the default format 124986cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 125036aa5ae6SEnrico Granata break; 125136aa5ae6SEnrico Granata case 'L': // if this is an L, print the location of the value 125286cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 125336aa5ae6SEnrico Granata break; 125436aa5ae6SEnrico Granata case 'S': // if this is an S, print the summary after all 125586cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 125636aa5ae6SEnrico Granata break; 125736aa5ae6SEnrico Granata case '#': // if this is a '#', print the number of children 125886cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 125936aa5ae6SEnrico Granata break; 126036aa5ae6SEnrico Granata case 'T': // if this is a 'T', print the type 126186cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 126236aa5ae6SEnrico Granata break; 12632c75f11eSEnrico Granata case 'N': // if this is a 'N', print the name 12642c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleName; 12652c75f11eSEnrico Granata break; 12662c75f11eSEnrico Granata case '>': // if this is a '>', print the name 12672c75f11eSEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath; 12682c75f11eSEnrico Granata break; 126936aa5ae6SEnrico Granata default: 12705c42d8a8SJim Ingham if (log) 127136aa5ae6SEnrico Granata log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str()); 127236aa5ae6SEnrico Granata break; 127336aa5ae6SEnrico Granata } 12749fc1944eSEnrico Granata } 12759fc1944eSEnrico Granata // a good custom format tells us to print the value using it 12769fc1944eSEnrico Granata else 1277e992a089SEnrico Granata { 1278e992a089SEnrico Granata if (log) 127968ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] will display value for this VO"); 128086cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1281e992a089SEnrico Granata } 12829fc1944eSEnrico Granata } 1283e992a089SEnrico Granata if (log) 128468ae4117SEnrico Granata log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d", 1285e992a089SEnrico Granata *custom_format, 1286e992a089SEnrico Granata *val_obj_display); 12879fc1944eSEnrico Granata return true; 12889fc1944eSEnrico Granata } 12899fc1944eSEnrico Granata 12909fc1944eSEnrico Granata static bool 12919fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 12929fc1944eSEnrico Granata const char* var_name_end, 12939fc1944eSEnrico Granata const char* var_name_final, 12949fc1944eSEnrico Granata const char** open_bracket_position, 12959fc1944eSEnrico Granata const char** separator_position, 12969fc1944eSEnrico Granata const char** close_bracket_position, 12979fc1944eSEnrico Granata const char** var_name_final_if_array_range, 12989fc1944eSEnrico Granata int64_t* index_lower, 12999fc1944eSEnrico Granata int64_t* index_higher) 13009fc1944eSEnrico Granata { 13015160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 13029fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 13039fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 13049fc1944eSEnrico Granata { 13059fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 13069fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 13079fc1944eSEnrico Granata // as usual, we assume that [] will come before % 13089fc1944eSEnrico Granata //printf("trying to expand a []\n"); 13099fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 13109fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 13119fc1944eSEnrico Granata { 1312e992a089SEnrico Granata if (log) 1313d228483dSEnrico Granata log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data"); 13149fc1944eSEnrico Granata *index_lower = 0; 13159fc1944eSEnrico Granata } 13169fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 13179fc1944eSEnrico Granata { 13189fc1944eSEnrico Granata char *end = NULL; 13199fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 13209fc1944eSEnrico Granata *index_higher = *index_lower; 1321e992a089SEnrico Granata if (log) 1322d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower); 13239fc1944eSEnrico Granata } 13249fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 13259fc1944eSEnrico Granata { 13269fc1944eSEnrico Granata char *end = NULL; 13279fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 13289fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 1329e992a089SEnrico Granata if (log) 1330d01b2953SDaniel Malea log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher); 13319fc1944eSEnrico Granata } 13329fc1944eSEnrico Granata else 1333e992a089SEnrico Granata { 1334e992a089SEnrico Granata if (log) 1335d228483dSEnrico Granata log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it"); 13369fc1944eSEnrico Granata return false; 1337e992a089SEnrico Granata } 13389fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 13399fc1944eSEnrico Granata { 1340e992a089SEnrico Granata if (log) 1341d228483dSEnrico Granata log->Printf("[ScanBracketedRange] swapping indices"); 1342c7bece56SGreg Clayton int64_t temp = *index_lower; 13439fc1944eSEnrico Granata *index_lower = *index_higher; 13449fc1944eSEnrico Granata *index_higher = temp; 13459fc1944eSEnrico Granata } 13469fc1944eSEnrico Granata } 1347e992a089SEnrico Granata else if (log) 1348d228483dSEnrico Granata log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely"); 13499fc1944eSEnrico Granata return true; 13509fc1944eSEnrico Granata } 13519fc1944eSEnrico Granata 13520769b2b1SMichael Sartain template <typename T> 13530769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name) 13540769b2b1SMichael Sartain { 13550769b2b1SMichael Sartain if (script_interpreter) 13560769b2b1SMichael Sartain { 13570769b2b1SMichael Sartain Error script_error; 13580769b2b1SMichael Sartain std::string script_output; 13590769b2b1SMichael Sartain 13600769b2b1SMichael Sartain if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success()) 13610769b2b1SMichael Sartain { 13620769b2b1SMichael Sartain s.Printf("%s", script_output.c_str()); 13630769b2b1SMichael Sartain return true; 13640769b2b1SMichael Sartain } 13650769b2b1SMichael Sartain else 13660769b2b1SMichael Sartain { 13670769b2b1SMichael Sartain s.Printf("<error: %s>",script_error.AsCString()); 13680769b2b1SMichael Sartain } 13690769b2b1SMichael Sartain } 13700769b2b1SMichael Sartain return false; 13710769b2b1SMichael Sartain } 13720769b2b1SMichael Sartain 13739fc1944eSEnrico Granata static ValueObjectSP 1374c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 1375c7bece56SGreg Clayton size_t index, 1376b57e4a1bSJason Molenda StackFrame* frame, 1377fc7a7f3bSEnrico Granata bool deref_pointer) 13789fc1944eSEnrico Granata { 13795160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1380fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1381599171adSEnrico Granata std::string ptr_deref_buffer(10,0); 1382599171adSEnrico Granata ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); 1383e992a089SEnrico Granata if (log) 1384599171adSEnrico Granata log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str()); 1385fc7a7f3bSEnrico Granata const char* first_unparsed; 1386fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1387fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1388fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 138986cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1390599171adSEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(), 1391fc7a7f3bSEnrico Granata &first_unparsed, 1392fc7a7f3bSEnrico Granata &reason_to_stop, 1393fc7a7f3bSEnrico Granata &final_value_type, 1394fc7a7f3bSEnrico Granata options, 1395fc7a7f3bSEnrico Granata &what_next); 1396fc7a7f3bSEnrico Granata if (!item) 1397fc7a7f3bSEnrico Granata { 1398e992a089SEnrico Granata if (log) 1399d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d," 1400e992a089SEnrico Granata " final_value_type %d", 1401fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1402fc7a7f3bSEnrico Granata } 14039fc1944eSEnrico Granata else 14049fc1944eSEnrico Granata { 1405e992a089SEnrico Granata if (log) 1406d228483dSEnrico Granata log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1407e992a089SEnrico Granata " final_value_type %d", 1408fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 14099fc1944eSEnrico Granata } 14109fc1944eSEnrico Granata return item; 14119fc1944eSEnrico Granata } 14129fc1944eSEnrico Granata 14130769b2b1SMichael Sartain static inline bool 14140769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var) 14150769b2b1SMichael Sartain { 14160769b2b1SMichael Sartain return (::strncmp (var_name_begin, var, strlen(var)) == 0); 14170769b2b1SMichael Sartain } 14180769b2b1SMichael Sartain 14190769b2b1SMichael Sartain static bool 14200769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format, 14210769b2b1SMichael Sartain const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr) 14220769b2b1SMichael Sartain { 14230769b2b1SMichael Sartain int var_len = strlen(var); 14240769b2b1SMichael Sartain if (::strncmp (var_name_begin, var, var_len) == 0) 14250769b2b1SMichael Sartain { 14260769b2b1SMichael Sartain var_name_begin += var_len; 14270769b2b1SMichael Sartain if (*var_name_begin == '}') 14280769b2b1SMichael Sartain { 14290769b2b1SMichael Sartain format = default_format; 14300769b2b1SMichael Sartain return true; 14310769b2b1SMichael Sartain } 14320769b2b1SMichael Sartain else if (*var_name_begin == '%') 14330769b2b1SMichael Sartain { 14340769b2b1SMichael Sartain // Allow format specifiers: x|X|u with optional width specifiers. 14350769b2b1SMichael Sartain // ${thread.id%x} ; hex 14360769b2b1SMichael Sartain // ${thread.id%X} ; uppercase hex 14370769b2b1SMichael Sartain // ${thread.id%u} ; unsigned decimal 14380769b2b1SMichael Sartain // ${thread.id%8.8X} ; width.precision + specifier 14390769b2b1SMichael Sartain // ${thread.id%tid} ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id) 14400769b2b1SMichael Sartain int dot_count = 0; 14410769b2b1SMichael Sartain const char *specifier = NULL; 14420769b2b1SMichael Sartain int width_precision_length = 0; 14430769b2b1SMichael Sartain const char *width_precision = ++var_name_begin; 14440769b2b1SMichael Sartain while (isdigit(*var_name_begin) || *var_name_begin == '.') 14450769b2b1SMichael Sartain { 14460769b2b1SMichael Sartain dot_count += (*var_name_begin == '.'); 14470769b2b1SMichael Sartain if (dot_count > 1) 14480769b2b1SMichael Sartain break; 14490769b2b1SMichael Sartain var_name_begin++; 14500769b2b1SMichael Sartain width_precision_length++; 14510769b2b1SMichael Sartain } 14520769b2b1SMichael Sartain 14530769b2b1SMichael Sartain if (IsToken (var_name_begin, "tid}")) 14540769b2b1SMichael Sartain { 14550769b2b1SMichael Sartain Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr); 14560769b2b1SMichael Sartain if (target) 14570769b2b1SMichael Sartain { 14580769b2b1SMichael Sartain ArchSpec arch (target->GetArchitecture ()); 14590769b2b1SMichael Sartain llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS; 14600769b2b1SMichael Sartain if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux)) 14610769b2b1SMichael Sartain specifier = PRIu64; 14620769b2b1SMichael Sartain } 14630769b2b1SMichael Sartain if (!specifier) 14640769b2b1SMichael Sartain { 14650769b2b1SMichael Sartain format = default_format; 14660769b2b1SMichael Sartain return true; 14670769b2b1SMichael Sartain } 14680769b2b1SMichael Sartain } 14690769b2b1SMichael Sartain else if (IsToken (var_name_begin, "x}")) 14700769b2b1SMichael Sartain specifier = PRIx64; 14710769b2b1SMichael Sartain else if (IsToken (var_name_begin, "X}")) 14720769b2b1SMichael Sartain specifier = PRIX64; 14730769b2b1SMichael Sartain else if (IsToken (var_name_begin, "u}")) 14740769b2b1SMichael Sartain specifier = PRIu64; 14750769b2b1SMichael Sartain 14760769b2b1SMichael Sartain if (specifier) 14770769b2b1SMichael Sartain { 14780769b2b1SMichael Sartain format = "%"; 14790769b2b1SMichael Sartain if (width_precision_length) 14800769b2b1SMichael Sartain format += std::string(width_precision, width_precision_length); 14810769b2b1SMichael Sartain format += specifier; 14820769b2b1SMichael Sartain return true; 14830769b2b1SMichael Sartain } 14840769b2b1SMichael Sartain } 14850769b2b1SMichael Sartain } 14860769b2b1SMichael Sartain return false; 14870769b2b1SMichael Sartain } 14880769b2b1SMichael Sartain 1489705b1809SJason Molenda // Find information for the "thread.info.*" specifiers in a format string 1490705b1809SJason Molenda static bool 1491705b1809SJason Molenda FormatThreadExtendedInfoRecurse 1492705b1809SJason Molenda ( 1493705b1809SJason Molenda const char *var_name_begin, 1494705b1809SJason Molenda StructuredData::ObjectSP thread_info_dictionary, 1495705b1809SJason Molenda const SymbolContext *sc, 1496705b1809SJason Molenda const ExecutionContext *exe_ctx, 1497705b1809SJason Molenda Stream &s 1498705b1809SJason Molenda ) 1499705b1809SJason Molenda { 1500705b1809SJason Molenda bool var_success = false; 1501705b1809SJason Molenda std::string token_format; 1502705b1809SJason Molenda 1503705b1809SJason Molenda llvm::StringRef var_name(var_name_begin); 1504705b1809SJason Molenda size_t percent_idx = var_name.find('%'); 1505705b1809SJason Molenda size_t close_curly_idx = var_name.find('}'); 1506705b1809SJason Molenda llvm::StringRef path = var_name; 1507705b1809SJason Molenda llvm::StringRef formatter = var_name; 1508705b1809SJason Molenda 1509705b1809SJason Molenda // 'path' will be the dot separated list of objects to transverse up until we hit 1510705b1809SJason Molenda // a close curly brace, a percent sign, or an end of string. 1511705b1809SJason Molenda if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos) 1512705b1809SJason Molenda { 1513705b1809SJason Molenda if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos) 1514705b1809SJason Molenda { 1515705b1809SJason Molenda if (percent_idx < close_curly_idx) 1516705b1809SJason Molenda { 1517705b1809SJason Molenda path = var_name.slice(0, percent_idx); 1518705b1809SJason Molenda formatter = var_name.substr (percent_idx); 1519705b1809SJason Molenda } 1520705b1809SJason Molenda else 1521705b1809SJason Molenda { 1522705b1809SJason Molenda path = var_name.slice(0, close_curly_idx); 1523705b1809SJason Molenda formatter = var_name.substr (close_curly_idx); 1524705b1809SJason Molenda } 1525705b1809SJason Molenda } 1526705b1809SJason Molenda else if (percent_idx != llvm::StringRef::npos) 1527705b1809SJason Molenda { 1528705b1809SJason Molenda path = var_name.slice(0, percent_idx); 1529705b1809SJason Molenda formatter = var_name.substr (percent_idx); 1530705b1809SJason Molenda } 1531705b1809SJason Molenda else if (close_curly_idx != llvm::StringRef::npos) 1532705b1809SJason Molenda { 1533705b1809SJason Molenda path = var_name.slice(0, close_curly_idx); 1534705b1809SJason Molenda formatter = var_name.substr (close_curly_idx); 1535705b1809SJason Molenda } 1536705b1809SJason Molenda } 1537705b1809SJason Molenda 1538705b1809SJason Molenda StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path); 1539705b1809SJason Molenda 1540705b1809SJason Molenda if (value.get()) 1541705b1809SJason Molenda { 1542705b1809SJason Molenda if (value->GetType() == StructuredData::Type::eTypeInteger) 1543705b1809SJason Molenda { 1544705b1809SJason Molenda if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 1545705b1809SJason Molenda { 1546705b1809SJason Molenda s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue()); 1547705b1809SJason Molenda var_success = true; 1548705b1809SJason Molenda } 1549705b1809SJason Molenda } 1550705b1809SJason Molenda else if (value->GetType() == StructuredData::Type::eTypeFloat) 1551705b1809SJason Molenda { 1552705b1809SJason Molenda s.Printf ("%f", value->GetAsFloat()->GetValue()); 1553705b1809SJason Molenda var_success = true; 1554705b1809SJason Molenda } 1555705b1809SJason Molenda else if (value->GetType() == StructuredData::Type::eTypeString) 1556705b1809SJason Molenda { 1557705b1809SJason Molenda s.Printf("%s", value->GetAsString()->GetValue().c_str()); 1558705b1809SJason Molenda var_success = true; 1559705b1809SJason Molenda } 1560705b1809SJason Molenda else if (value->GetType() == StructuredData::Type::eTypeArray) 1561705b1809SJason Molenda { 1562705b1809SJason Molenda if (value->GetAsArray()->GetSize() > 0) 1563705b1809SJason Molenda { 1564705b1809SJason Molenda s.Printf ("%zu", value->GetAsArray()->GetSize()); 1565705b1809SJason Molenda var_success = true; 1566705b1809SJason Molenda } 1567705b1809SJason Molenda } 1568705b1809SJason Molenda else if (value->GetType() == StructuredData::Type::eTypeDictionary) 1569705b1809SJason Molenda { 1570705b1809SJason Molenda s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize()); 1571705b1809SJason Molenda var_success = true; 1572705b1809SJason Molenda } 1573705b1809SJason Molenda } 1574705b1809SJason Molenda 1575705b1809SJason Molenda return var_success; 1576705b1809SJason Molenda } 1577705b1809SJason Molenda 1578705b1809SJason Molenda 1579c3ce7f27SMichael Sartain static bool 1580c3ce7f27SMichael Sartain FormatPromptRecurse 15811b654882SGreg Clayton ( 15821b654882SGreg Clayton const char *format, 15831b654882SGreg Clayton const SymbolContext *sc, 15841b654882SGreg Clayton const ExecutionContext *exe_ctx, 15851b654882SGreg Clayton const Address *addr, 15861b654882SGreg Clayton Stream &s, 15874becb37eSEnrico Granata const char **end, 1588aff1b357SJason Molenda ValueObject* valobj, 1589aff1b357SJason Molenda bool function_changed, 1590aff1b357SJason Molenda bool initial_function 15911b654882SGreg Clayton ) 15921b654882SGreg Clayton { 1593c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 15941b654882SGreg Clayton bool success = true; 15951b654882SGreg Clayton const char *p; 15965160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1597c3ce7f27SMichael Sartain 15981b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 15991b654882SGreg Clayton { 1600c482a192SEnrico Granata if (realvalobj) 16014becb37eSEnrico Granata { 1602c482a192SEnrico Granata valobj = realvalobj; 1603c482a192SEnrico Granata realvalobj = NULL; 16044becb37eSEnrico Granata } 16051b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 16061b654882SGreg Clayton if (non_special_chars > 0) 16071b654882SGreg Clayton { 16081b654882SGreg Clayton if (success) 16091b654882SGreg Clayton s.Write (p, non_special_chars); 16101b654882SGreg Clayton p += non_special_chars; 16111b654882SGreg Clayton } 16121b654882SGreg Clayton 16131b654882SGreg Clayton if (*p == '\0') 16141b654882SGreg Clayton { 16151b654882SGreg Clayton break; 16161b654882SGreg Clayton } 16171b654882SGreg Clayton else if (*p == '{') 16181b654882SGreg Clayton { 16191b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 16201b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 16211b654882SGreg Clayton // a format that only prints out the function or symbol name if there 16221b654882SGreg Clayton // is one in the symbol context you can use: 16231b654882SGreg Clayton // "{function =${function.name}}" 16241b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 16251b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 16261b654882SGreg Clayton // will then be evaluated and only be output if there is a function 16271b654882SGreg Clayton // or symbol with a valid name. 16281b654882SGreg Clayton StreamString sub_strm; 16291b654882SGreg Clayton 16301b654882SGreg Clayton ++p; // Skip the '{' 16311b654882SGreg Clayton 1632aff1b357SJason Molenda if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function)) 16331b654882SGreg Clayton { 16341b654882SGreg Clayton // The stream had all it needed 16351b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 16361b654882SGreg Clayton } 16371b654882SGreg Clayton if (*p != '}') 16381b654882SGreg Clayton { 16391b654882SGreg Clayton success = false; 16401b654882SGreg Clayton break; 16411b654882SGreg Clayton } 16421b654882SGreg Clayton } 16431b654882SGreg Clayton else if (*p == '}') 16441b654882SGreg Clayton { 16451b654882SGreg Clayton // End of a enclosing scope 16461b654882SGreg Clayton break; 16471b654882SGreg Clayton } 16481b654882SGreg Clayton else if (*p == '$') 16491b654882SGreg Clayton { 16501b654882SGreg Clayton // We have a prompt variable to print 16511b654882SGreg Clayton ++p; 16521b654882SGreg Clayton if (*p == '{') 16531b654882SGreg Clayton { 16541b654882SGreg Clayton ++p; 16551b654882SGreg Clayton const char *var_name_begin = p; 16561b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 16571b654882SGreg Clayton 16581b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 16591b654882SGreg Clayton { 16601b654882SGreg Clayton // if we have already failed to parse, skip this variable 16611b654882SGreg Clayton if (success) 16621b654882SGreg Clayton { 16631b654882SGreg Clayton const char *cstr = NULL; 16640769b2b1SMichael Sartain std::string token_format; 16651b654882SGreg Clayton Address format_addr; 1666aff1b357SJason Molenda 1667aff1b357SJason Molenda // normally "addr" means print a raw address but 1668aff1b357SJason Molenda // "file-addr-or-load-addr" means print a module + file addr if there's no load addr 1669aff1b357SJason Molenda bool print_file_addr_or_load_addr = false; 1670aff1b357SJason Molenda bool addr_offset_concrete_func_only = false; 1671aff1b357SJason Molenda bool addr_offset_print_with_no_padding = false; 16721b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 16731b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 16741b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 16751b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 16761b654882SGreg Clayton FileSpec format_file_spec; 1677e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 16781b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 16799fc1944eSEnrico Granata bool do_deref_pointer = false; 168086cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 168186cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 16821b654882SGreg Clayton 16831b654882SGreg Clayton // Each variable must set success to true below... 16841b654882SGreg Clayton bool var_success = false; 16851b654882SGreg Clayton switch (var_name_begin[0]) 16861b654882SGreg Clayton { 16874becb37eSEnrico Granata case '*': 16886f3533fbSEnrico Granata case 'v': 16896f3533fbSEnrico Granata case 's': 16904becb37eSEnrico Granata { 1691c482a192SEnrico Granata if (!valobj) 169234132754SGreg Clayton break; 16936f3533fbSEnrico Granata 1694c3e320a7SEnrico Granata if (log) 1695d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin); 1696c3e320a7SEnrico Granata 16976f3533fbSEnrico Granata // check for *var and *svar 16986f3533fbSEnrico Granata if (*var_name_begin == '*') 16996f3533fbSEnrico Granata { 17009fc1944eSEnrico Granata do_deref_pointer = true; 17019fc1944eSEnrico Granata var_name_begin++; 1702c3e320a7SEnrico Granata if (log) 170368ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin); 170468ae4117SEnrico Granata } 1705c3e320a7SEnrico Granata 17066f3533fbSEnrico Granata if (*var_name_begin == 's') 17074becb37eSEnrico Granata { 1708c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 170986cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 171086cc9829SEnrico Granata if (!valobj) 171186cc9829SEnrico Granata break; 17126f3533fbSEnrico Granata var_name_begin++; 1713c3e320a7SEnrico Granata if (log) 171468ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin); 171568ae4117SEnrico Granata } 1716c3e320a7SEnrico Granata 17176f3533fbSEnrico Granata // should be a 'v' by now 17186f3533fbSEnrico Granata if (*var_name_begin != 'v') 17196f3533fbSEnrico Granata break; 17206f3533fbSEnrico Granata 1721c3e320a7SEnrico Granata if (log) 172268ae4117SEnrico Granata log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin); 1723c3e320a7SEnrico Granata 1724fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 172586cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1726fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 17278c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 172886cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 172934132754SGreg Clayton ValueObject* target = NULL; 17304d122c40SGreg Clayton Format custom_format = eFormatInvalid; 173134132754SGreg Clayton const char* var_name_final = NULL; 17329fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 173334132754SGreg Clayton const char* close_bracket_position = NULL; 173434132754SGreg Clayton int64_t index_lower = -1; 173534132754SGreg Clayton int64_t index_higher = -1; 17369fc1944eSEnrico Granata bool is_array_range = false; 1737fc7a7f3bSEnrico Granata const char* first_unparsed; 173885933ed4SEnrico Granata bool was_plain_var = false; 173985933ed4SEnrico Granata bool was_var_format = false; 1740a777dc2aSEnrico Granata bool was_var_indexed = false; 1741fc7a7f3bSEnrico Granata 1742c482a192SEnrico Granata if (!valobj) break; 1743c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 17440769b2b1SMichael Sartain if (IsToken (var_name_begin, "var}")) 17450a3958e0SEnrico Granata { 174685933ed4SEnrico Granata was_plain_var = true; 1747c482a192SEnrico Granata target = valobj; 174886cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 17490a3958e0SEnrico Granata } 175088282c69SEnrico Granata else if (IsToken (var_name_begin, "var.script:")) 175188282c69SEnrico Granata { 175288282c69SEnrico Granata var_name_begin += ::strlen("var.script:"); 175388282c69SEnrico Granata std::string script_name(var_name_begin,var_name_end); 175488282c69SEnrico Granata ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 175588282c69SEnrico Granata if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name)) 175688282c69SEnrico Granata var_success = true; 175788282c69SEnrico Granata break; 175888282c69SEnrico Granata } 17590769b2b1SMichael Sartain else if (IsToken (var_name_begin,"var%")) 17609fc1944eSEnrico Granata { 176185933ed4SEnrico Granata was_var_format = true; 17629fc1944eSEnrico Granata // this is a variable with some custom format applied to it 17639fc1944eSEnrico Granata const char* percent_position; 1764c482a192SEnrico Granata target = valobj; 176586cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 17669fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 17679fc1944eSEnrico Granata var_name_end, 17689fc1944eSEnrico Granata &var_name_final, 17699fc1944eSEnrico Granata &percent_position, 17709fc1944eSEnrico Granata &custom_format, 17719fc1944eSEnrico Granata &val_obj_display); 17720a3958e0SEnrico Granata } 17739fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 17740769b2b1SMichael Sartain else if (IsToken (var_name_begin, "var")) 17759fc1944eSEnrico Granata { 17760769b2b1SMichael Sartain if (IsToken (var_name_begin, "var[")) 1777a777dc2aSEnrico Granata was_var_indexed = true; 17789fc1944eSEnrico Granata const char* percent_position; 17799fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 17809fc1944eSEnrico Granata var_name_end, 17819fc1944eSEnrico Granata &var_name_final, 17829fc1944eSEnrico Granata &percent_position, 17839fc1944eSEnrico Granata &custom_format, 17849fc1944eSEnrico Granata &val_obj_display); 17859fc1944eSEnrico Granata 17869fc1944eSEnrico Granata const char* open_bracket_position; 17879fc1944eSEnrico Granata const char* separator_position; 17889fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 17899fc1944eSEnrico Granata var_name_end, 17909fc1944eSEnrico Granata var_name_final, 17919fc1944eSEnrico Granata &open_bracket_position, 17929fc1944eSEnrico Granata &separator_position, 17939fc1944eSEnrico Granata &close_bracket_position, 17949fc1944eSEnrico Granata &var_name_final_if_array_range, 17959fc1944eSEnrico Granata &index_lower, 17969fc1944eSEnrico Granata &index_higher); 17979fc1944eSEnrico Granata 17989fc1944eSEnrico Granata Error error; 17999fc1944eSEnrico Granata 1800599171adSEnrico Granata std::string expr_path(var_name_final-var_name_begin-1,0); 1801599171adSEnrico Granata memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3); 1802fc7a7f3bSEnrico Granata 1803e992a089SEnrico Granata if (log) 1804599171adSEnrico Granata log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str()); 1805fc7a7f3bSEnrico Granata 1806599171adSEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.c_str(), 1807fc7a7f3bSEnrico Granata &first_unparsed, 1808fc7a7f3bSEnrico Granata &reason_to_stop, 1809fc7a7f3bSEnrico Granata &final_value_type, 1810fc7a7f3bSEnrico Granata options, 1811fc7a7f3bSEnrico Granata &what_next).get(); 1812fc7a7f3bSEnrico Granata 1813fc7a7f3bSEnrico Granata if (!target) 18149fc1944eSEnrico Granata { 1815e992a089SEnrico Granata if (log) 1816d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d," 1817e992a089SEnrico Granata " final_value_type %d", 1818fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1819fc7a7f3bSEnrico Granata break; 18200a3958e0SEnrico Granata } 1821a7187d00SEnrico Granata else 1822fc7a7f3bSEnrico Granata { 1823e992a089SEnrico Granata if (log) 1824d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d," 1825e992a089SEnrico Granata " final_value_type %d", 1826fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 182750bed5e8SEnrico Granata target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get(); 1828a7187d00SEnrico Granata } 18290a3958e0SEnrico Granata } 18300a3958e0SEnrico Granata else 18310a3958e0SEnrico Granata break; 18329fc1944eSEnrico Granata 183386cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 183486cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1835fc7a7f3bSEnrico Granata 183686cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1837fc7a7f3bSEnrico Granata 1838a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 18390a3958e0SEnrico Granata { 18409fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 18419fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 18429fc1944eSEnrico Granata // to get to the target ValueObject 18439fc1944eSEnrico Granata Error error; 18449fc1944eSEnrico Granata target = target->Dereference(error).get(); 1845dc940730SEnrico Granata if (error.Fail()) 1846dc940730SEnrico Granata { 1847dc940730SEnrico Granata if (log) 1848d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \ 1849dc940730SEnrico Granata break; 1850dc940730SEnrico Granata } 18519fc1944eSEnrico Granata do_deref_pointer = false; 18520a3958e0SEnrico Granata } 18530a3958e0SEnrico Granata 1854f164d940SJim Ingham if (!target) 1855f164d940SJim Ingham { 1856f164d940SJim Ingham if (log) 1857f164d940SJim Ingham log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression"); 1858f164d940SJim Ingham break; 1859f164d940SJim Ingham } 1860f164d940SJim Ingham 1861a777dc2aSEnrico Granata // we do not want to use the summary for a bitfield of type T:n 1862a777dc2aSEnrico Granata // if we were originally dealing with just a T - that would get 1863a777dc2aSEnrico Granata // us into an endless recursion 1864a777dc2aSEnrico Granata if (target->IsBitfield() && was_var_indexed) 1865a777dc2aSEnrico Granata { 1866a777dc2aSEnrico Granata // TODO: check for a (T:n)-specific summary - we should still obey that 1867a777dc2aSEnrico Granata StreamString bitfield_name; 1868a777dc2aSEnrico Granata bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); 1869a777dc2aSEnrico Granata lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false)); 1870a777dc2aSEnrico Granata if (!DataVisualization::GetSummaryForType(type_sp)) 1871a777dc2aSEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 1872a777dc2aSEnrico Granata } 1873a777dc2aSEnrico Granata 187485933ed4SEnrico Granata // TODO use flags for these 187557ee3067SGreg Clayton const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL); 1876622be238SEnrico Granata bool is_array = (type_info_flags & eTypeIsArray) != 0; 1877622be238SEnrico Granata bool is_pointer = (type_info_flags & eTypeIsPointer) != 0; 187857ee3067SGreg Clayton bool is_aggregate = target->GetClangType().IsAggregateType(); 1879f4efecd9SEnrico Granata 188086cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1881f4efecd9SEnrico Granata { 188285933ed4SEnrico Granata StreamString str_temp; 1883e992a089SEnrico Granata if (log) 1884d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range"); 1885d64d0bc0SEnrico Granata 18865088c486SGreg Clayton if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format)) 1887d64d0bc0SEnrico Granata { 1888f4efecd9SEnrico Granata // try to use the special cases 188985933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 189085933ed4SEnrico Granata val_obj_display, 189185933ed4SEnrico Granata custom_format); 1892e992a089SEnrico Granata if (log) 1893d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't"); 1894d64d0bc0SEnrico Granata 1895d64d0bc0SEnrico Granata // should not happen 18965088c486SGreg Clayton if (var_success) 189785933ed4SEnrico Granata s << str_temp.GetData(); 1898d64d0bc0SEnrico Granata var_success = true; 1899d64d0bc0SEnrico Granata break; 1900d64d0bc0SEnrico Granata } 1901d64d0bc0SEnrico Granata else 1902d64d0bc0SEnrico Granata { 190388da35f8SEnrico Granata if (was_plain_var) // if ${var} 1904d64d0bc0SEnrico Granata { 1905d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1906d64d0bc0SEnrico Granata } 190788da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 190888da35f8SEnrico Granata { 190923f59509SGreg Clayton target->DumpPrintableRepresentation (s, 191088da35f8SEnrico Granata val_obj_display, 191186cc9829SEnrico Granata custom_format, 191286cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 191388da35f8SEnrico Granata } 1914d64d0bc0SEnrico Granata var_success = true; 1915d64d0bc0SEnrico Granata break; 1916d64d0bc0SEnrico Granata } 1917d64d0bc0SEnrico Granata } 1918d64d0bc0SEnrico Granata 1919d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1920d64d0bc0SEnrico Granata // type @ location message 1921d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1922d64d0bc0SEnrico Granata { 1923d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1924d64d0bc0SEnrico Granata var_success = true; 192585933ed4SEnrico Granata break; 192685933ed4SEnrico Granata } 192785933ed4SEnrico Granata 1928d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 192986cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 193085933ed4SEnrico Granata { 193185933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 193285933ed4SEnrico Granata var_success = true; 1933f4efecd9SEnrico Granata break; 1934f4efecd9SEnrico Granata } 1935f4efecd9SEnrico Granata 19369fc1944eSEnrico Granata if (!is_array_range) 1937e992a089SEnrico Granata { 1938e992a089SEnrico Granata if (log) 1939d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output"); 19409fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1941e992a089SEnrico Granata } 19429fc1944eSEnrico Granata else 19439fc1944eSEnrico Granata { 1944e992a089SEnrico Granata if (log) 1945d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] checking if I can handle as array"); 19469fc1944eSEnrico Granata if (!is_array && !is_pointer) 19479fc1944eSEnrico Granata break; 1948e992a089SEnrico Granata if (log) 1949d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] handle as array"); 1950fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1951fc7a7f3bSEnrico Granata StreamString special_directions_writer; 19520a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 19530a3958e0SEnrico Granata { 1954fc7a7f3bSEnrico Granata ConstString additional_data; 1955fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1956fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1957fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1958fc7a7f3bSEnrico Granata additional_data.GetCString()); 1959fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 19600a3958e0SEnrico Granata } 19610a3958e0SEnrico Granata 19620a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 19630a3958e0SEnrico Granata s.PutChar('['); 19640a3958e0SEnrico Granata var_success = true; 19650a3958e0SEnrico Granata 19669fc1944eSEnrico Granata if (index_higher < 0) 1967c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 19680a3958e0SEnrico Granata 1969cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 197022c55d18SEnrico Granata 19710a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 19720a3958e0SEnrico Granata { 1973fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 19749fc1944eSEnrico Granata index_lower, 1975c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1976fc7a7f3bSEnrico Granata false).get(); 19770a3958e0SEnrico Granata 1978fc7a7f3bSEnrico Granata if (!item) 1979fc7a7f3bSEnrico Granata { 1980e992a089SEnrico Granata if (log) 1981d01b2953SDaniel Malea log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower); 1982fc7a7f3bSEnrico Granata } 1983fc7a7f3bSEnrico Granata else 1984fc7a7f3bSEnrico Granata { 1985e992a089SEnrico Granata if (log) 1986d228483dSEnrico Granata log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions); 1987fc7a7f3bSEnrico Granata } 1988fc7a7f3bSEnrico Granata 19890a3958e0SEnrico Granata if (!special_directions) 19909fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 19910a3958e0SEnrico Granata else 1992aff1b357SJason Molenda var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function); 19930a3958e0SEnrico Granata 199422c55d18SEnrico Granata if (--max_num_children == 0) 199522c55d18SEnrico Granata { 199622c55d18SEnrico Granata s.PutCString(", ..."); 199722c55d18SEnrico Granata break; 199822c55d18SEnrico Granata } 199922c55d18SEnrico Granata 20000a3958e0SEnrico Granata if (index_lower < index_higher) 20010a3958e0SEnrico Granata s.PutChar(','); 20020a3958e0SEnrico Granata } 20030a3958e0SEnrico Granata s.PutChar(']'); 20044becb37eSEnrico Granata } 20054becb37eSEnrico Granata } 200634132754SGreg Clayton break; 20071b654882SGreg Clayton case 'a': 2008aff1b357SJason Molenda if (IsToken (var_name_begin, "addr-file-or-load}")) 2009aff1b357SJason Molenda { 2010aff1b357SJason Molenda print_file_addr_or_load_addr = true; 2011aff1b357SJason Molenda } 2012aff1b357SJason Molenda if (IsToken (var_name_begin, "addr}") 2013aff1b357SJason Molenda || IsToken (var_name_begin, "addr-file-or-load}")) 20141b654882SGreg Clayton { 20151b654882SGreg Clayton if (addr && addr->IsValid()) 20161b654882SGreg Clayton { 20171b654882SGreg Clayton var_success = true; 20181b654882SGreg Clayton format_addr = *addr; 20191b654882SGreg Clayton } 20201b654882SGreg Clayton } 20211b654882SGreg Clayton break; 20221b654882SGreg Clayton 20231b654882SGreg Clayton case 'p': 20240769b2b1SMichael Sartain if (IsToken (var_name_begin, "process.")) 20251b654882SGreg Clayton { 2026c14ee32dSGreg Clayton if (exe_ctx) 2027c14ee32dSGreg Clayton { 2028c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 2029c14ee32dSGreg Clayton if (process) 20301b654882SGreg Clayton { 20311b654882SGreg Clayton var_name_begin += ::strlen ("process."); 20320769b2b1SMichael Sartain if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc)) 20331b654882SGreg Clayton { 20340769b2b1SMichael Sartain s.Printf(token_format.c_str(), process->GetID()); 20351b654882SGreg Clayton var_success = true; 20361b654882SGreg Clayton } 20370769b2b1SMichael Sartain else if ((IsToken (var_name_begin, "name}")) || 20380769b2b1SMichael Sartain (IsToken (var_name_begin, "file.basename}")) || 20390769b2b1SMichael Sartain (IsToken (var_name_begin, "file.fullpath}"))) 20401b654882SGreg Clayton { 2041c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 2042aa149cbdSGreg Clayton if (exe_module) 20431b654882SGreg Clayton { 20441b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 20451b654882SGreg Clayton { 2046aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 20479076c0ffSSean Callanan var_success = (bool)format_file_spec; 20481b654882SGreg Clayton } 20491b654882SGreg Clayton else 20501b654882SGreg Clayton { 2051aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 20529076c0ffSSean Callanan var_success = (bool)format_file_spec; 20531b654882SGreg Clayton } 20541b654882SGreg Clayton } 20551b654882SGreg Clayton } 20560769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 2057aad8e480SEnrico Granata { 2058aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2059aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2060aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 20610769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, process, script_name)) 2062aad8e480SEnrico Granata var_success = true; 2063aad8e480SEnrico Granata } 20641b654882SGreg Clayton } 20651b654882SGreg Clayton } 2066c14ee32dSGreg Clayton } 20671b654882SGreg Clayton break; 20681b654882SGreg Clayton 20691b654882SGreg Clayton case 't': 20700769b2b1SMichael Sartain if (IsToken (var_name_begin, "thread.")) 20711b654882SGreg Clayton { 2072c14ee32dSGreg Clayton if (exe_ctx) 2073c14ee32dSGreg Clayton { 2074c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 2075c14ee32dSGreg Clayton if (thread) 20761b654882SGreg Clayton { 20771b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 20780769b2b1SMichael Sartain if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 20791b654882SGreg Clayton { 20800769b2b1SMichael Sartain s.Printf(token_format.c_str(), thread->GetID()); 20811b654882SGreg Clayton var_success = true; 20821b654882SGreg Clayton } 20830769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc)) 2084160c9d81SGreg Clayton { 20850769b2b1SMichael Sartain s.Printf(token_format.c_str(), thread->GetProtocolID()); 2086160c9d81SGreg Clayton var_success = true; 2087160c9d81SGreg Clayton } 20880769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc)) 20891b654882SGreg Clayton { 20900769b2b1SMichael Sartain s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID()); 20911b654882SGreg Clayton var_success = true; 20921b654882SGreg Clayton } 20930769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name}")) 20941b654882SGreg Clayton { 2095c14ee32dSGreg Clayton cstr = thread->GetName(); 20961b654882SGreg Clayton var_success = cstr && cstr[0]; 20971b654882SGreg Clayton if (var_success) 20981b654882SGreg Clayton s.PutCString(cstr); 20991b654882SGreg Clayton } 21000769b2b1SMichael Sartain else if (IsToken (var_name_begin, "queue}")) 21011b654882SGreg Clayton { 2102c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 21031b654882SGreg Clayton var_success = cstr && cstr[0]; 21041b654882SGreg Clayton if (var_success) 21051b654882SGreg Clayton s.PutCString(cstr); 21061b654882SGreg Clayton } 21070769b2b1SMichael Sartain else if (IsToken (var_name_begin, "stop-reason}")) 21081b654882SGreg Clayton { 2109c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 21105d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 21111b654882SGreg Clayton { 2112b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 21131b654882SGreg Clayton if (cstr && cstr[0]) 21141b654882SGreg Clayton { 21151b654882SGreg Clayton s.PutCString(cstr); 21161b654882SGreg Clayton var_success = true; 21171b654882SGreg Clayton } 21181b654882SGreg Clayton } 21191b654882SGreg Clayton } 21200769b2b1SMichael Sartain else if (IsToken (var_name_begin, "return-value}")) 212173ca05a2SJim Ingham { 212273ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 21235d88a068SJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 212473ca05a2SJim Ingham { 212573ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 212673ca05a2SJim Ingham if (return_valobj_sp) 212773ca05a2SJim Ingham { 21284d93b8cdSEnrico Granata return_valobj_sp->Dump(s); 212973ca05a2SJim Ingham var_success = true; 213073ca05a2SJim Ingham } 213173ca05a2SJim Ingham } 213273ca05a2SJim Ingham } 213330fadafeSJim Ingham else if (IsToken (var_name_begin, "completed-expression}")) 213430fadafeSJim Ingham { 213530fadafeSJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 213630fadafeSJim Ingham if (stop_info_sp && stop_info_sp->IsValid()) 213730fadafeSJim Ingham { 213830fadafeSJim Ingham ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp); 213930fadafeSJim Ingham if (expression_var_sp && expression_var_sp->GetValueObject()) 214030fadafeSJim Ingham { 214130fadafeSJim Ingham expression_var_sp->GetValueObject()->Dump(s); 214230fadafeSJim Ingham var_success = true; 214330fadafeSJim Ingham } 214430fadafeSJim Ingham } 214530fadafeSJim Ingham } 21460769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 2147aad8e480SEnrico Granata { 2148aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2149aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2150aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 21510769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name)) 2152aad8e480SEnrico Granata var_success = true; 2153aad8e480SEnrico Granata } 2154705b1809SJason Molenda else if (IsToken (var_name_begin, "info.")) 2155705b1809SJason Molenda { 2156705b1809SJason Molenda var_name_begin += ::strlen("info."); 2157705b1809SJason Molenda StructuredData::ObjectSP object_sp = thread->GetExtendedInfo(); 2158705b1809SJason Molenda if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary) 2159705b1809SJason Molenda { 2160705b1809SJason Molenda var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s); 2161705b1809SJason Molenda } 2162705b1809SJason Molenda } 2163aad8e480SEnrico Granata } 2164aad8e480SEnrico Granata } 216573ca05a2SJim Ingham } 21660769b2b1SMichael Sartain else if (IsToken (var_name_begin, "target.")) 21671b654882SGreg Clayton { 216867cc0636SGreg Clayton // TODO: hookup properties 216967cc0636SGreg Clayton // if (!target_properties_sp) 217067cc0636SGreg Clayton // { 217167cc0636SGreg Clayton // Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 217267cc0636SGreg Clayton // if (target) 217367cc0636SGreg Clayton // target_properties_sp = target->GetProperties(); 217467cc0636SGreg Clayton // } 217567cc0636SGreg Clayton // 217667cc0636SGreg Clayton // if (target_properties_sp) 217767cc0636SGreg Clayton // { 217867cc0636SGreg Clayton // var_name_begin += ::strlen ("target."); 217967cc0636SGreg Clayton // const char *end_property = strchr(var_name_begin, '}'); 218067cc0636SGreg Clayton // if (end_property) 218167cc0636SGreg Clayton // { 218267cc0636SGreg Clayton // ConstString property_name(var_name_begin, end_property - var_name_begin); 218367cc0636SGreg Clayton // std::string property_value (target_properties_sp->GetPropertyValue(property_name)); 218467cc0636SGreg Clayton // if (!property_value.empty()) 218567cc0636SGreg Clayton // { 218667cc0636SGreg Clayton // s.PutCString (property_value.c_str()); 218767cc0636SGreg Clayton // var_success = true; 218867cc0636SGreg Clayton // } 218967cc0636SGreg Clayton // } 219067cc0636SGreg Clayton // } 21910603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 21920603aa9dSGreg Clayton if (target) 21931b654882SGreg Clayton { 21941b654882SGreg Clayton var_name_begin += ::strlen ("target."); 21950769b2b1SMichael Sartain if (IsToken (var_name_begin, "arch}")) 21961b654882SGreg Clayton { 21971b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 21981b654882SGreg Clayton if (arch.IsValid()) 21991b654882SGreg Clayton { 220064195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 22011b654882SGreg Clayton var_success = true; 22021b654882SGreg Clayton } 22031b654882SGreg Clayton } 22040769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 2205aad8e480SEnrico Granata { 2206aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2207aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2208aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 22090769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, target, script_name)) 2210aad8e480SEnrico Granata var_success = true; 2211aad8e480SEnrico Granata } 22121b654882SGreg Clayton } 22131b654882SGreg Clayton } 22141b654882SGreg Clayton break; 22151b654882SGreg Clayton 22161b654882SGreg Clayton case 'm': 22170769b2b1SMichael Sartain if (IsToken (var_name_begin, "module.")) 22181b654882SGreg Clayton { 22190603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 22201b654882SGreg Clayton { 22210603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 22221b654882SGreg Clayton var_name_begin += ::strlen ("module."); 22231b654882SGreg Clayton 22240769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 22251b654882SGreg Clayton { 22261b654882SGreg Clayton if (module->GetFileSpec()) 22271b654882SGreg Clayton { 22281b654882SGreg Clayton var_name_begin += ::strlen ("file."); 22291b654882SGreg Clayton 22300769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 22311b654882SGreg Clayton { 22321b654882SGreg Clayton format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 22339076c0ffSSean Callanan var_success = (bool)format_file_spec; 22341b654882SGreg Clayton } 22350769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 22361b654882SGreg Clayton { 22371b654882SGreg Clayton format_file_spec = module->GetFileSpec(); 22389076c0ffSSean Callanan var_success = (bool)format_file_spec; 22391b654882SGreg Clayton } 22401b654882SGreg Clayton } 22411b654882SGreg Clayton } 22421b654882SGreg Clayton } 22431b654882SGreg Clayton } 22441b654882SGreg Clayton break; 22451b654882SGreg Clayton 22461b654882SGreg Clayton 22471b654882SGreg Clayton case 'f': 22480769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 22491b654882SGreg Clayton { 22501b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 22511b654882SGreg Clayton { 22521b654882SGreg Clayton var_name_begin += ::strlen ("file."); 22531b654882SGreg Clayton 22540769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 22551b654882SGreg Clayton { 22561b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 22579076c0ffSSean Callanan var_success = (bool)format_file_spec; 22581b654882SGreg Clayton } 22590769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 22601b654882SGreg Clayton { 22611b654882SGreg Clayton format_file_spec = *sc->comp_unit; 22629076c0ffSSean Callanan var_success = (bool)format_file_spec; 22631b654882SGreg Clayton } 22641b654882SGreg Clayton } 22651b654882SGreg Clayton } 22660769b2b1SMichael Sartain else if (IsToken (var_name_begin, "frame.")) 22671b654882SGreg Clayton { 2268c14ee32dSGreg Clayton if (exe_ctx) 2269c14ee32dSGreg Clayton { 2270b57e4a1bSJason Molenda StackFrame *frame = exe_ctx->GetFramePtr(); 2271c14ee32dSGreg Clayton if (frame) 22721b654882SGreg Clayton { 22731b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 22740769b2b1SMichael Sartain if (IsToken (var_name_begin, "index}")) 22751b654882SGreg Clayton { 2276c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 22771b654882SGreg Clayton var_success = true; 22781b654882SGreg Clayton } 22790769b2b1SMichael Sartain else if (IsToken (var_name_begin, "pc}")) 22801b654882SGreg Clayton { 22811b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 22821b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 22831b654882SGreg Clayton var_success = true; 22841b654882SGreg Clayton } 22850769b2b1SMichael Sartain else if (IsToken (var_name_begin, "sp}")) 22861b654882SGreg Clayton { 22871b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 22881b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 22891b654882SGreg Clayton var_success = true; 22901b654882SGreg Clayton } 22910769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fp}")) 22921b654882SGreg Clayton { 22931b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 22941b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 22951b654882SGreg Clayton var_success = true; 22961b654882SGreg Clayton } 22970769b2b1SMichael Sartain else if (IsToken (var_name_begin, "flags}")) 22981b654882SGreg Clayton { 22991b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 23001b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 23011b654882SGreg Clayton var_success = true; 23021b654882SGreg Clayton } 23030769b2b1SMichael Sartain else if (IsToken (var_name_begin, "reg.")) 23041b654882SGreg Clayton { 2305c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 23061b654882SGreg Clayton if (reg_ctx) 23071b654882SGreg Clayton { 23081b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 23091b654882SGreg Clayton if (var_name_begin < var_name_end) 23101b654882SGreg Clayton { 23111b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 23121b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 23131b654882SGreg Clayton if (reg_info) 23141b654882SGreg Clayton var_success = true; 23151b654882SGreg Clayton } 23161b654882SGreg Clayton } 23171b654882SGreg Clayton } 23180769b2b1SMichael Sartain else if (IsToken (var_name_begin, "script:")) 2319aad8e480SEnrico Granata { 2320aad8e480SEnrico Granata var_name_begin += ::strlen("script:"); 2321aad8e480SEnrico Granata std::string script_name(var_name_begin,var_name_end); 2322aad8e480SEnrico Granata ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 23230769b2b1SMichael Sartain if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name)) 2324aad8e480SEnrico Granata var_success = true; 2325aad8e480SEnrico Granata } 2326aad8e480SEnrico Granata } 2327aad8e480SEnrico Granata } 23281b654882SGreg Clayton } 23290769b2b1SMichael Sartain else if (IsToken (var_name_begin, "function.")) 23301b654882SGreg Clayton { 23311b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 23321b654882SGreg Clayton { 23331b654882SGreg Clayton var_name_begin += ::strlen ("function."); 23340769b2b1SMichael Sartain if (IsToken (var_name_begin, "id}")) 23351b654882SGreg Clayton { 23361b654882SGreg Clayton if (sc->function) 2337d01b2953SDaniel Malea s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID()); 23381b654882SGreg Clayton else 23391b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 23401b654882SGreg Clayton 23411b654882SGreg Clayton var_success = true; 23421b654882SGreg Clayton } 2343aff1b357SJason Molenda if (IsToken (var_name_begin, "changed}") && function_changed) 2344aff1b357SJason Molenda { 2345aff1b357SJason Molenda var_success = true; 2346aff1b357SJason Molenda } 2347aff1b357SJason Molenda if (IsToken (var_name_begin, "initial-function}") && initial_function) 2348aff1b357SJason Molenda { 2349aff1b357SJason Molenda var_success = true; 2350aff1b357SJason Molenda } 23510769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name}")) 23521b654882SGreg Clayton { 23531b654882SGreg Clayton if (sc->function) 23541b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 23551b654882SGreg Clayton else if (sc->symbol) 23561b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 23571b654882SGreg Clayton if (cstr) 23581b654882SGreg Clayton { 23591b654882SGreg Clayton s.PutCString(cstr); 23600d9c9934SGreg Clayton 23610d9c9934SGreg Clayton if (sc->block) 23620d9c9934SGreg Clayton { 23630d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 23640d9c9934SGreg Clayton if (inline_block) 23650d9c9934SGreg Clayton { 23660d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 23670d9c9934SGreg Clayton if (inline_info) 23680d9c9934SGreg Clayton { 23690d9c9934SGreg Clayton s.PutCString(" [inlined] "); 23700d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 23710d9c9934SGreg Clayton } 23720d9c9934SGreg Clayton } 23730d9c9934SGreg Clayton } 23741b654882SGreg Clayton var_success = true; 23751b654882SGreg Clayton } 23761b654882SGreg Clayton } 2377aff1b357SJason Molenda else if (IsToken (var_name_begin, "name-without-args}")) 2378aff1b357SJason Molenda { 2379aff1b357SJason Molenda ConstString name; 2380aff1b357SJason Molenda if (sc->function) 2381aff1b357SJason Molenda name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments); 2382aff1b357SJason Molenda else if (sc->symbol) 2383aff1b357SJason Molenda name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments); 2384aff1b357SJason Molenda if (name) 2385aff1b357SJason Molenda { 2386aff1b357SJason Molenda s.PutCString(name.GetCString()); 2387aff1b357SJason Molenda var_success = true; 2388aff1b357SJason Molenda } 2389aff1b357SJason Molenda } 23900769b2b1SMichael Sartain else if (IsToken (var_name_begin, "name-with-args}")) 23916d3dbf51SGreg Clayton { 23926d3dbf51SGreg Clayton // Print the function name with arguments in it 23936d3dbf51SGreg Clayton 23946d3dbf51SGreg Clayton if (sc->function) 23956d3dbf51SGreg Clayton { 23966d3dbf51SGreg Clayton var_success = true; 23976d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 23986d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 23996d3dbf51SGreg Clayton if (cstr) 24006d3dbf51SGreg Clayton { 24016d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 24026d3dbf51SGreg Clayton VariableListSP variable_list_sp; 24036d3dbf51SGreg Clayton bool get_function_vars = true; 24046d3dbf51SGreg Clayton if (sc->block) 24056d3dbf51SGreg Clayton { 24066d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 24076d3dbf51SGreg Clayton 24086d3dbf51SGreg Clayton if (inline_block) 24096d3dbf51SGreg Clayton { 24106d3dbf51SGreg Clayton get_function_vars = false; 24116d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 24126d3dbf51SGreg Clayton if (inline_info) 24136d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 24146d3dbf51SGreg Clayton } 24156d3dbf51SGreg Clayton } 24166d3dbf51SGreg Clayton 24176d3dbf51SGreg Clayton if (get_function_vars) 24186d3dbf51SGreg Clayton { 24196d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 24206d3dbf51SGreg Clayton } 24216d3dbf51SGreg Clayton 24226d3dbf51SGreg Clayton if (inline_info) 24236d3dbf51SGreg Clayton { 24246d3dbf51SGreg Clayton s.PutCString (cstr); 24256d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 24266d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 24276d3dbf51SGreg Clayton } 24286d3dbf51SGreg Clayton 24296d3dbf51SGreg Clayton VariableList args; 24306d3dbf51SGreg Clayton if (variable_list_sp) 2431cc7f9bf5SEnrico Granata variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); 24326d3dbf51SGreg Clayton if (args.GetSize() > 0) 24336d3dbf51SGreg Clayton { 24346d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 2435e4a4f5d5SEnrico Granata const char *close_paren = nullptr; 2436e4a4f5d5SEnrico Granata const char *generic = strchr(cstr, '<'); 2437e4a4f5d5SEnrico Granata // if before the arguments list begins there is a template sign 2438e4a4f5d5SEnrico Granata // then scan to the end of the generic args before you try to find 2439e4a4f5d5SEnrico Granata // the arguments list 2440e4a4f5d5SEnrico Granata if (generic && open_paren && generic < open_paren) 2441e4a4f5d5SEnrico Granata { 2442e4a4f5d5SEnrico Granata int generic_depth = 1; 2443e4a4f5d5SEnrico Granata ++generic; 2444e4a4f5d5SEnrico Granata for (; 2445e4a4f5d5SEnrico Granata *generic && generic_depth > 0; 2446e4a4f5d5SEnrico Granata generic++) 2447e4a4f5d5SEnrico Granata { 2448e4a4f5d5SEnrico Granata if (*generic == '<') 2449e4a4f5d5SEnrico Granata generic_depth++; 2450e4a4f5d5SEnrico Granata if (*generic == '>') 2451e4a4f5d5SEnrico Granata generic_depth--; 2452e4a4f5d5SEnrico Granata } 2453e4a4f5d5SEnrico Granata if (*generic) 2454e4a4f5d5SEnrico Granata open_paren = strchr(generic, '('); 2455e4a4f5d5SEnrico Granata else 2456e4a4f5d5SEnrico Granata open_paren = nullptr; 2457e4a4f5d5SEnrico Granata } 24586d3dbf51SGreg Clayton if (open_paren) 2459855958caSGreg Clayton { 24600769b2b1SMichael Sartain if (IsToken (open_paren, "(anonymous namespace)")) 2461855958caSGreg Clayton { 2462855958caSGreg Clayton open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); 2463855958caSGreg Clayton if (open_paren) 24646d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 2465855958caSGreg Clayton } 2466855958caSGreg Clayton else 2467855958caSGreg Clayton close_paren = strchr (open_paren, ')'); 2468855958caSGreg Clayton } 24696d3dbf51SGreg Clayton 24706d3dbf51SGreg Clayton if (open_paren) 24716d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 24726d3dbf51SGreg Clayton else 24736d3dbf51SGreg Clayton { 24746d3dbf51SGreg Clayton s.PutCString (cstr); 24756d3dbf51SGreg Clayton s.PutChar ('('); 24766d3dbf51SGreg Clayton } 24775b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 24786d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 24796d3dbf51SGreg Clayton { 2480894f7359SEnrico Granata std::string buffer; 2481894f7359SEnrico Granata 24826d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 24836d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 2484894f7359SEnrico Granata const char *var_representation = nullptr; 24856d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 2486894f7359SEnrico Granata if (var_value_sp->GetClangType().IsAggregateType() && 2487894f7359SEnrico Granata DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get())) 2488894f7359SEnrico Granata { 2489894f7359SEnrico Granata static StringSummaryFormat format(TypeSummaryImpl::Flags() 2490894f7359SEnrico Granata .SetHideItemNames(false) 2491894f7359SEnrico Granata .SetShowMembersOneLiner(true), 2492894f7359SEnrico Granata ""); 2493*f35bc632SEnrico Granata format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions()); 2494894f7359SEnrico Granata var_representation = buffer.c_str(); 2495894f7359SEnrico Granata } 2496894f7359SEnrico Granata else 2497894f7359SEnrico Granata var_representation = var_value_sp->GetValueAsCString(); 24986d3dbf51SGreg Clayton if (arg_idx > 0) 24996d3dbf51SGreg Clayton s.PutCString (", "); 25003b188b17SGreg Clayton if (var_value_sp->GetError().Success()) 2501cc7f9bf5SEnrico Granata { 2502894f7359SEnrico Granata if (var_representation) 2503894f7359SEnrico Granata s.Printf ("%s=%s", var_name, var_representation); 25043b188b17SGreg Clayton else 2505cc7f9bf5SEnrico Granata s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); 2506cc7f9bf5SEnrico Granata } 2507cc7f9bf5SEnrico Granata else 25083b188b17SGreg Clayton s.Printf ("%s=<unavailable>", var_name); 25096d3dbf51SGreg Clayton } 25106d3dbf51SGreg Clayton 25116d3dbf51SGreg Clayton if (close_paren) 25126d3dbf51SGreg Clayton s.PutCString (close_paren); 25136d3dbf51SGreg Clayton else 25146d3dbf51SGreg Clayton s.PutChar(')'); 25156d3dbf51SGreg Clayton 25166d3dbf51SGreg Clayton } 25176d3dbf51SGreg Clayton else 25186d3dbf51SGreg Clayton { 25196d3dbf51SGreg Clayton s.PutCString(cstr); 25206d3dbf51SGreg Clayton } 25216d3dbf51SGreg Clayton } 25226d3dbf51SGreg Clayton } 25236d3dbf51SGreg Clayton else if (sc->symbol) 25246d3dbf51SGreg Clayton { 25256d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 25266d3dbf51SGreg Clayton if (cstr) 25276d3dbf51SGreg Clayton { 25286d3dbf51SGreg Clayton s.PutCString(cstr); 25296d3dbf51SGreg Clayton var_success = true; 25306d3dbf51SGreg Clayton } 25316d3dbf51SGreg Clayton } 25326d3dbf51SGreg Clayton } 2533aff1b357SJason Molenda else if (IsToken (var_name_begin, "addr-offset}") 2534aff1b357SJason Molenda || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}")) 25351b654882SGreg Clayton { 2536aff1b357SJason Molenda if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}")) 2537aff1b357SJason Molenda { 2538aff1b357SJason Molenda addr_offset_print_with_no_padding = true; 2539aff1b357SJason Molenda addr_offset_concrete_func_only = true; 2540aff1b357SJason Molenda } 25411b654882SGreg Clayton var_success = addr != NULL; 25421b654882SGreg Clayton if (var_success) 25431b654882SGreg Clayton { 25441b654882SGreg Clayton format_addr = *addr; 25451b654882SGreg Clayton calculate_format_addr_function_offset = true; 25461b654882SGreg Clayton } 25471b654882SGreg Clayton } 25480769b2b1SMichael Sartain else if (IsToken (var_name_begin, "line-offset}")) 25491b654882SGreg Clayton { 25501b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 25511b654882SGreg Clayton if (var_success) 25521b654882SGreg Clayton { 25531b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 25541b654882SGreg Clayton calculate_format_addr_function_offset = true; 25551b654882SGreg Clayton } 25561b654882SGreg Clayton } 25570769b2b1SMichael Sartain else if (IsToken (var_name_begin, "pc-offset}")) 25581b654882SGreg Clayton { 2559b57e4a1bSJason Molenda StackFrame *frame = exe_ctx->GetFramePtr(); 2560c14ee32dSGreg Clayton var_success = frame != NULL; 25611b654882SGreg Clayton if (var_success) 25621b654882SGreg Clayton { 2563c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 25641b654882SGreg Clayton calculate_format_addr_function_offset = true; 25651b654882SGreg Clayton } 25661b654882SGreg Clayton } 25671b654882SGreg Clayton } 25681b654882SGreg Clayton } 25691b654882SGreg Clayton break; 25701b654882SGreg Clayton 25711b654882SGreg Clayton case 'l': 25720769b2b1SMichael Sartain if (IsToken (var_name_begin, "line.")) 25731b654882SGreg Clayton { 25741b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 25751b654882SGreg Clayton { 25761b654882SGreg Clayton var_name_begin += ::strlen ("line."); 25770769b2b1SMichael Sartain if (IsToken (var_name_begin, "file.")) 25781b654882SGreg Clayton { 25791b654882SGreg Clayton var_name_begin += ::strlen ("file."); 25801b654882SGreg Clayton 25810769b2b1SMichael Sartain if (IsToken (var_name_begin, "basename}")) 25821b654882SGreg Clayton { 25831b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 25849076c0ffSSean Callanan var_success = (bool)format_file_spec; 25851b654882SGreg Clayton } 25860769b2b1SMichael Sartain else if (IsToken (var_name_begin, "fullpath}")) 25871b654882SGreg Clayton { 25881b654882SGreg Clayton format_file_spec = sc->line_entry.file; 25899076c0ffSSean Callanan var_success = (bool)format_file_spec; 25901b654882SGreg Clayton } 25911b654882SGreg Clayton } 25920769b2b1SMichael Sartain else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc)) 25931b654882SGreg Clayton { 25941b654882SGreg Clayton var_success = true; 25950769b2b1SMichael Sartain s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line); 25961b654882SGreg Clayton } 25970769b2b1SMichael Sartain else if ((IsToken (var_name_begin, "start-addr}")) || 25980769b2b1SMichael Sartain (IsToken (var_name_begin, "end-addr}"))) 25991b654882SGreg Clayton { 26001b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 26011b654882SGreg Clayton if (var_success) 26021b654882SGreg Clayton { 26031b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 26041b654882SGreg Clayton if (var_name_begin[0] == 'e') 26051b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 26061b654882SGreg Clayton } 26071b654882SGreg Clayton } 26081b654882SGreg Clayton } 26091b654882SGreg Clayton } 26101b654882SGreg Clayton break; 2611aff1b357SJason Molenda case 'c': 2612aff1b357SJason Molenda if (IsToken (var_name_begin, "current-pc-arrow")) 2613aff1b357SJason Molenda { 2614aff1b357SJason Molenda if (addr && exe_ctx && exe_ctx->GetFramePtr()) 2615aff1b357SJason Molenda { 2616aff1b357SJason Molenda RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP(); 2617aff1b357SJason Molenda if (reg_ctx.get()) 2618aff1b357SJason Molenda { 2619aff1b357SJason Molenda addr_t pc_loadaddr = reg_ctx->GetPC(); 2620aff1b357SJason Molenda if (pc_loadaddr != LLDB_INVALID_ADDRESS) 2621aff1b357SJason Molenda { 2622aff1b357SJason Molenda Address pc; 2623aff1b357SJason Molenda pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr()); 2624aff1b357SJason Molenda if (pc == *addr) 2625aff1b357SJason Molenda { 2626aff1b357SJason Molenda s.Printf ("->"); 2627aff1b357SJason Molenda var_success = true; 2628aff1b357SJason Molenda } 2629aff1b357SJason Molenda else 2630aff1b357SJason Molenda { 2631aff1b357SJason Molenda s.Printf(" "); 2632aff1b357SJason Molenda var_success = true; 2633aff1b357SJason Molenda } 2634aff1b357SJason Molenda } 2635aff1b357SJason Molenda } 2636aff1b357SJason Molenda } 2637aff1b357SJason Molenda } 2638aff1b357SJason Molenda break; 26391b654882SGreg Clayton } 26401b654882SGreg Clayton 26411b654882SGreg Clayton if (var_success) 26421b654882SGreg Clayton { 26431b654882SGreg Clayton // If format addr is valid, then we need to print an address 26441b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 26451b654882SGreg Clayton { 2646b57e4a1bSJason Molenda StackFrame *frame = exe_ctx->GetFramePtr(); 26471b654882SGreg Clayton // We have a register value to display... 26481b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 26491b654882SGreg Clayton { 2650c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 26511b654882SGreg Clayton } 26521b654882SGreg Clayton else 26531b654882SGreg Clayton { 26541b654882SGreg Clayton if (reg_ctx == NULL) 2655c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 26561b654882SGreg Clayton 26571b654882SGreg Clayton if (reg_ctx) 26581b654882SGreg Clayton { 26591b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 26601b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 26611b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 26621b654882SGreg Clayton var_success = reg_info != NULL; 26631b654882SGreg Clayton } 26641b654882SGreg Clayton } 26651b654882SGreg Clayton } 26661b654882SGreg Clayton 26671b654882SGreg Clayton if (reg_info != NULL) 26681b654882SGreg Clayton { 26697349bd90SGreg Clayton RegisterValue reg_value; 26707349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 26717349bd90SGreg Clayton if (var_success) 26721b654882SGreg Clayton { 26739a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 26741b654882SGreg Clayton } 26751b654882SGreg Clayton } 26761b654882SGreg Clayton 26771b654882SGreg Clayton if (format_file_spec) 26781b654882SGreg Clayton { 26791b654882SGreg Clayton s << format_file_spec; 26801b654882SGreg Clayton } 26811b654882SGreg Clayton 26821b654882SGreg Clayton // If format addr is valid, then we need to print an address 26831b654882SGreg Clayton if (format_addr.IsValid()) 26841b654882SGreg Clayton { 26850603aa9dSGreg Clayton var_success = false; 26860603aa9dSGreg Clayton 26871b654882SGreg Clayton if (calculate_format_addr_function_offset) 26881b654882SGreg Clayton { 26891b654882SGreg Clayton Address func_addr; 26900603aa9dSGreg Clayton 26910603aa9dSGreg Clayton if (sc) 26920603aa9dSGreg Clayton { 26931b654882SGreg Clayton if (sc->function) 26940d9c9934SGreg Clayton { 26951b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 2696aff1b357SJason Molenda if (sc->block && addr_offset_concrete_func_only == false) 26970d9c9934SGreg Clayton { 26980d9c9934SGreg Clayton // Check to make sure we aren't in an inline 26990d9c9934SGreg Clayton // function. If we are, use the inline block 27000d9c9934SGreg Clayton // range that contains "format_addr" since 27010d9c9934SGreg Clayton // blocks can be discontiguous. 27020d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 27030d9c9934SGreg Clayton AddressRange inline_range; 27040d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 27050d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 27060d9c9934SGreg Clayton } 27070d9c9934SGreg Clayton } 2708e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2709e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 27100603aa9dSGreg Clayton } 27111b654882SGreg Clayton 27120603aa9dSGreg Clayton if (func_addr.IsValid()) 27131b654882SGreg Clayton { 2714aff1b357SJason Molenda const char *addr_offset_padding = " "; 2715aff1b357SJason Molenda if (addr_offset_print_with_no_padding) 2716aff1b357SJason Molenda { 2717aff1b357SJason Molenda addr_offset_padding = ""; 2718aff1b357SJason Molenda } 27191b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 27201b654882SGreg Clayton { 27211b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 27221b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 27231b654882SGreg Clayton if (addr_file_addr > func_file_addr) 2724aff1b357SJason Molenda s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr); 27251b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 2726aff1b357SJason Molenda s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr); 27270603aa9dSGreg Clayton var_success = true; 27281b654882SGreg Clayton } 27291b654882SGreg Clayton else 27300603aa9dSGreg Clayton { 27310603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 27320603aa9dSGreg Clayton if (target) 27330603aa9dSGreg Clayton { 27340603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 27350603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 27360603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 2737aff1b357SJason Molenda s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr); 27380603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 2739aff1b357SJason Molenda s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr); 27400603aa9dSGreg Clayton var_success = true; 27410603aa9dSGreg Clayton } 27420603aa9dSGreg Clayton } 27431b654882SGreg Clayton } 27441b654882SGreg Clayton } 27451b654882SGreg Clayton else 27461b654882SGreg Clayton { 27470603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 27481b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 27490603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 27500603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 27511b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 27521b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 27531b654882SGreg Clayton 27541b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 27550603aa9dSGreg Clayton { 2756aff1b357SJason Molenda int addr_width = 0; 2757aff1b357SJason Molenda if (exe_ctx && target) 2758aff1b357SJason Molenda { 2759fd1a9362SEric Christopher addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 2760aff1b357SJason Molenda } 276135f1a0d5SGreg Clayton if (addr_width == 0) 276235f1a0d5SGreg Clayton addr_width = 16; 2763aff1b357SJason Molenda if (print_file_addr_or_load_addr) 2764aff1b357SJason Molenda { 2765aff1b357SJason Molenda format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0); 2766aff1b357SJason Molenda } 2767aff1b357SJason Molenda else 2768aff1b357SJason Molenda { 2769d01b2953SDaniel Malea s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr); 2770aff1b357SJason Molenda } 27710603aa9dSGreg Clayton var_success = true; 27720603aa9dSGreg Clayton } 27731b654882SGreg Clayton } 27741b654882SGreg Clayton } 27751b654882SGreg Clayton } 27761b654882SGreg Clayton 27771b654882SGreg Clayton if (var_success == false) 27781b654882SGreg Clayton success = false; 27791b654882SGreg Clayton } 27801b654882SGreg Clayton p = var_name_end; 27811b654882SGreg Clayton } 27821b654882SGreg Clayton else 27831b654882SGreg Clayton break; 27841b654882SGreg Clayton } 27851b654882SGreg Clayton else 27861b654882SGreg Clayton { 27871b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 27881b654882SGreg Clayton s.PutChar(*p); 27891b654882SGreg Clayton } 27901b654882SGreg Clayton } 27911b654882SGreg Clayton else if (*p == '\\') 27921b654882SGreg Clayton { 27931b654882SGreg Clayton ++p; // skip the slash 27941b654882SGreg Clayton switch (*p) 27951b654882SGreg Clayton { 27961b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 27971b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 27981b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 27991b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 28001b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 28011b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 28021b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 28031b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 28041b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 28051b654882SGreg Clayton case '0': 28061b654882SGreg Clayton // 1 to 3 octal chars 28071b654882SGreg Clayton { 28080603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 28090603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 28100603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 28110603aa9dSGreg Clayton 28120603aa9dSGreg Clayton int i; 28130603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 28140603aa9dSGreg Clayton oct_str[i] = p[i]; 28150603aa9dSGreg Clayton 28160603aa9dSGreg Clayton // We don't want to consume the last octal character since 28170603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 28180603aa9dSGreg Clayton // one less than i (even if i is zero) 28190603aa9dSGreg Clayton p += i - 1; 28200603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 28210603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 28221b654882SGreg Clayton { 2823c7bece56SGreg Clayton s.PutChar((char)octal_value); 28241b654882SGreg Clayton } 28251b654882SGreg Clayton } 28261b654882SGreg Clayton break; 28271b654882SGreg Clayton 28281b654882SGreg Clayton case 'x': 28291b654882SGreg Clayton // hex number in the format 28300603aa9dSGreg Clayton if (isxdigit(p[1])) 28311b654882SGreg Clayton { 28320603aa9dSGreg Clayton ++p; // Skip the 'x' 28331b654882SGreg Clayton 28340603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 28350603aa9dSGreg Clayton // NULL terminator 28361b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 28371b654882SGreg Clayton hex_str[0] = *p; 28380603aa9dSGreg Clayton if (isxdigit(p[1])) 28390603aa9dSGreg Clayton { 28400603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 28411b654882SGreg Clayton hex_str[1] = *p; 28420603aa9dSGreg Clayton } 28430603aa9dSGreg Clayton 28441b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 28450603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 2846c7bece56SGreg Clayton s.PutChar ((char)hex_value); 28471b654882SGreg Clayton } 28481b654882SGreg Clayton else 28491b654882SGreg Clayton { 28500603aa9dSGreg Clayton s.PutChar('x'); 28511b654882SGreg Clayton } 28521b654882SGreg Clayton break; 28531b654882SGreg Clayton 28541b654882SGreg Clayton default: 28550603aa9dSGreg Clayton // Just desensitize any other character by just printing what 28560603aa9dSGreg Clayton // came after the '\' 28570603aa9dSGreg Clayton s << *p; 28581b654882SGreg Clayton break; 28591b654882SGreg Clayton 28601b654882SGreg Clayton } 28611b654882SGreg Clayton 28621b654882SGreg Clayton } 28631b654882SGreg Clayton } 28641b654882SGreg Clayton if (end) 28651b654882SGreg Clayton *end = p; 28661b654882SGreg Clayton return success; 28671b654882SGreg Clayton } 28681b654882SGreg Clayton 2869c3ce7f27SMichael Sartain bool 2870c3ce7f27SMichael Sartain Debugger::FormatPrompt 2871c3ce7f27SMichael Sartain ( 2872c3ce7f27SMichael Sartain const char *format, 2873c3ce7f27SMichael Sartain const SymbolContext *sc, 2874c3ce7f27SMichael Sartain const ExecutionContext *exe_ctx, 2875c3ce7f27SMichael Sartain const Address *addr, 2876c3ce7f27SMichael Sartain Stream &s, 2877c3ce7f27SMichael Sartain ValueObject* valobj 2878c3ce7f27SMichael Sartain ) 2879c3ce7f27SMichael Sartain { 2880c3ce7f27SMichael Sartain bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true; 2881c3ce7f27SMichael Sartain std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color); 2882c3ce7f27SMichael Sartain if (format_str.length()) 2883c3ce7f27SMichael Sartain format = format_str.c_str(); 2884aff1b357SJason Molenda return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false); 2885c3ce7f27SMichael Sartain } 2886c3ce7f27SMichael Sartain 2887aff1b357SJason Molenda bool 2888aff1b357SJason Molenda Debugger::FormatDisassemblerAddress (const char *format, 2889aff1b357SJason Molenda const SymbolContext *sc, 2890aff1b357SJason Molenda const SymbolContext *prev_sc, 2891aff1b357SJason Molenda const ExecutionContext *exe_ctx, 2892aff1b357SJason Molenda const Address *addr, 2893aff1b357SJason Molenda Stream &s) 2894aff1b357SJason Molenda { 2895aff1b357SJason Molenda if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope()) 2896aff1b357SJason Molenda { 2897aff1b357SJason Molenda format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat(); 2898aff1b357SJason Molenda } 2899aff1b357SJason Molenda bool function_changed = false; 2900aff1b357SJason Molenda bool initial_function = false; 2901aff1b357SJason Molenda if (prev_sc && (prev_sc->function || prev_sc->symbol)) 2902aff1b357SJason Molenda { 2903aff1b357SJason Molenda if (sc && (sc->function || sc->symbol)) 2904aff1b357SJason Molenda { 2905aff1b357SJason Molenda if (prev_sc->symbol && sc->symbol) 2906aff1b357SJason Molenda { 2907aff1b357SJason Molenda if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType())) 2908aff1b357SJason Molenda { 2909aff1b357SJason Molenda function_changed = true; 2910aff1b357SJason Molenda } 2911aff1b357SJason Molenda } 2912aff1b357SJason Molenda else if (prev_sc->function && sc->function) 2913aff1b357SJason Molenda { 2914aff1b357SJason Molenda if (prev_sc->function->GetMangled() != sc->function->GetMangled()) 2915aff1b357SJason Molenda { 2916aff1b357SJason Molenda function_changed = true; 2917aff1b357SJason Molenda } 2918aff1b357SJason Molenda } 2919aff1b357SJason Molenda } 2920aff1b357SJason Molenda } 2921aff1b357SJason Molenda // The first context on a list of instructions will have a prev_sc that 2922aff1b357SJason Molenda // has no Function or Symbol -- if SymbolContext had an IsValid() method, it 2923aff1b357SJason Molenda // would return false. But we do get a prev_sc pointer. 2924aff1b357SJason Molenda if ((sc && (sc->function || sc->symbol)) 2925aff1b357SJason Molenda && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL)) 2926aff1b357SJason Molenda { 2927aff1b357SJason Molenda initial_function = true; 2928aff1b357SJason Molenda } 2929aff1b357SJason Molenda return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function); 2930aff1b357SJason Molenda } 2931aff1b357SJason Molenda 2932aff1b357SJason Molenda 2933228063cdSJim Ingham void 2934228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2935228063cdSJim Ingham { 29364f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 29374f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 29384f02b22dSJim Ingham // callback. 2939228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2940228063cdSJim Ingham } 2941228063cdSJim Ingham 2942228063cdSJim Ingham bool 2943228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2944228063cdSJim Ingham { 2945228063cdSJim Ingham Log::Callbacks log_callbacks; 2946228063cdSJim Ingham 2947228063cdSJim Ingham StreamSP log_stream_sp; 29489a028519SSean Callanan if (m_log_callback_stream_sp) 2949228063cdSJim Ingham { 2950228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2951228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2952228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2953228063cdSJim Ingham } 2954228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2955228063cdSJim Ingham { 295644d93782SGreg Clayton log_stream_sp = GetOutputFile(); 2957228063cdSJim Ingham } 2958228063cdSJim Ingham else 2959228063cdSJim Ingham { 2960228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2961c1b2ccfdSGreg Clayton if (pos != m_log_streams.end()) 2962c1b2ccfdSGreg Clayton log_stream_sp = pos->second.lock(); 2963c1b2ccfdSGreg Clayton if (!log_stream_sp) 2964228063cdSJim Ingham { 2965228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2966228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2967228063cdSJim Ingham } 2968228063cdSJim Ingham } 2969228063cdSJim Ingham assert (log_stream_sp.get()); 2970228063cdSJim Ingham 2971228063cdSJim Ingham if (log_options == 0) 2972228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2973228063cdSJim Ingham 297457abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks)) 2975228063cdSJim Ingham { 2976228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2977228063cdSJim Ingham return true; 2978228063cdSJim Ingham } 2979228063cdSJim Ingham else 2980228063cdSJim Ingham { 2981228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2982228063cdSJim Ingham if (log_channel_sp) 2983228063cdSJim Ingham { 2984228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2985228063cdSJim Ingham { 2986228063cdSJim Ingham return true; 2987228063cdSJim Ingham } 2988228063cdSJim Ingham else 2989228063cdSJim Ingham { 2990228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2991228063cdSJim Ingham return false; 2992228063cdSJim Ingham } 2993228063cdSJim Ingham } 2994228063cdSJim Ingham else 2995228063cdSJim Ingham { 2996228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2997228063cdSJim Ingham return false; 2998228063cdSJim Ingham } 2999228063cdSJim Ingham } 3000228063cdSJim Ingham return false; 3001228063cdSJim Ingham } 3002228063cdSJim Ingham 30039585fbfcSGreg Clayton SourceManager & 30049585fbfcSGreg Clayton Debugger::GetSourceManager () 30059585fbfcSGreg Clayton { 30069585fbfcSGreg Clayton if (m_source_manager_ap.get() == NULL) 30079585fbfcSGreg Clayton m_source_manager_ap.reset (new SourceManager (shared_from_this())); 30089585fbfcSGreg Clayton return *m_source_manager_ap; 30099585fbfcSGreg Clayton } 30109585fbfcSGreg Clayton 30119585fbfcSGreg Clayton 301244d93782SGreg Clayton 301344d93782SGreg Clayton // This function handles events that were broadcast by the process. 301444d93782SGreg Clayton void 301544d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp) 301644d93782SGreg Clayton { 301744d93782SGreg Clayton using namespace lldb; 301844d93782SGreg Clayton const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp); 301944d93782SGreg Clayton 302044d93782SGreg Clayton // if (event_type & eBreakpointEventTypeAdded 302144d93782SGreg Clayton // || event_type & eBreakpointEventTypeRemoved 302244d93782SGreg Clayton // || event_type & eBreakpointEventTypeEnabled 302344d93782SGreg Clayton // || event_type & eBreakpointEventTypeDisabled 302444d93782SGreg Clayton // || event_type & eBreakpointEventTypeCommandChanged 302544d93782SGreg Clayton // || event_type & eBreakpointEventTypeConditionChanged 302644d93782SGreg Clayton // || event_type & eBreakpointEventTypeIgnoreChanged 302744d93782SGreg Clayton // || event_type & eBreakpointEventTypeLocationsResolved) 302844d93782SGreg Clayton // { 302944d93782SGreg Clayton // // Don't do anything about these events, since the breakpoint commands already echo these actions. 303044d93782SGreg Clayton // } 303144d93782SGreg Clayton // 303244d93782SGreg Clayton if (event_type & eBreakpointEventTypeLocationsAdded) 303344d93782SGreg Clayton { 303444d93782SGreg Clayton uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp); 303544d93782SGreg Clayton if (num_new_locations > 0) 303644d93782SGreg Clayton { 303744d93782SGreg Clayton BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); 303844d93782SGreg Clayton StreamFileSP output_sp (GetOutputFile()); 303944d93782SGreg Clayton if (output_sp) 304044d93782SGreg Clayton { 304144d93782SGreg Clayton output_sp->Printf("%d location%s added to breakpoint %d\n", 304244d93782SGreg Clayton num_new_locations, 304344d93782SGreg Clayton num_new_locations == 1 ? "" : "s", 304444d93782SGreg Clayton breakpoint->GetID()); 304544d93782SGreg Clayton RefreshTopIOHandler(); 304644d93782SGreg Clayton } 304744d93782SGreg Clayton } 304844d93782SGreg Clayton } 304944d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsRemoved) 305044d93782SGreg Clayton // { 305144d93782SGreg Clayton // // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 305244d93782SGreg Clayton // } 305344d93782SGreg Clayton // else if (event_type & eBreakpointEventTypeLocationsResolved) 305444d93782SGreg Clayton // { 305544d93782SGreg Clayton // // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 305644d93782SGreg Clayton // } 305744d93782SGreg Clayton } 305844d93782SGreg Clayton 305944d93782SGreg Clayton size_t 306044d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream) 306144d93782SGreg Clayton { 306244d93782SGreg Clayton size_t total_bytes = 0; 306344d93782SGreg Clayton if (stream == NULL) 306444d93782SGreg Clayton stream = GetOutputFile().get(); 306544d93782SGreg Clayton 306644d93782SGreg Clayton if (stream) 306744d93782SGreg Clayton { 306844d93782SGreg Clayton // The process has stuff waiting for stdout; get it and write it out to the appropriate place. 306944d93782SGreg Clayton if (process == NULL) 307044d93782SGreg Clayton { 307144d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 307244d93782SGreg Clayton if (target_sp) 307344d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 307444d93782SGreg Clayton } 307544d93782SGreg Clayton if (process) 307644d93782SGreg Clayton { 307744d93782SGreg Clayton Error error; 307844d93782SGreg Clayton size_t len; 307944d93782SGreg Clayton char stdio_buffer[1024]; 308044d93782SGreg Clayton while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 308144d93782SGreg Clayton { 308244d93782SGreg Clayton stream->Write(stdio_buffer, len); 308344d93782SGreg Clayton total_bytes += len; 308444d93782SGreg Clayton } 308544d93782SGreg Clayton } 308644d93782SGreg Clayton stream->Flush(); 308744d93782SGreg Clayton } 308844d93782SGreg Clayton return total_bytes; 308944d93782SGreg Clayton } 309044d93782SGreg Clayton 309144d93782SGreg Clayton size_t 309244d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream) 309344d93782SGreg Clayton { 309444d93782SGreg Clayton size_t total_bytes = 0; 309544d93782SGreg Clayton if (stream == NULL) 309644d93782SGreg Clayton stream = GetOutputFile().get(); 309744d93782SGreg Clayton 309844d93782SGreg Clayton if (stream) 309944d93782SGreg Clayton { 310044d93782SGreg Clayton // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 310144d93782SGreg Clayton if (process == NULL) 310244d93782SGreg Clayton { 310344d93782SGreg Clayton TargetSP target_sp = GetTargetList().GetSelectedTarget(); 310444d93782SGreg Clayton if (target_sp) 310544d93782SGreg Clayton process = target_sp->GetProcessSP().get(); 310644d93782SGreg Clayton } 310744d93782SGreg Clayton if (process) 310844d93782SGreg Clayton { 310944d93782SGreg Clayton Error error; 311044d93782SGreg Clayton size_t len; 311144d93782SGreg Clayton char stdio_buffer[1024]; 311244d93782SGreg Clayton while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 311344d93782SGreg Clayton { 311444d93782SGreg Clayton stream->Write(stdio_buffer, len); 311544d93782SGreg Clayton total_bytes += len; 311644d93782SGreg Clayton } 311744d93782SGreg Clayton } 311844d93782SGreg Clayton stream->Flush(); 311944d93782SGreg Clayton } 312044d93782SGreg Clayton return total_bytes; 312144d93782SGreg Clayton } 312244d93782SGreg Clayton 3123dc6224e0SGreg Clayton 312444d93782SGreg Clayton // This function handles events that were broadcast by the process. 312544d93782SGreg Clayton void 312644d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp) 312744d93782SGreg Clayton { 312844d93782SGreg Clayton using namespace lldb; 312944d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 313044d93782SGreg Clayton ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); 313144d93782SGreg Clayton 3132b4874f1aSGreg Clayton StreamString output_stream; 3133b4874f1aSGreg Clayton StreamString error_stream; 313444d93782SGreg Clayton const bool gui_enabled = IsForwardingEvents(); 313544d93782SGreg Clayton 3136b4874f1aSGreg Clayton if (!gui_enabled) 3137b4874f1aSGreg Clayton { 3138b4874f1aSGreg Clayton bool pop_process_io_handler = false; 313944d93782SGreg Clayton assert (process_sp); 314044d93782SGreg Clayton 3141b4874f1aSGreg Clayton if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged) 314244d93782SGreg Clayton { 3143b4874f1aSGreg Clayton GetProcessSTDOUT (process_sp.get(), &output_stream); 314444d93782SGreg Clayton } 3145b4874f1aSGreg Clayton 3146b4874f1aSGreg Clayton if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged) 314744d93782SGreg Clayton { 3148b4874f1aSGreg Clayton GetProcessSTDERR (process_sp.get(), &error_stream); 314944d93782SGreg Clayton } 3150b4874f1aSGreg Clayton 3151b4874f1aSGreg Clayton if (event_type & Process::eBroadcastBitStateChanged) 315244d93782SGreg Clayton { 3153dc6224e0SGreg Clayton Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler); 315444d93782SGreg Clayton } 3155b4874f1aSGreg Clayton 3156b4874f1aSGreg Clayton if (output_stream.GetSize() || error_stream.GetSize()) 3157b4874f1aSGreg Clayton { 3158b4874f1aSGreg Clayton StreamFileSP error_stream_sp (GetOutputFile()); 31596fea17e8SGreg Clayton bool top_io_handler_hid = false; 31606fea17e8SGreg Clayton 31616fea17e8SGreg Clayton if (process_sp->ProcessIOHandlerIsActive() == false) 31626fea17e8SGreg Clayton top_io_handler_hid = HideTopIOHandler(); 3163b4874f1aSGreg Clayton 3164b4874f1aSGreg Clayton if (output_stream.GetSize()) 3165b4874f1aSGreg Clayton { 3166b4874f1aSGreg Clayton StreamFileSP output_stream_sp (GetOutputFile()); 3167b4874f1aSGreg Clayton if (output_stream_sp) 3168b4874f1aSGreg Clayton output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize()); 3169b4874f1aSGreg Clayton } 3170b4874f1aSGreg Clayton 3171b4874f1aSGreg Clayton if (error_stream.GetSize()) 3172b4874f1aSGreg Clayton { 3173b4874f1aSGreg Clayton StreamFileSP error_stream_sp (GetErrorFile()); 3174b4874f1aSGreg Clayton if (error_stream_sp) 3175b4874f1aSGreg Clayton error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize()); 317644d93782SGreg Clayton } 317744d93782SGreg Clayton 317844d93782SGreg Clayton if (top_io_handler_hid) 317944d93782SGreg Clayton RefreshTopIOHandler(); 318044d93782SGreg Clayton } 318144d93782SGreg Clayton 3182b4874f1aSGreg Clayton if (pop_process_io_handler) 3183b4874f1aSGreg Clayton process_sp->PopProcessIOHandler(); 3184b4874f1aSGreg Clayton } 3185b4874f1aSGreg Clayton } 3186b4874f1aSGreg Clayton 318744d93782SGreg Clayton void 318844d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp) 318944d93782SGreg Clayton { 319044d93782SGreg Clayton // At present the only thread event we handle is the Frame Changed event, 319144d93782SGreg Clayton // and all we do for that is just reprint the thread status for that thread. 319244d93782SGreg Clayton using namespace lldb; 319344d93782SGreg Clayton const uint32_t event_type = event_sp->GetType(); 319444d93782SGreg Clayton if (event_type == Thread::eBroadcastBitStackChanged || 319544d93782SGreg Clayton event_type == Thread::eBroadcastBitThreadSelected ) 319644d93782SGreg Clayton { 319744d93782SGreg Clayton ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get())); 319844d93782SGreg Clayton if (thread_sp) 319944d93782SGreg Clayton { 320044d93782SGreg Clayton HideTopIOHandler(); 320144d93782SGreg Clayton StreamFileSP stream_sp (GetOutputFile()); 320244d93782SGreg Clayton thread_sp->GetStatus(*stream_sp, 0, 1, 1); 320344d93782SGreg Clayton RefreshTopIOHandler(); 320444d93782SGreg Clayton } 320544d93782SGreg Clayton } 320644d93782SGreg Clayton } 320744d93782SGreg Clayton 320844d93782SGreg Clayton bool 320944d93782SGreg Clayton Debugger::IsForwardingEvents () 321044d93782SGreg Clayton { 321144d93782SGreg Clayton return (bool)m_forward_listener_sp; 321244d93782SGreg Clayton } 321344d93782SGreg Clayton 321444d93782SGreg Clayton void 321544d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp) 321644d93782SGreg Clayton { 321744d93782SGreg Clayton m_forward_listener_sp = listener_sp; 321844d93782SGreg Clayton } 321944d93782SGreg Clayton 322044d93782SGreg Clayton void 322144d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp) 322244d93782SGreg Clayton { 322344d93782SGreg Clayton m_forward_listener_sp.reset(); 322444d93782SGreg Clayton } 322544d93782SGreg Clayton 322644d93782SGreg Clayton 322744d93782SGreg Clayton void 322844d93782SGreg Clayton Debugger::DefaultEventHandler() 322944d93782SGreg Clayton { 323044d93782SGreg Clayton Listener& listener(GetListener()); 323144d93782SGreg Clayton ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass()); 323244d93782SGreg Clayton ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass()); 323344d93782SGreg Clayton ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass()); 323444d93782SGreg Clayton BroadcastEventSpec target_event_spec (broadcaster_class_target, 323544d93782SGreg Clayton Target::eBroadcastBitBreakpointChanged); 323644d93782SGreg Clayton 323744d93782SGreg Clayton BroadcastEventSpec process_event_spec (broadcaster_class_process, 323844d93782SGreg Clayton Process::eBroadcastBitStateChanged | 323944d93782SGreg Clayton Process::eBroadcastBitSTDOUT | 324044d93782SGreg Clayton Process::eBroadcastBitSTDERR); 324144d93782SGreg Clayton 324244d93782SGreg Clayton BroadcastEventSpec thread_event_spec (broadcaster_class_thread, 324344d93782SGreg Clayton Thread::eBroadcastBitStackChanged | 324444d93782SGreg Clayton Thread::eBroadcastBitThreadSelected ); 324544d93782SGreg Clayton 324644d93782SGreg Clayton listener.StartListeningForEventSpec (*this, target_event_spec); 324744d93782SGreg Clayton listener.StartListeningForEventSpec (*this, process_event_spec); 324844d93782SGreg Clayton listener.StartListeningForEventSpec (*this, thread_event_spec); 324944d93782SGreg Clayton listener.StartListeningForEvents (m_command_interpreter_ap.get(), 325044d93782SGreg Clayton CommandInterpreter::eBroadcastBitQuitCommandReceived | 325144d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousOutputData | 325244d93782SGreg Clayton CommandInterpreter::eBroadcastBitAsynchronousErrorData ); 325344d93782SGreg Clayton 325444d93782SGreg Clayton bool done = false; 325544d93782SGreg Clayton while (!done) 325644d93782SGreg Clayton { 325744d93782SGreg Clayton // Mutex::Locker locker; 325844d93782SGreg Clayton // if (locker.TryLock(m_input_reader_stack.GetMutex())) 325944d93782SGreg Clayton // { 326044d93782SGreg Clayton // if (m_input_reader_stack.IsEmpty()) 326144d93782SGreg Clayton // break; 326244d93782SGreg Clayton // } 326344d93782SGreg Clayton // 326444d93782SGreg Clayton EventSP event_sp; 326544d93782SGreg Clayton if (listener.WaitForEvent(NULL, event_sp)) 326644d93782SGreg Clayton { 326744d93782SGreg Clayton if (event_sp) 326844d93782SGreg Clayton { 326944d93782SGreg Clayton Broadcaster *broadcaster = event_sp->GetBroadcaster(); 327044d93782SGreg Clayton if (broadcaster) 327144d93782SGreg Clayton { 327244d93782SGreg Clayton uint32_t event_type = event_sp->GetType(); 327344d93782SGreg Clayton ConstString broadcaster_class (broadcaster->GetBroadcasterClass()); 327444d93782SGreg Clayton if (broadcaster_class == broadcaster_class_process) 327544d93782SGreg Clayton { 327644d93782SGreg Clayton HandleProcessEvent (event_sp); 327744d93782SGreg Clayton } 327844d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_target) 327944d93782SGreg Clayton { 328044d93782SGreg Clayton if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get())) 328144d93782SGreg Clayton { 328244d93782SGreg Clayton HandleBreakpointEvent (event_sp); 328344d93782SGreg Clayton } 328444d93782SGreg Clayton } 328544d93782SGreg Clayton else if (broadcaster_class == broadcaster_class_thread) 328644d93782SGreg Clayton { 328744d93782SGreg Clayton HandleThreadEvent (event_sp); 328844d93782SGreg Clayton } 328944d93782SGreg Clayton else if (broadcaster == m_command_interpreter_ap.get()) 329044d93782SGreg Clayton { 329144d93782SGreg Clayton if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived) 329244d93782SGreg Clayton { 329344d93782SGreg Clayton done = true; 329444d93782SGreg Clayton } 329544d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData) 329644d93782SGreg Clayton { 329744d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 329844d93782SGreg Clayton if (data && data[0]) 329944d93782SGreg Clayton { 330044d93782SGreg Clayton StreamFileSP error_sp (GetErrorFile()); 330144d93782SGreg Clayton if (error_sp) 330244d93782SGreg Clayton { 330344d93782SGreg Clayton HideTopIOHandler(); 330444d93782SGreg Clayton error_sp->PutCString(data); 330544d93782SGreg Clayton error_sp->Flush(); 330644d93782SGreg Clayton RefreshTopIOHandler(); 330744d93782SGreg Clayton } 330844d93782SGreg Clayton } 330944d93782SGreg Clayton } 331044d93782SGreg Clayton else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData) 331144d93782SGreg Clayton { 331244d93782SGreg Clayton const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get())); 331344d93782SGreg Clayton if (data && data[0]) 331444d93782SGreg Clayton { 331544d93782SGreg Clayton StreamFileSP output_sp (GetOutputFile()); 331644d93782SGreg Clayton if (output_sp) 331744d93782SGreg Clayton { 331844d93782SGreg Clayton HideTopIOHandler(); 331944d93782SGreg Clayton output_sp->PutCString(data); 332044d93782SGreg Clayton output_sp->Flush(); 332144d93782SGreg Clayton RefreshTopIOHandler(); 332244d93782SGreg Clayton } 332344d93782SGreg Clayton } 332444d93782SGreg Clayton } 332544d93782SGreg Clayton } 332644d93782SGreg Clayton } 332744d93782SGreg Clayton 332844d93782SGreg Clayton if (m_forward_listener_sp) 332944d93782SGreg Clayton m_forward_listener_sp->AddEvent(event_sp); 333044d93782SGreg Clayton } 333144d93782SGreg Clayton } 333244d93782SGreg Clayton } 333344d93782SGreg Clayton } 333444d93782SGreg Clayton 333544d93782SGreg Clayton lldb::thread_result_t 333644d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg) 333744d93782SGreg Clayton { 333844d93782SGreg Clayton ((Debugger *)arg)->DefaultEventHandler(); 333944d93782SGreg Clayton return NULL; 334044d93782SGreg Clayton } 334144d93782SGreg Clayton 334244d93782SGreg Clayton bool 334344d93782SGreg Clayton Debugger::StartEventHandlerThread() 334444d93782SGreg Clayton { 3345acee96aeSZachary Turner if (!m_event_handler_thread.IsJoinable()) 3346807b6b32SGreg Clayton { 33477c2896a2SZachary Turner // Use larger 8MB stack for this thread 33487c2896a2SZachary Turner m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread, this, NULL, 33497c2896a2SZachary Turner g_debugger_event_thread_stack_bytes); 3350807b6b32SGreg Clayton } 3351acee96aeSZachary Turner return m_event_handler_thread.IsJoinable(); 335244d93782SGreg Clayton } 335344d93782SGreg Clayton 335444d93782SGreg Clayton void 335544d93782SGreg Clayton Debugger::StopEventHandlerThread() 335644d93782SGreg Clayton { 3357acee96aeSZachary Turner if (m_event_handler_thread.IsJoinable()) 335844d93782SGreg Clayton { 335944d93782SGreg Clayton GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived); 336039de3110SZachary Turner m_event_handler_thread.Join(nullptr); 336144d93782SGreg Clayton } 336244d93782SGreg Clayton } 336344d93782SGreg Clayton 336444d93782SGreg Clayton 336544d93782SGreg Clayton lldb::thread_result_t 336644d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg) 336744d93782SGreg Clayton { 336844d93782SGreg Clayton Debugger *debugger = (Debugger *)arg; 336944d93782SGreg Clayton debugger->ExecuteIOHanders(); 337044d93782SGreg Clayton debugger->StopEventHandlerThread(); 337144d93782SGreg Clayton return NULL; 337244d93782SGreg Clayton } 337344d93782SGreg Clayton 337444d93782SGreg Clayton bool 337544d93782SGreg Clayton Debugger::StartIOHandlerThread() 337644d93782SGreg Clayton { 3377acee96aeSZachary Turner if (!m_io_handler_thread.IsJoinable()) 3378807b6b32SGreg Clayton m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler", 3379807b6b32SGreg Clayton IOHandlerThread, 3380807b6b32SGreg Clayton this, 3381807b6b32SGreg Clayton NULL, 3382807b6b32SGreg Clayton 8*1024*1024); // Use larger 8MB stack for this thread 3383acee96aeSZachary Turner return m_io_handler_thread.IsJoinable(); 338444d93782SGreg Clayton } 338544d93782SGreg Clayton 338644d93782SGreg Clayton void 338744d93782SGreg Clayton Debugger::StopIOHandlerThread() 338844d93782SGreg Clayton { 3389acee96aeSZachary Turner if (m_io_handler_thread.IsJoinable()) 339044d93782SGreg Clayton { 339144d93782SGreg Clayton if (m_input_file_sp) 339244d93782SGreg Clayton m_input_file_sp->GetFile().Close(); 339339de3110SZachary Turner m_io_handler_thread.Join(nullptr); 339444d93782SGreg Clayton } 339544d93782SGreg Clayton } 339644d93782SGreg Clayton 339744d93782SGreg Clayton 3398