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;
67ebc1bb27SCaroline Tice 
681b654882SGreg Clayton #pragma mark Static Functions
691b654882SGreg Clayton 
701b654882SGreg Clayton static Mutex &
711b654882SGreg Clayton GetDebuggerListMutex ()
721b654882SGreg Clayton {
731b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
741b654882SGreg Clayton     return g_mutex;
751b654882SGreg Clayton }
761b654882SGreg Clayton 
771b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
781b654882SGreg Clayton 
791b654882SGreg Clayton static DebuggerList &
801b654882SGreg Clayton GetDebuggerList()
811b654882SGreg Clayton {
821b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
836a7f3338SBruce Mitchener     // global init constructors
841b654882SGreg Clayton     static DebuggerList g_list;
851b654882SGreg Clayton     return g_list;
861b654882SGreg Clayton }
87e372b98dSGreg Clayton 
88e372b98dSGreg Clayton OptionEnumValueElement
8967cc0636SGreg Clayton g_show_disassembly_enum_values[] =
90e372b98dSGreg Clayton {
9167cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
9267cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
9367cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
94e372b98dSGreg Clayton     { 0, NULL, NULL }
95e372b98dSGreg Clayton };
96e372b98dSGreg Clayton 
9767cc0636SGreg Clayton OptionEnumValueElement
9867cc0636SGreg Clayton g_language_enumerators[] =
9967cc0636SGreg Clayton {
10067cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
10167cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
10267cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
103a12993c9SGreg Clayton     { 0, NULL, NULL }
10467cc0636SGreg Clayton };
105e372b98dSGreg Clayton 
10667cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10767cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10867cc0636SGreg Clayton 
1090769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
11067cc0636SGreg Clayton     "{, ${frame.pc}}"\
11167cc0636SGreg Clayton     MODULE_WITH_FUNC\
11267cc0636SGreg Clayton     FILE_AND_LINE\
1130769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
1140769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
115705b1809SJason Molenda     "{, activity = '${thread.info.activity.name}'}" \
116705b1809SJason Molenda     "{, ${thread.info.trace_messages} messages}" \
11767cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
11867cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
11930fadafeSJim Ingham     "{\\nCompleted expression: ${thread.completed-expression}}"\
12067cc0636SGreg Clayton     "\\n"
12167cc0636SGreg Clayton 
12267cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
12367cc0636SGreg Clayton     MODULE_WITH_FUNC\
12467cc0636SGreg Clayton     FILE_AND_LINE\
12567cc0636SGreg Clayton     "\\n"
12667cc0636SGreg Clayton 
127aff1b357SJason Molenda #define DEFAULT_DISASSEMBLY_FORMAT "${addr-file-or-load} <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>: "
12867cc0636SGreg Clayton 
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)." },
148e8cd0c98SGreg Clayton 
14967cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
15067cc0636SGreg Clayton };
15167cc0636SGreg Clayton 
15267cc0636SGreg Clayton enum
15367cc0636SGreg Clayton {
15467cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
155aff1b357SJason Molenda     ePropertyDisassemblyFormat,
15667cc0636SGreg Clayton     ePropertyFrameFormat,
15767cc0636SGreg Clayton     ePropertyNotiftVoid,
15867cc0636SGreg Clayton     ePropertyPrompt,
15967cc0636SGreg Clayton     ePropertyScriptLanguage,
16067cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
16167cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
16267cc0636SGreg Clayton     ePropertyStopLineCountAfter,
16367cc0636SGreg Clayton     ePropertyStopLineCountBefore,
16467cc0636SGreg Clayton     ePropertyTerminalWidth,
16567cc0636SGreg Clayton     ePropertyThreadFormat,
166c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
167c3ce7f27SMichael Sartain     ePropertyUseColor,
16890a8db30SEnrico Granata     ePropertyAutoOneLineSummaries
16967cc0636SGreg Clayton };
17067cc0636SGreg Clayton 
1715fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1724c05410fSGreg Clayton 
1734c05410fSGreg Clayton Error
1744c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1754c05410fSGreg Clayton                             VarSetOperationType op,
1764c05410fSGreg Clayton                             const char *property_path,
1774c05410fSGreg Clayton                             const char *value)
1784c05410fSGreg Clayton {
17984a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
18084a53dfbSEnrico Granata     TargetSP target_sp;
181397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
18284a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
18384a53dfbSEnrico Granata     {
18484a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
18584a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
18684a53dfbSEnrico Granata     }
1874c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1884c05410fSGreg Clayton     if (error.Success())
1894c05410fSGreg Clayton     {
19084a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
1914c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1924c05410fSGreg Clayton         {
1934c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
194c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
195c3ce7f27SMichael Sartain             if (str.length())
196c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
19744d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
1984c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1994c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
2004c05410fSGreg Clayton         }
201c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
202c3ce7f27SMichael Sartain         {
203c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
204c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
205c3ce7f27SMichael Sartain         }
206397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
20784a53dfbSEnrico Granata         {
208397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
20984a53dfbSEnrico Granata             {
21084a53dfbSEnrico Granata                 std::list<Error> errors;
2119730339bSEnrico Granata                 StreamString feedback_stream;
2129730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
21384a53dfbSEnrico Granata                 {
21444d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
21544d93782SGreg Clayton                     if (stream_sp)
21644d93782SGreg Clayton                     {
21784a53dfbSEnrico Granata                         for (auto error : errors)
21884a53dfbSEnrico Granata                         {
21944d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
22084a53dfbSEnrico Granata                         }
2219730339bSEnrico Granata                         if (feedback_stream.GetSize())
22244d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
22344d93782SGreg Clayton                     }
22484a53dfbSEnrico Granata                 }
22584a53dfbSEnrico Granata             }
22684a53dfbSEnrico Granata         }
2274c05410fSGreg Clayton     }
2284c05410fSGreg Clayton     return error;
2294c05410fSGreg Clayton }
2304c05410fSGreg Clayton 
23167cc0636SGreg Clayton bool
23267cc0636SGreg Clayton Debugger::GetAutoConfirm () const
23367cc0636SGreg Clayton {
23467cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
235754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
23667cc0636SGreg Clayton }
23767cc0636SGreg Clayton 
23867cc0636SGreg Clayton const char *
239aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const
240aff1b357SJason Molenda {
241aff1b357SJason Molenda     const uint32_t idx = ePropertyDisassemblyFormat;
242aff1b357SJason Molenda     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
243aff1b357SJason Molenda }
244aff1b357SJason Molenda 
245aff1b357SJason Molenda const char *
24667cc0636SGreg Clayton Debugger::GetFrameFormat() const
24767cc0636SGreg Clayton {
24867cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
249754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
25067cc0636SGreg Clayton }
25167cc0636SGreg Clayton 
25267cc0636SGreg Clayton bool
25367cc0636SGreg Clayton Debugger::GetNotifyVoid () const
25467cc0636SGreg Clayton {
25567cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
256754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
25767cc0636SGreg Clayton }
25867cc0636SGreg Clayton 
25967cc0636SGreg Clayton const char *
26067cc0636SGreg Clayton Debugger::GetPrompt() const
26167cc0636SGreg Clayton {
26267cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
263754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
26467cc0636SGreg Clayton }
26567cc0636SGreg Clayton 
26667cc0636SGreg Clayton void
26767cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
26867cc0636SGreg Clayton {
26967cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
27067cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
27167cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
272c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
273c3ce7f27SMichael Sartain     if (str.length())
274c3ce7f27SMichael Sartain         new_prompt = str.c_str();
27544d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
27667cc0636SGreg Clayton }
27767cc0636SGreg Clayton 
27867cc0636SGreg Clayton const char *
27967cc0636SGreg Clayton Debugger::GetThreadFormat() const
28067cc0636SGreg Clayton {
28167cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
282754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
28367cc0636SGreg Clayton }
28467cc0636SGreg Clayton 
28567cc0636SGreg Clayton lldb::ScriptLanguage
28667cc0636SGreg Clayton Debugger::GetScriptLanguage() const
28767cc0636SGreg Clayton {
28867cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
289754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
29067cc0636SGreg Clayton }
29167cc0636SGreg Clayton 
29267cc0636SGreg Clayton bool
29367cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
29467cc0636SGreg Clayton {
29567cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
29667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
29767cc0636SGreg Clayton }
29867cc0636SGreg Clayton 
29967cc0636SGreg Clayton uint32_t
30067cc0636SGreg Clayton Debugger::GetTerminalWidth () const
30167cc0636SGreg Clayton {
30267cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
303754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
30467cc0636SGreg Clayton }
30567cc0636SGreg Clayton 
30667cc0636SGreg Clayton bool
30767cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
30867cc0636SGreg Clayton {
30967cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
31067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
31167cc0636SGreg Clayton }
31267cc0636SGreg Clayton 
31367cc0636SGreg Clayton bool
31467cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
31567cc0636SGreg Clayton {
31667cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
317754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
31867cc0636SGreg Clayton }
31967cc0636SGreg Clayton 
32067cc0636SGreg Clayton bool
32167cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
32267cc0636SGreg Clayton {
32367cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
32467cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
32567cc0636SGreg Clayton }
32667cc0636SGreg Clayton 
327c3ce7f27SMichael Sartain bool
328c3ce7f27SMichael Sartain Debugger::GetUseColor () const
329c3ce7f27SMichael Sartain {
330c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
331c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
332c3ce7f27SMichael Sartain }
333c3ce7f27SMichael Sartain 
334c3ce7f27SMichael Sartain bool
335c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
336c3ce7f27SMichael Sartain {
337c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
338c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
339c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
340c3ce7f27SMichael Sartain     return ret;
341c3ce7f27SMichael Sartain }
342c3ce7f27SMichael Sartain 
34367cc0636SGreg Clayton uint32_t
34467cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
34567cc0636SGreg Clayton {
34667cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
347754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
34867cc0636SGreg Clayton }
34967cc0636SGreg Clayton 
35067cc0636SGreg Clayton Debugger::StopDisassemblyType
35167cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
35267cc0636SGreg Clayton {
35367cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
354754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
35567cc0636SGreg Clayton }
35667cc0636SGreg Clayton 
35767cc0636SGreg Clayton uint32_t
35867cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
35967cc0636SGreg Clayton {
36067cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
361754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
36267cc0636SGreg Clayton }
363e372b98dSGreg Clayton 
364553fad5cSEnrico Granata bool
36590a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
366553fad5cSEnrico Granata {
36790a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
368553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
369553fad5cSEnrico Granata 
370553fad5cSEnrico Granata }
371553fad5cSEnrico Granata 
3721b654882SGreg Clayton #pragma mark Debugger
3731b654882SGreg Clayton 
37467cc0636SGreg Clayton //const DebuggerPropertiesSP &
37567cc0636SGreg Clayton //Debugger::GetSettings() const
37667cc0636SGreg Clayton //{
37767cc0636SGreg Clayton //    return m_properties_sp;
37867cc0636SGreg Clayton //}
37967cc0636SGreg Clayton //
38099d0faf2SGreg Clayton 
3812f88aadfSCaroline Tice int
3822f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3832f88aadfSCaroline Tice {
3842f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3852f88aadfSCaroline Tice }
3862f88aadfSCaroline Tice 
38730fdc8d8SChris Lattner void
3885fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
38930fdc8d8SChris Lattner {
3905fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
391c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
392dbe54508SGreg Clayton         lldb_private::Initialize();
39399d0faf2SGreg Clayton }
39430fdc8d8SChris Lattner 
39530fdc8d8SChris Lattner void
39630fdc8d8SChris Lattner Debugger::Terminate ()
39730fdc8d8SChris Lattner {
3986611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3996611103cSGreg Clayton     {
40030fdc8d8SChris Lattner         g_shared_debugger_refcount--;
40130fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
40230fdc8d8SChris Lattner         {
403dbe54508SGreg Clayton             lldb_private::WillTerminate();
404dbe54508SGreg Clayton             lldb_private::Terminate();
4056760a517SCaroline Tice 
40699d0faf2SGreg Clayton             // Clear our master list of debugger objects
40799d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
40899d0faf2SGreg Clayton             GetDebuggerList().clear();
40930fdc8d8SChris Lattner         }
4106760a517SCaroline Tice     }
4116760a517SCaroline Tice }
41230fdc8d8SChris Lattner 
41320bd37f7SCaroline Tice void
41420bd37f7SCaroline Tice Debugger::SettingsInitialize ()
41520bd37f7SCaroline Tice {
4166920b52bSGreg Clayton     Target::SettingsInitialize ();
41720bd37f7SCaroline Tice }
41820bd37f7SCaroline Tice 
41920bd37f7SCaroline Tice void
42020bd37f7SCaroline Tice Debugger::SettingsTerminate ()
42120bd37f7SCaroline Tice {
4226920b52bSGreg Clayton     Target::SettingsTerminate ();
42320bd37f7SCaroline Tice }
42420bd37f7SCaroline Tice 
42521dfcd9dSEnrico Granata bool
426e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
42721dfcd9dSEnrico Granata {
4285fb8f797SGreg Clayton     if (g_load_plugin_callback)
429e743c782SEnrico Granata     {
43058a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
43158a559c0SZachary Turner         if (dynlib.isValid())
43221dfcd9dSEnrico Granata         {
43358a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
43421dfcd9dSEnrico Granata             return true;
43521dfcd9dSEnrico Granata         }
4365fb8f797SGreg Clayton     }
4375fb8f797SGreg Clayton     else
4385fb8f797SGreg Clayton     {
4395fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4405fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4415fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4425fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4435fb8f797SGreg Clayton     }
44421dfcd9dSEnrico Granata     return false;
44521dfcd9dSEnrico Granata }
44621dfcd9dSEnrico Granata 
44721dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
44821dfcd9dSEnrico Granata LoadPluginCallback
44921dfcd9dSEnrico Granata (
45021dfcd9dSEnrico Granata  void *baton,
45121dfcd9dSEnrico Granata  FileSpec::FileType file_type,
45221dfcd9dSEnrico Granata  const FileSpec &file_spec
45321dfcd9dSEnrico Granata  )
45421dfcd9dSEnrico Granata {
45521dfcd9dSEnrico Granata     Error error;
45621dfcd9dSEnrico Granata 
45721dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4583cf443ddSMichael Sartain     static ConstString g_solibext("so");
45921dfcd9dSEnrico Granata 
46021dfcd9dSEnrico Granata     if (!baton)
46121dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
46221dfcd9dSEnrico Granata 
46321dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
46421dfcd9dSEnrico Granata 
46521dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
46621dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
46721dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
46821dfcd9dSEnrico Granata     // file type information.
46921dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
47021dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
47121dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
47221dfcd9dSEnrico Granata     {
47321dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
47421dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
47521dfcd9dSEnrico Granata 
4763cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4773cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4783cf443ddSMichael Sartain         {
47921dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4803cf443ddSMichael Sartain         }
48121dfcd9dSEnrico Granata 
482e743c782SEnrico Granata         Error plugin_load_error;
483e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
48421dfcd9dSEnrico Granata 
48521dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
48621dfcd9dSEnrico Granata     }
48721dfcd9dSEnrico Granata 
48821dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
48921dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
49021dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
49121dfcd9dSEnrico Granata     {
49221dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
49321dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
4946a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
49521dfcd9dSEnrico Granata         // information.
49621dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
49721dfcd9dSEnrico Granata     }
49821dfcd9dSEnrico Granata 
49921dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
50021dfcd9dSEnrico Granata }
50121dfcd9dSEnrico Granata 
50221dfcd9dSEnrico Granata void
50321dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
50421dfcd9dSEnrico Granata {
50521dfcd9dSEnrico Granata     FileSpec dir_spec;
50621dfcd9dSEnrico Granata     const bool find_directories = true;
50721dfcd9dSEnrico Granata     const bool find_files = true;
50821dfcd9dSEnrico Granata     const bool find_other = true;
50921dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
51042ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
51121dfcd9dSEnrico Granata     {
51221dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
51321dfcd9dSEnrico Granata         {
51421dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
51521dfcd9dSEnrico Granata                                           find_directories,
51621dfcd9dSEnrico Granata                                           find_files,
51721dfcd9dSEnrico Granata                                           find_other,
51821dfcd9dSEnrico Granata                                           LoadPluginCallback,
51921dfcd9dSEnrico Granata                                           this);
52021dfcd9dSEnrico Granata         }
52121dfcd9dSEnrico Granata     }
52221dfcd9dSEnrico Granata 
52342ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, 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     }
535e8cd0c98SGreg Clayton 
536e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
53721dfcd9dSEnrico Granata }
53821dfcd9dSEnrico Granata 
5396611103cSGreg Clayton DebuggerSP
540228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5416611103cSGreg Clayton {
542228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
543c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5446611103cSGreg Clayton     {
5456611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5466611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5476611103cSGreg Clayton     }
54821dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5496611103cSGreg Clayton     return debugger_sp;
5506611103cSGreg Clayton }
5516611103cSGreg Clayton 
552e02657b1SCaroline Tice void
5534d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
554e02657b1SCaroline Tice {
555e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
556e02657b1SCaroline Tice         return;
557e02657b1SCaroline Tice 
5588314c525SJim Ingham     debugger_sp->Clear();
5598314c525SJim Ingham 
560c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
561c15f55e2SGreg Clayton     {
562e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
563e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
564e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
565e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
566e02657b1SCaroline Tice         {
567e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
568e02657b1SCaroline Tice             {
569e02657b1SCaroline Tice                 debugger_list.erase (pos);
570e02657b1SCaroline Tice                 return;
571e02657b1SCaroline Tice             }
572e02657b1SCaroline Tice         }
573e02657b1SCaroline Tice     }
574c15f55e2SGreg Clayton }
575e02657b1SCaroline Tice 
5764d122c40SGreg Clayton DebuggerSP
5773df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5783df9a8dfSCaroline Tice {
5794d122c40SGreg Clayton     DebuggerSP debugger_sp;
5806920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5816920b52bSGreg Clayton     {
5826920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5836920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5846920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5856920b52bSGreg Clayton 
5866920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5876920b52bSGreg Clayton         {
5886920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5896920b52bSGreg Clayton             {
5906920b52bSGreg Clayton                 debugger_sp = *pos;
5916920b52bSGreg Clayton                 break;
5926920b52bSGreg Clayton             }
5936920b52bSGreg Clayton         }
5946920b52bSGreg Clayton     }
5953df9a8dfSCaroline Tice     return debugger_sp;
5963df9a8dfSCaroline Tice }
5976611103cSGreg Clayton 
5986611103cSGreg Clayton TargetSP
5996611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6006611103cSGreg Clayton {
6014d122c40SGreg Clayton     TargetSP target_sp;
602c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
603c15f55e2SGreg Clayton     {
6046611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6056611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6066611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6076611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6086611103cSGreg Clayton         {
6096611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6106611103cSGreg Clayton             if (target_sp)
6116611103cSGreg Clayton                 break;
6126611103cSGreg Clayton         }
613c15f55e2SGreg Clayton     }
6146611103cSGreg Clayton     return target_sp;
6156611103cSGreg Clayton }
6166611103cSGreg Clayton 
617e4e45924SGreg Clayton TargetSP
618e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
619e4e45924SGreg Clayton {
620e4e45924SGreg Clayton     TargetSP target_sp;
621c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
622c15f55e2SGreg Clayton     {
623e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
624e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
625e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
626e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
627e4e45924SGreg Clayton         {
628e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
629e4e45924SGreg Clayton             if (target_sp)
630e4e45924SGreg Clayton                 break;
631e4e45924SGreg Clayton         }
632c15f55e2SGreg Clayton     }
633e4e45924SGreg Clayton     return target_sp;
634e4e45924SGreg Clayton }
635e4e45924SGreg Clayton 
636e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
637e6481c7eSJason Molenda     UserID(g_unique_id++),
638e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
639e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
640e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
641e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
642e6481c7eSJason Molenda     m_terminal_state(),
643e6481c7eSJason Molenda     m_target_list(*this),
644e6481c7eSJason Molenda     m_platform_list(),
645e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
646e6481c7eSJason Molenda     m_source_manager_ap(),
647e6481c7eSJason Molenda     m_source_file_cache(),
648e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
649e6481c7eSJason Molenda     m_input_reader_stack(),
650e6481c7eSJason Molenda     m_instance_name(),
651e6481c7eSJason Molenda     m_loaded_plugins()
65230fdc8d8SChris Lattner {
65367cc0636SGreg Clayton     char instance_cstr[256];
65467cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
65567cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
656228063cdSJim Ingham     if (log_callback)
657228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6586611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
659ded470d3SGreg Clayton     // Always add our default platform to the platform list
660615eb7e6SGreg Clayton     PlatformSP default_platform_sp (Platform::GetHostPlatform());
661ded470d3SGreg Clayton     assert (default_platform_sp.get());
662ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
66367cc0636SGreg Clayton 
664754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
66567cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
66667cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
66767cc0636SGreg Clayton                                      true,
66867cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
669754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
670754a9369SGreg Clayton     {
671754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
672754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
673754a9369SGreg Clayton                                          true,
674754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
675754a9369SGreg Clayton     }
67667cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
67767cc0636SGreg Clayton     term_width->SetMinimumValue(10);
67867cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
679c3ce7f27SMichael Sartain 
680c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
681c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
682c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
683c3ce7f27SMichael Sartain         SetUseColor (false);
68430fdc8d8SChris Lattner }
68530fdc8d8SChris Lattner 
68630fdc8d8SChris Lattner Debugger::~Debugger ()
68730fdc8d8SChris Lattner {
6888314c525SJim Ingham     Clear();
6898314c525SJim Ingham }
6908314c525SJim Ingham 
6918314c525SJim Ingham void
6928314c525SJim Ingham Debugger::Clear()
6938314c525SJim Ingham {
69444d93782SGreg Clayton     ClearIOHandlers();
69544d93782SGreg Clayton     StopIOHandlerThread();
69644d93782SGreg Clayton     StopEventHandlerThread();
6971ed54f50SGreg Clayton     m_listener.Clear();
6986611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6996611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7006611103cSGreg Clayton     {
701ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
702ccbc08e6SGreg Clayton         if (target_sp)
703ccbc08e6SGreg Clayton         {
704ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7056611103cSGreg Clayton             if (process_sp)
7061fd07059SJim Ingham                 process_sp->Finalize();
707ccbc08e6SGreg Clayton             target_sp->Destroy();
7086611103cSGreg Clayton         }
70930fdc8d8SChris Lattner     }
7104bddaeb5SJim Ingham     BroadcasterManager::Clear ();
71130fdc8d8SChris Lattner 
7120d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7130d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
714c5917d9aSJim Ingham     m_terminal_state.Clear();
71544d93782SGreg Clayton     if (m_input_file_sp)
71644d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7170c4129f2SGreg Clayton 
7180c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7198314c525SJim Ingham }
72030fdc8d8SChris Lattner 
72130fdc8d8SChris Lattner bool
722fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
723fc3f027dSGreg Clayton {
72444d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
72544d93782SGreg Clayton     return false;
726fc3f027dSGreg Clayton }
727fc3f027dSGreg Clayton 
728fc3f027dSGreg Clayton void
729fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
730fc3f027dSGreg Clayton {
73144d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
732fc3f027dSGreg Clayton }
733fc3f027dSGreg Clayton 
734fc3f027dSGreg Clayton bool
73530fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
73630fdc8d8SChris Lattner {
7376611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
73830fdc8d8SChris Lattner }
73930fdc8d8SChris Lattner 
74030fdc8d8SChris Lattner void
74130fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
74230fdc8d8SChris Lattner {
7436611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
74430fdc8d8SChris Lattner }
74530fdc8d8SChris Lattner 
74630fdc8d8SChris Lattner 
74730fdc8d8SChris Lattner void
74830fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
74930fdc8d8SChris Lattner {
75044d93782SGreg Clayton     if (m_input_file_sp)
75144d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
75244d93782SGreg Clayton     else
75344d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
75444d93782SGreg Clayton 
75544d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
75651b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
75751b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
75830fdc8d8SChris Lattner 
759c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
760c5917d9aSJim Ingham     SaveInputTerminalState ();
76130fdc8d8SChris Lattner }
76230fdc8d8SChris Lattner 
76330fdc8d8SChris Lattner void
76430fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
76530fdc8d8SChris Lattner {
76644d93782SGreg Clayton     if (m_output_file_sp)
76744d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
76844d93782SGreg Clayton     else
76944d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
77044d93782SGreg Clayton 
77144d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
77251b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
77351b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7742f88aadfSCaroline Tice 
775b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
776b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
777b588726eSEnrico Granata     const bool can_create = false;
778b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
779b588726eSEnrico Granata     if (script_interpreter)
780b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
78130fdc8d8SChris Lattner }
78230fdc8d8SChris Lattner 
78330fdc8d8SChris Lattner void
78430fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
78530fdc8d8SChris Lattner {
78644d93782SGreg Clayton     if (m_error_file_sp)
78744d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
78844d93782SGreg Clayton     else
78944d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
79044d93782SGreg Clayton 
79144d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
79251b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
79351b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
79430fdc8d8SChris Lattner }
79530fdc8d8SChris Lattner 
796c5917d9aSJim Ingham void
797c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
798c5917d9aSJim Ingham {
79944d93782SGreg Clayton     if (m_input_file_sp)
80044d93782SGreg Clayton     {
80144d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
802c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
803c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
804c5917d9aSJim Ingham     }
80544d93782SGreg Clayton }
806c5917d9aSJim Ingham 
807c5917d9aSJim Ingham void
808c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
809c5917d9aSJim Ingham {
810c5917d9aSJim Ingham     m_terminal_state.Restore();
811c5917d9aSJim Ingham }
812c5917d9aSJim Ingham 
81330fdc8d8SChris Lattner ExecutionContext
8142976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
81530fdc8d8SChris Lattner {
81630fdc8d8SChris Lattner     ExecutionContext exe_ctx;
817c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
818c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
81930fdc8d8SChris Lattner 
82030fdc8d8SChris Lattner     if (target_sp)
82130fdc8d8SChris Lattner     {
822c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
823c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
824c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
82530fdc8d8SChris Lattner         {
826c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
827c14ee32dSGreg Clayton             if (thread_sp)
82830fdc8d8SChris Lattner             {
829c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
830c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
831c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
832c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
83330fdc8d8SChris Lattner             }
83430fdc8d8SChris Lattner         }
83530fdc8d8SChris Lattner     }
83630fdc8d8SChris Lattner     return exe_ctx;
83730fdc8d8SChris Lattner }
83830fdc8d8SChris Lattner 
83930fdc8d8SChris Lattner void
840efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
841efed6131SCaroline Tice {
84244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
84344d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
844efed6131SCaroline Tice     if (reader_sp)
84544d93782SGreg Clayton         reader_sp->Interrupt();
846efed6131SCaroline Tice }
847efed6131SCaroline Tice 
848efed6131SCaroline Tice void
849efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
850efed6131SCaroline Tice {
85144d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
85244d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
853efed6131SCaroline Tice     if (reader_sp)
85444d93782SGreg Clayton         reader_sp->GotEOF();
855efed6131SCaroline Tice }
856efed6131SCaroline Tice 
857efed6131SCaroline Tice void
85844d93782SGreg Clayton Debugger::ClearIOHandlers ()
8593d6086f6SCaroline Tice {
860b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
86144d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
862d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8633d6086f6SCaroline Tice     {
86444d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8653d6086f6SCaroline Tice         if (reader_sp)
8663d6086f6SCaroline Tice         {
86744d93782SGreg Clayton             m_input_reader_stack.Pop();
8683d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
869e68f5d6bSGreg Clayton             reader_sp->Cancel();
8703d6086f6SCaroline Tice         }
8713d6086f6SCaroline Tice     }
8723d6086f6SCaroline Tice }
8733d6086f6SCaroline Tice 
8743d6086f6SCaroline Tice void
87544d93782SGreg Clayton Debugger::ExecuteIOHanders()
876969ed3d1SCaroline Tice {
87744d93782SGreg Clayton 
87844d93782SGreg Clayton     while (1)
879969ed3d1SCaroline Tice     {
88044d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
88130fdc8d8SChris Lattner         if (!reader_sp)
88230fdc8d8SChris Lattner             break;
88330fdc8d8SChris Lattner 
88444d93782SGreg Clayton         reader_sp->Activate();
88544d93782SGreg Clayton         reader_sp->Run();
88644d93782SGreg Clayton         reader_sp->Deactivate();
88744d93782SGreg Clayton 
88844d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
88944d93782SGreg Clayton         while (1)
89030fdc8d8SChris Lattner         {
89144d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
89244d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
89344d93782SGreg Clayton                 m_input_reader_stack.Pop();
89430fdc8d8SChris Lattner             else
89530fdc8d8SChris Lattner                 break;
89630fdc8d8SChris Lattner         }
89730fdc8d8SChris Lattner     }
89844d93782SGreg Clayton     ClearIOHandlers();
89944d93782SGreg Clayton }
90030fdc8d8SChris Lattner 
90144d93782SGreg Clayton bool
90244d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
90344d93782SGreg Clayton {
90444d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
90544d93782SGreg Clayton }
90630fdc8d8SChris Lattner 
90744d93782SGreg Clayton 
90844d93782SGreg Clayton ConstString
90944d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
91044d93782SGreg Clayton {
91144d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
91230fdc8d8SChris Lattner }
91330fdc8d8SChris Lattner 
91430fdc8d8SChris Lattner void
91544d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
91644d93782SGreg Clayton {
91744d93782SGreg Clayton     PushIOHandler (reader_sp);
918577508dfSGreg Clayton 
919577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
920577508dfSGreg Clayton     while (top_reader_sp)
921577508dfSGreg Clayton     {
922577508dfSGreg Clayton         top_reader_sp->Activate();
923577508dfSGreg Clayton         top_reader_sp->Run();
924577508dfSGreg Clayton         top_reader_sp->Deactivate();
925577508dfSGreg Clayton 
926577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
927577508dfSGreg Clayton         {
928577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
929577508dfSGreg Clayton                 break;
930577508dfSGreg Clayton         }
931577508dfSGreg Clayton 
932577508dfSGreg Clayton         while (1)
933577508dfSGreg Clayton         {
934577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
935577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
936577508dfSGreg Clayton                 m_input_reader_stack.Pop();
937577508dfSGreg Clayton             else
938577508dfSGreg Clayton                 break;
939577508dfSGreg Clayton         }
940577508dfSGreg Clayton     }
94144d93782SGreg Clayton }
94244d93782SGreg Clayton 
94344d93782SGreg Clayton void
94444d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
94544d93782SGreg Clayton {
94644d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
94744d93782SGreg Clayton     // This function is called when one ore more of the streams
94844d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
94944d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
95044d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
95144d93782SGreg Clayton 
95244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
95344d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
95444d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
95544d93782SGreg Clayton     if (!in)
95644d93782SGreg Clayton     {
95744d93782SGreg Clayton         if (top_reader_sp)
95844d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
95944d93782SGreg Clayton         else
96044d93782SGreg Clayton             in = GetInputFile();
96144d93782SGreg Clayton 
96244d93782SGreg Clayton         // If there is nothing, use stdin
96344d93782SGreg Clayton         if (!in)
96444d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
96544d93782SGreg Clayton     }
96644d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
96744d93782SGreg Clayton     if (!out)
96844d93782SGreg Clayton     {
96944d93782SGreg Clayton         if (top_reader_sp)
97044d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
97144d93782SGreg Clayton         else
97244d93782SGreg Clayton             out = GetOutputFile();
97344d93782SGreg Clayton 
97444d93782SGreg Clayton         // If there is nothing, use stdout
97544d93782SGreg Clayton         if (!out)
97644d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
97744d93782SGreg Clayton     }
97844d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
97944d93782SGreg Clayton     if (!err)
98044d93782SGreg Clayton     {
98144d93782SGreg Clayton         if (top_reader_sp)
98244d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
98344d93782SGreg Clayton         else
98444d93782SGreg Clayton             err = GetErrorFile();
98544d93782SGreg Clayton 
98644d93782SGreg Clayton         // If there is nothing, use stderr
98744d93782SGreg Clayton         if (!err)
98844d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
98944d93782SGreg Clayton 
99044d93782SGreg Clayton     }
99144d93782SGreg Clayton }
99244d93782SGreg Clayton 
99344d93782SGreg Clayton void
99444d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
99530fdc8d8SChris Lattner {
99630fdc8d8SChris Lattner     if (!reader_sp)
99730fdc8d8SChris Lattner         return;
998b44880caSCaroline Tice 
99944d93782SGreg Clayton     // Got the current top input reader...
100044d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1001b44880caSCaroline Tice 
1002b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
1003b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
1004b4874f1aSGreg Clayton     {
100544d93782SGreg Clayton         // Push our new input reader
1006d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
100744d93782SGreg Clayton 
100844d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
100944d93782SGreg Clayton         // and let this new input reader take over
101044d93782SGreg Clayton         if (top_reader_sp)
101144d93782SGreg Clayton             top_reader_sp->Deactivate();
101230fdc8d8SChris Lattner     }
1013b4874f1aSGreg Clayton }
101430fdc8d8SChris Lattner 
101530fdc8d8SChris Lattner bool
101644d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
101730fdc8d8SChris Lattner {
101830fdc8d8SChris Lattner     bool result = false;
101930fdc8d8SChris Lattner 
102044d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
102144d93782SGreg Clayton 
102230fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10236a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
1024d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
102530fdc8d8SChris Lattner     {
102644d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
102730fdc8d8SChris Lattner 
102830fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
102930fdc8d8SChris Lattner         {
103044d93782SGreg Clayton             reader_sp->Deactivate();
1031b4874f1aSGreg Clayton             reader_sp->Cancel();
1032d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
103330fdc8d8SChris Lattner 
1034d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
103530fdc8d8SChris Lattner             if (reader_sp)
103644d93782SGreg Clayton                 reader_sp->Activate();
103744d93782SGreg Clayton 
103844d93782SGreg Clayton             result = true;
103930fdc8d8SChris Lattner         }
104030fdc8d8SChris Lattner     }
104130fdc8d8SChris Lattner     return result;
104230fdc8d8SChris Lattner }
104330fdc8d8SChris Lattner 
104430fdc8d8SChris Lattner bool
104544d93782SGreg Clayton Debugger::HideTopIOHandler()
104630fdc8d8SChris Lattner {
104744d93782SGreg Clayton     Mutex::Locker locker;
104830fdc8d8SChris Lattner 
104944d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
105030fdc8d8SChris Lattner     {
105144d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
105244d93782SGreg Clayton         if (reader_sp)
105344d93782SGreg Clayton             reader_sp->Hide();
105444d93782SGreg Clayton         return true;
105530fdc8d8SChris Lattner     }
105644d93782SGreg Clayton     return false;
105730fdc8d8SChris Lattner }
105830fdc8d8SChris Lattner 
105930fdc8d8SChris Lattner void
106044d93782SGreg Clayton Debugger::RefreshTopIOHandler()
106130fdc8d8SChris Lattner {
106244d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
106344d93782SGreg Clayton     if (reader_sp)
106444d93782SGreg Clayton         reader_sp->Refresh();
106530fdc8d8SChris Lattner }
106644d93782SGreg Clayton 
10676611103cSGreg Clayton 
10685b52f0c7SJim Ingham StreamSP
10695b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10705b52f0c7SJim Ingham {
10715b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10725b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10735b52f0c7SJim Ingham }
10745b52f0c7SJim Ingham 
10755b52f0c7SJim Ingham StreamSP
10765b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10775b52f0c7SJim Ingham {
10785b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10795b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10805b52f0c7SJim Ingham }
10815b52f0c7SJim Ingham 
1082c7bece56SGreg Clayton size_t
1083061858ceSEnrico Granata Debugger::GetNumDebuggers()
1084061858ceSEnrico Granata {
1085c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1086c15f55e2SGreg Clayton     {
1087061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1088061858ceSEnrico Granata         return GetDebuggerList().size();
1089061858ceSEnrico Granata     }
1090c15f55e2SGreg Clayton     return 0;
1091c15f55e2SGreg Clayton }
1092061858ceSEnrico Granata 
1093061858ceSEnrico Granata lldb::DebuggerSP
1094c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1095061858ceSEnrico Granata {
1096061858ceSEnrico Granata     DebuggerSP debugger_sp;
1097061858ceSEnrico Granata 
1098c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1099c15f55e2SGreg Clayton     {
1100061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1101061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1102061858ceSEnrico Granata 
1103061858ceSEnrico Granata         if (index < debugger_list.size())
1104061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1105c15f55e2SGreg Clayton     }
1106061858ceSEnrico Granata 
1107061858ceSEnrico Granata     return debugger_sp;
1108061858ceSEnrico Granata }
1109061858ceSEnrico Granata 
1110ebc1bb27SCaroline Tice DebuggerSP
1111ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1112ebc1bb27SCaroline Tice {
11134d122c40SGreg Clayton     DebuggerSP debugger_sp;
1114ebc1bb27SCaroline Tice 
1115c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1116c15f55e2SGreg Clayton     {
1117ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1118ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1119ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1120ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1121ebc1bb27SCaroline Tice         {
1122ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1123ebc1bb27SCaroline Tice             {
1124ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1125ebc1bb27SCaroline Tice                 break;
1126ebc1bb27SCaroline Tice             }
1127ebc1bb27SCaroline Tice         }
1128c15f55e2SGreg Clayton     }
1129ebc1bb27SCaroline Tice     return debugger_sp;
1130ebc1bb27SCaroline Tice }
11313df9a8dfSCaroline Tice 
11322643b905SSaleem Abdulrasool #if 0
11331b654882SGreg Clayton static void
1134b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11351b654882SGreg Clayton {
11361b654882SGreg Clayton     if (frame == NULL)
11371b654882SGreg Clayton         return;
11381b654882SGreg Clayton 
11391b654882SGreg Clayton     StreamString s;
11401b654882SGreg Clayton     const char *prompt_format =
11411b654882SGreg Clayton     "{addr = '${addr}'\n}"
1142aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1143aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
11441b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11451b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11461b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11471b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11481b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11491b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11501b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11511b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11521b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11531b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11541b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11551b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11561b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11571b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11581b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11591b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11601b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11611b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11621b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11631b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11641b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11651b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11661b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11671b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11681b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11691b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11701b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1171aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1172aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
11731b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1174aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1175ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11761b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1177aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
11781b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11791b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11801b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11811b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11821b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11831b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11841b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11851b654882SGreg Clayton ;
11861b654882SGreg Clayton 
11871b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11881b654882SGreg Clayton     ExecutionContext exe_ctx;
11890603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1190c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
11911b654882SGreg Clayton     {
11921b654882SGreg Clayton         printf("%s\n", s.GetData());
11931b654882SGreg Clayton     }
11941b654882SGreg Clayton     else
11951b654882SGreg Clayton     {
11961b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11971b654882SGreg Clayton     }
11981b654882SGreg Clayton }
11992643b905SSaleem Abdulrasool #endif
12001b654882SGreg Clayton 
12019fc1944eSEnrico Granata static bool
12029fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
12039fc1944eSEnrico Granata                       const char* var_name_end,
12049fc1944eSEnrico Granata                       const char** var_name_final,
12059fc1944eSEnrico Granata                       const char** percent_position,
12064d122c40SGreg Clayton                       Format* custom_format,
12079fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
12089fc1944eSEnrico Granata {
12095160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12109fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
12119fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1212e992a089SEnrico Granata     {
1213e992a089SEnrico Granata         if (log)
1214d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
12159fc1944eSEnrico Granata         *var_name_final = var_name_end;
1216e992a089SEnrico Granata     }
12179fc1944eSEnrico Granata     else
12189fc1944eSEnrico Granata     {
12199fc1944eSEnrico Granata         *var_name_final = *percent_position;
122036aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1221e992a089SEnrico Granata         if (log)
122268ae4117SEnrico Granata             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
122336aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
12249fc1944eSEnrico Granata                                                   true,
12259fc1944eSEnrico Granata                                                   *custom_format) )
12269fc1944eSEnrico Granata         {
1227e992a089SEnrico Granata             if (log)
122868ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
122936aa5ae6SEnrico Granata 
123036aa5ae6SEnrico Granata             switch (format_name.front())
123136aa5ae6SEnrico Granata             {
123236aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
123386cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
123436aa5ae6SEnrico Granata                     break;
123536aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
123686cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
123736aa5ae6SEnrico Granata                     break;
123836aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
123986cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
124036aa5ae6SEnrico Granata                     break;
124136aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
124286cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
124336aa5ae6SEnrico Granata                     break;
124436aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
124586cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
124636aa5ae6SEnrico Granata                     break;
124736aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
124886cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
124936aa5ae6SEnrico Granata                     break;
12502c75f11eSEnrico Granata                 case 'N': // if this is a 'N', print the name
12512c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
12522c75f11eSEnrico Granata                     break;
12532c75f11eSEnrico Granata                 case '>': // if this is a '>', print the name
12542c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
12552c75f11eSEnrico Granata                     break;
125636aa5ae6SEnrico Granata                 default:
12575c42d8a8SJim Ingham                     if (log)
125836aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
125936aa5ae6SEnrico Granata                     break;
126036aa5ae6SEnrico Granata             }
12619fc1944eSEnrico Granata         }
12629fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
12639fc1944eSEnrico Granata         else
1264e992a089SEnrico Granata         {
1265e992a089SEnrico Granata             if (log)
126668ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
126786cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1268e992a089SEnrico Granata         }
12699fc1944eSEnrico Granata     }
1270e992a089SEnrico Granata     if (log)
127168ae4117SEnrico Granata         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1272e992a089SEnrico Granata                     *custom_format,
1273e992a089SEnrico Granata                     *val_obj_display);
12749fc1944eSEnrico Granata     return true;
12759fc1944eSEnrico Granata }
12769fc1944eSEnrico Granata 
12779fc1944eSEnrico Granata static bool
12789fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
12799fc1944eSEnrico Granata                     const char* var_name_end,
12809fc1944eSEnrico Granata                     const char* var_name_final,
12819fc1944eSEnrico Granata                     const char** open_bracket_position,
12829fc1944eSEnrico Granata                     const char** separator_position,
12839fc1944eSEnrico Granata                     const char** close_bracket_position,
12849fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12859fc1944eSEnrico Granata                     int64_t* index_lower,
12869fc1944eSEnrico Granata                     int64_t* index_higher)
12879fc1944eSEnrico Granata {
12885160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12899fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12909fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12919fc1944eSEnrico Granata     {
12929fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12939fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12949fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12959fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12969fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12979fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12989fc1944eSEnrico Granata         {
1299e992a089SEnrico Granata             if (log)
1300d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
13019fc1944eSEnrico Granata             *index_lower = 0;
13029fc1944eSEnrico Granata         }
13039fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
13049fc1944eSEnrico Granata         {
13059fc1944eSEnrico Granata             char *end = NULL;
13069fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13079fc1944eSEnrico Granata             *index_higher = *index_lower;
1308e992a089SEnrico Granata             if (log)
1309d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
13109fc1944eSEnrico Granata         }
13119fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
13129fc1944eSEnrico Granata         {
13139fc1944eSEnrico Granata             char *end = NULL;
13149fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13159fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1316e992a089SEnrico Granata             if (log)
1317d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
13189fc1944eSEnrico Granata         }
13199fc1944eSEnrico Granata         else
1320e992a089SEnrico Granata         {
1321e992a089SEnrico Granata             if (log)
1322d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
13239fc1944eSEnrico Granata             return false;
1324e992a089SEnrico Granata         }
13259fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
13269fc1944eSEnrico Granata         {
1327e992a089SEnrico Granata             if (log)
1328d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1329c7bece56SGreg Clayton             int64_t temp = *index_lower;
13309fc1944eSEnrico Granata             *index_lower = *index_higher;
13319fc1944eSEnrico Granata             *index_higher = temp;
13329fc1944eSEnrico Granata         }
13339fc1944eSEnrico Granata     }
1334e992a089SEnrico Granata     else if (log)
1335d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
13369fc1944eSEnrico Granata     return true;
13379fc1944eSEnrico Granata }
13389fc1944eSEnrico Granata 
13390769b2b1SMichael Sartain template <typename T>
13400769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
13410769b2b1SMichael Sartain {
13420769b2b1SMichael Sartain     if (script_interpreter)
13430769b2b1SMichael Sartain     {
13440769b2b1SMichael Sartain         Error script_error;
13450769b2b1SMichael Sartain         std::string script_output;
13460769b2b1SMichael Sartain 
13470769b2b1SMichael Sartain         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
13480769b2b1SMichael Sartain         {
13490769b2b1SMichael Sartain             s.Printf("%s", script_output.c_str());
13500769b2b1SMichael Sartain             return true;
13510769b2b1SMichael Sartain         }
13520769b2b1SMichael Sartain         else
13530769b2b1SMichael Sartain         {
13540769b2b1SMichael Sartain             s.Printf("<error: %s>",script_error.AsCString());
13550769b2b1SMichael Sartain         }
13560769b2b1SMichael Sartain     }
13570769b2b1SMichael Sartain     return false;
13580769b2b1SMichael Sartain }
13590769b2b1SMichael Sartain 
13609fc1944eSEnrico Granata static ValueObjectSP
1361c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1362c7bece56SGreg Clayton                          size_t index,
1363b57e4a1bSJason Molenda                          StackFrame* frame,
1364fc7a7f3bSEnrico Granata                          bool deref_pointer)
13659fc1944eSEnrico Granata {
13665160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1367fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1368599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1369599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1370e992a089SEnrico Granata     if (log)
1371599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1372fc7a7f3bSEnrico Granata     const char* first_unparsed;
1373fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1374fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1375fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
137686cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1377599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1378fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1379fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1380fc7a7f3bSEnrico Granata                                                           &final_value_type,
1381fc7a7f3bSEnrico Granata                                                           options,
1382fc7a7f3bSEnrico Granata                                                           &what_next);
1383fc7a7f3bSEnrico Granata     if (!item)
1384fc7a7f3bSEnrico Granata     {
1385e992a089SEnrico Granata         if (log)
1386d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1387e992a089SEnrico Granata                " final_value_type %d",
1388fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1389fc7a7f3bSEnrico Granata     }
13909fc1944eSEnrico Granata     else
13919fc1944eSEnrico Granata     {
1392e992a089SEnrico Granata         if (log)
1393d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1394e992a089SEnrico Granata                " final_value_type %d",
1395fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
13969fc1944eSEnrico Granata     }
13979fc1944eSEnrico Granata     return item;
13989fc1944eSEnrico Granata }
13999fc1944eSEnrico Granata 
14000769b2b1SMichael Sartain static inline bool
14010769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var)
14020769b2b1SMichael Sartain {
14030769b2b1SMichael Sartain     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
14040769b2b1SMichael Sartain }
14050769b2b1SMichael Sartain 
14060769b2b1SMichael Sartain static bool
14070769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
14080769b2b1SMichael Sartain     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
14090769b2b1SMichael Sartain {
14100769b2b1SMichael Sartain     int var_len = strlen(var);
14110769b2b1SMichael Sartain     if (::strncmp (var_name_begin, var, var_len) == 0)
14120769b2b1SMichael Sartain     {
14130769b2b1SMichael Sartain         var_name_begin += var_len;
14140769b2b1SMichael Sartain         if (*var_name_begin == '}')
14150769b2b1SMichael Sartain         {
14160769b2b1SMichael Sartain             format = default_format;
14170769b2b1SMichael Sartain             return true;
14180769b2b1SMichael Sartain         }
14190769b2b1SMichael Sartain         else if (*var_name_begin == '%')
14200769b2b1SMichael Sartain         {
14210769b2b1SMichael Sartain             // Allow format specifiers: x|X|u with optional width specifiers.
14220769b2b1SMichael Sartain             //   ${thread.id%x}    ; hex
14230769b2b1SMichael Sartain             //   ${thread.id%X}    ; uppercase hex
14240769b2b1SMichael Sartain             //   ${thread.id%u}    ; unsigned decimal
14250769b2b1SMichael Sartain             //   ${thread.id%8.8X} ; width.precision + specifier
14260769b2b1SMichael Sartain             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
14270769b2b1SMichael Sartain             int dot_count = 0;
14280769b2b1SMichael Sartain             const char *specifier = NULL;
14290769b2b1SMichael Sartain             int width_precision_length = 0;
14300769b2b1SMichael Sartain             const char *width_precision = ++var_name_begin;
14310769b2b1SMichael Sartain             while (isdigit(*var_name_begin) || *var_name_begin == '.')
14320769b2b1SMichael Sartain             {
14330769b2b1SMichael Sartain                 dot_count += (*var_name_begin == '.');
14340769b2b1SMichael Sartain                 if (dot_count > 1)
14350769b2b1SMichael Sartain                     break;
14360769b2b1SMichael Sartain                 var_name_begin++;
14370769b2b1SMichael Sartain                 width_precision_length++;
14380769b2b1SMichael Sartain             }
14390769b2b1SMichael Sartain 
14400769b2b1SMichael Sartain             if (IsToken (var_name_begin, "tid}"))
14410769b2b1SMichael Sartain             {
14420769b2b1SMichael Sartain                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
14430769b2b1SMichael Sartain                 if (target)
14440769b2b1SMichael Sartain                 {
14450769b2b1SMichael Sartain                     ArchSpec arch (target->GetArchitecture ());
14460769b2b1SMichael Sartain                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
14470769b2b1SMichael Sartain                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
14480769b2b1SMichael Sartain                         specifier = PRIu64;
14490769b2b1SMichael Sartain                 }
14500769b2b1SMichael Sartain                 if (!specifier)
14510769b2b1SMichael Sartain                 {
14520769b2b1SMichael Sartain                     format = default_format;
14530769b2b1SMichael Sartain                     return true;
14540769b2b1SMichael Sartain                 }
14550769b2b1SMichael Sartain             }
14560769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "x}"))
14570769b2b1SMichael Sartain                 specifier = PRIx64;
14580769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "X}"))
14590769b2b1SMichael Sartain                 specifier = PRIX64;
14600769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "u}"))
14610769b2b1SMichael Sartain                 specifier = PRIu64;
14620769b2b1SMichael Sartain 
14630769b2b1SMichael Sartain             if (specifier)
14640769b2b1SMichael Sartain             {
14650769b2b1SMichael Sartain                 format = "%";
14660769b2b1SMichael Sartain                 if (width_precision_length)
14670769b2b1SMichael Sartain                     format += std::string(width_precision, width_precision_length);
14680769b2b1SMichael Sartain                 format += specifier;
14690769b2b1SMichael Sartain                 return true;
14700769b2b1SMichael Sartain             }
14710769b2b1SMichael Sartain         }
14720769b2b1SMichael Sartain     }
14730769b2b1SMichael Sartain     return false;
14740769b2b1SMichael Sartain }
14750769b2b1SMichael Sartain 
1476705b1809SJason Molenda // Find information for the "thread.info.*" specifiers in a format string
1477705b1809SJason Molenda static bool
1478705b1809SJason Molenda FormatThreadExtendedInfoRecurse
1479705b1809SJason Molenda (
1480705b1809SJason Molenda     const char *var_name_begin,
1481705b1809SJason Molenda     StructuredData::ObjectSP thread_info_dictionary,
1482705b1809SJason Molenda     const SymbolContext *sc,
1483705b1809SJason Molenda     const ExecutionContext *exe_ctx,
1484705b1809SJason Molenda     Stream &s
1485705b1809SJason Molenda )
1486705b1809SJason Molenda {
1487705b1809SJason Molenda     bool var_success = false;
1488705b1809SJason Molenda     std::string token_format;
1489705b1809SJason Molenda 
1490705b1809SJason Molenda     llvm::StringRef var_name(var_name_begin);
1491705b1809SJason Molenda     size_t percent_idx = var_name.find('%');
1492705b1809SJason Molenda     size_t close_curly_idx = var_name.find('}');
1493705b1809SJason Molenda     llvm::StringRef path = var_name;
1494705b1809SJason Molenda     llvm::StringRef formatter = var_name;
1495705b1809SJason Molenda 
1496705b1809SJason Molenda     // 'path' will be the dot separated list of objects to transverse up until we hit
1497705b1809SJason Molenda     // a close curly brace, a percent sign, or an end of string.
1498705b1809SJason Molenda     if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
1499705b1809SJason Molenda     {
1500705b1809SJason Molenda         if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
1501705b1809SJason Molenda         {
1502705b1809SJason Molenda             if (percent_idx < close_curly_idx)
1503705b1809SJason Molenda             {
1504705b1809SJason Molenda                 path = var_name.slice(0, percent_idx);
1505705b1809SJason Molenda                 formatter = var_name.substr (percent_idx);
1506705b1809SJason Molenda             }
1507705b1809SJason Molenda             else
1508705b1809SJason Molenda             {
1509705b1809SJason Molenda                 path = var_name.slice(0, close_curly_idx);
1510705b1809SJason Molenda                 formatter = var_name.substr (close_curly_idx);
1511705b1809SJason Molenda             }
1512705b1809SJason Molenda         }
1513705b1809SJason Molenda         else if (percent_idx != llvm::StringRef::npos)
1514705b1809SJason Molenda         {
1515705b1809SJason Molenda             path = var_name.slice(0, percent_idx);
1516705b1809SJason Molenda             formatter = var_name.substr (percent_idx);
1517705b1809SJason Molenda         }
1518705b1809SJason Molenda         else if (close_curly_idx != llvm::StringRef::npos)
1519705b1809SJason Molenda         {
1520705b1809SJason Molenda             path = var_name.slice(0, close_curly_idx);
1521705b1809SJason Molenda             formatter = var_name.substr (close_curly_idx);
1522705b1809SJason Molenda         }
1523705b1809SJason Molenda     }
1524705b1809SJason Molenda 
1525705b1809SJason Molenda     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1526705b1809SJason Molenda 
1527705b1809SJason Molenda     if (value.get())
1528705b1809SJason Molenda     {
1529705b1809SJason Molenda         if (value->GetType() == StructuredData::Type::eTypeInteger)
1530705b1809SJason Molenda         {
1531705b1809SJason Molenda             if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1532705b1809SJason Molenda             {
1533705b1809SJason Molenda                 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
1534705b1809SJason Molenda                 var_success = true;
1535705b1809SJason Molenda             }
1536705b1809SJason Molenda         }
1537705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1538705b1809SJason Molenda         {
1539705b1809SJason Molenda             s.Printf ("%f", value->GetAsFloat()->GetValue());
1540705b1809SJason Molenda             var_success = true;
1541705b1809SJason Molenda         }
1542705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeString)
1543705b1809SJason Molenda         {
1544705b1809SJason Molenda             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1545705b1809SJason Molenda             var_success = true;
1546705b1809SJason Molenda         }
1547705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeArray)
1548705b1809SJason Molenda         {
1549705b1809SJason Molenda             if (value->GetAsArray()->GetSize() > 0)
1550705b1809SJason Molenda             {
1551705b1809SJason Molenda                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1552705b1809SJason Molenda                 var_success = true;
1553705b1809SJason Molenda             }
1554705b1809SJason Molenda         }
1555705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1556705b1809SJason Molenda         {
1557705b1809SJason Molenda             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1558705b1809SJason Molenda             var_success = true;
1559705b1809SJason Molenda         }
1560705b1809SJason Molenda     }
1561705b1809SJason Molenda 
1562705b1809SJason Molenda     return var_success;
1563705b1809SJason Molenda }
1564705b1809SJason Molenda 
1565705b1809SJason Molenda 
1566c3ce7f27SMichael Sartain static bool
1567c3ce7f27SMichael Sartain FormatPromptRecurse
15681b654882SGreg Clayton (
15691b654882SGreg Clayton     const char *format,
15701b654882SGreg Clayton     const SymbolContext *sc,
15711b654882SGreg Clayton     const ExecutionContext *exe_ctx,
15721b654882SGreg Clayton     const Address *addr,
15731b654882SGreg Clayton     Stream &s,
15744becb37eSEnrico Granata     const char **end,
1575aff1b357SJason Molenda     ValueObject* valobj,
1576aff1b357SJason Molenda     bool function_changed,
1577aff1b357SJason Molenda     bool initial_function
15781b654882SGreg Clayton )
15791b654882SGreg Clayton {
1580c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
15811b654882SGreg Clayton     bool success = true;
15821b654882SGreg Clayton     const char *p;
15835160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1584c3ce7f27SMichael Sartain 
15851b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
15861b654882SGreg Clayton     {
1587c482a192SEnrico Granata         if (realvalobj)
15884becb37eSEnrico Granata         {
1589c482a192SEnrico Granata             valobj = realvalobj;
1590c482a192SEnrico Granata             realvalobj = NULL;
15914becb37eSEnrico Granata         }
15921b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
15931b654882SGreg Clayton         if (non_special_chars > 0)
15941b654882SGreg Clayton         {
15951b654882SGreg Clayton             if (success)
15961b654882SGreg Clayton                 s.Write (p, non_special_chars);
15971b654882SGreg Clayton             p += non_special_chars;
15981b654882SGreg Clayton         }
15991b654882SGreg Clayton 
16001b654882SGreg Clayton         if (*p == '\0')
16011b654882SGreg Clayton         {
16021b654882SGreg Clayton             break;
16031b654882SGreg Clayton         }
16041b654882SGreg Clayton         else if (*p == '{')
16051b654882SGreg Clayton         {
16061b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
16071b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
16081b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
16091b654882SGreg Clayton             // is one in the symbol context you can use:
16101b654882SGreg Clayton             //      "{function =${function.name}}"
16111b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
16121b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
16131b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
16141b654882SGreg Clayton             // or symbol with a valid name.
16151b654882SGreg Clayton             StreamString sub_strm;
16161b654882SGreg Clayton 
16171b654882SGreg Clayton             ++p;  // Skip the '{'
16181b654882SGreg Clayton 
1619aff1b357SJason Molenda             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function))
16201b654882SGreg Clayton             {
16211b654882SGreg Clayton                 // The stream had all it needed
16221b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
16231b654882SGreg Clayton             }
16241b654882SGreg Clayton             if (*p != '}')
16251b654882SGreg Clayton             {
16261b654882SGreg Clayton                 success = false;
16271b654882SGreg Clayton                 break;
16281b654882SGreg Clayton             }
16291b654882SGreg Clayton         }
16301b654882SGreg Clayton         else if (*p == '}')
16311b654882SGreg Clayton         {
16321b654882SGreg Clayton             // End of a enclosing scope
16331b654882SGreg Clayton             break;
16341b654882SGreg Clayton         }
16351b654882SGreg Clayton         else if (*p == '$')
16361b654882SGreg Clayton         {
16371b654882SGreg Clayton             // We have a prompt variable to print
16381b654882SGreg Clayton             ++p;
16391b654882SGreg Clayton             if (*p == '{')
16401b654882SGreg Clayton             {
16411b654882SGreg Clayton                 ++p;
16421b654882SGreg Clayton                 const char *var_name_begin = p;
16431b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
16441b654882SGreg Clayton 
16451b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
16461b654882SGreg Clayton                 {
16471b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
16481b654882SGreg Clayton                     if (success)
16491b654882SGreg Clayton                     {
16501b654882SGreg Clayton                         const char *cstr = NULL;
16510769b2b1SMichael Sartain                         std::string token_format;
16521b654882SGreg Clayton                         Address format_addr;
1653aff1b357SJason Molenda 
1654aff1b357SJason Molenda                         // normally "addr" means print a raw address but
1655aff1b357SJason Molenda                         // "file-addr-or-load-addr" means print a module + file addr if there's no load addr
1656aff1b357SJason Molenda                         bool print_file_addr_or_load_addr = false;
1657aff1b357SJason Molenda                         bool addr_offset_concrete_func_only = false;
1658aff1b357SJason Molenda                         bool addr_offset_print_with_no_padding = false;
16591b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
16601b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
16611b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
16621b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
16631b654882SGreg Clayton                         FileSpec format_file_spec;
1664e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
16651b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
16669fc1944eSEnrico Granata                         bool do_deref_pointer = false;
166786cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
166886cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
16691b654882SGreg Clayton 
16701b654882SGreg Clayton                         // Each variable must set success to true below...
16711b654882SGreg Clayton                         bool var_success = false;
16721b654882SGreg Clayton                         switch (var_name_begin[0])
16731b654882SGreg Clayton                         {
16744becb37eSEnrico Granata                         case '*':
16756f3533fbSEnrico Granata                         case 'v':
16766f3533fbSEnrico Granata                         case 's':
16774becb37eSEnrico Granata                             {
1678c482a192SEnrico Granata                                 if (!valobj)
167934132754SGreg Clayton                                     break;
16806f3533fbSEnrico Granata 
1681c3e320a7SEnrico Granata                                 if (log)
1682d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1683c3e320a7SEnrico Granata 
16846f3533fbSEnrico Granata                                 // check for *var and *svar
16856f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
16866f3533fbSEnrico Granata                                 {
16879fc1944eSEnrico Granata                                     do_deref_pointer = true;
16889fc1944eSEnrico Granata                                     var_name_begin++;
1689c3e320a7SEnrico Granata                                     if (log)
169068ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
169168ae4117SEnrico Granata                                 }
1692c3e320a7SEnrico Granata 
16936f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
16944becb37eSEnrico Granata                                 {
1695c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
169686cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
169786cc9829SEnrico Granata                                     if (!valobj)
169886cc9829SEnrico Granata                                         break;
16996f3533fbSEnrico Granata                                     var_name_begin++;
1700c3e320a7SEnrico Granata                                     if (log)
170168ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
170268ae4117SEnrico Granata                                 }
1703c3e320a7SEnrico Granata 
17046f3533fbSEnrico Granata                                 // should be a 'v' by now
17056f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
17066f3533fbSEnrico Granata                                     break;
17076f3533fbSEnrico Granata 
1708c3e320a7SEnrico Granata                                 if (log)
170968ae4117SEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1710c3e320a7SEnrico Granata 
1711fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
171286cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1713fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
17148c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
171586cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
171634132754SGreg Clayton                                 ValueObject* target = NULL;
17174d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
171834132754SGreg Clayton                                 const char* var_name_final = NULL;
17199fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
172034132754SGreg Clayton                                 const char* close_bracket_position = NULL;
172134132754SGreg Clayton                                 int64_t index_lower = -1;
172234132754SGreg Clayton                                 int64_t index_higher = -1;
17239fc1944eSEnrico Granata                                 bool is_array_range = false;
1724fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
172585933ed4SEnrico Granata                                 bool was_plain_var = false;
172685933ed4SEnrico Granata                                 bool was_var_format = false;
1727a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1728fc7a7f3bSEnrico Granata 
1729c482a192SEnrico Granata                                 if (!valobj) break;
1730c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
17310769b2b1SMichael Sartain                                 if (IsToken (var_name_begin, "var}"))
17320a3958e0SEnrico Granata                                 {
173385933ed4SEnrico Granata                                     was_plain_var = true;
1734c482a192SEnrico Granata                                     target = valobj;
173586cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17360a3958e0SEnrico Granata                                 }
17370769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin,"var%"))
17389fc1944eSEnrico Granata                                 {
173985933ed4SEnrico Granata                                     was_var_format = true;
17409fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
17419fc1944eSEnrico Granata                                     const char* percent_position;
1742c482a192SEnrico Granata                                     target = valobj;
174386cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17449fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17459fc1944eSEnrico Granata                                                           var_name_end,
17469fc1944eSEnrico Granata                                                           &var_name_final,
17479fc1944eSEnrico Granata                                                           &percent_position,
17489fc1944eSEnrico Granata                                                           &custom_format,
17499fc1944eSEnrico Granata                                                           &val_obj_display);
17500a3958e0SEnrico Granata                                 }
17519fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
17520769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin, "var"))
17539fc1944eSEnrico Granata                                 {
17540769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "var["))
1755a777dc2aSEnrico Granata                                         was_var_indexed = true;
17569fc1944eSEnrico Granata                                     const char* percent_position;
17579fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17589fc1944eSEnrico Granata                                                           var_name_end,
17599fc1944eSEnrico Granata                                                           &var_name_final,
17609fc1944eSEnrico Granata                                                           &percent_position,
17619fc1944eSEnrico Granata                                                           &custom_format,
17629fc1944eSEnrico Granata                                                           &val_obj_display);
17639fc1944eSEnrico Granata 
17649fc1944eSEnrico Granata                                     const char* open_bracket_position;
17659fc1944eSEnrico Granata                                     const char* separator_position;
17669fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
17679fc1944eSEnrico Granata                                                         var_name_end,
17689fc1944eSEnrico Granata                                                         var_name_final,
17699fc1944eSEnrico Granata                                                         &open_bracket_position,
17709fc1944eSEnrico Granata                                                         &separator_position,
17719fc1944eSEnrico Granata                                                         &close_bracket_position,
17729fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
17739fc1944eSEnrico Granata                                                         &index_lower,
17749fc1944eSEnrico Granata                                                         &index_higher);
17759fc1944eSEnrico Granata 
17769fc1944eSEnrico Granata                                     Error error;
17779fc1944eSEnrico Granata 
1778599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1779599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1780fc7a7f3bSEnrico Granata 
1781e992a089SEnrico Granata                                     if (log)
1782599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1783fc7a7f3bSEnrico Granata 
1784599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1785fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1786fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1787fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1788fc7a7f3bSEnrico Granata                                                                              options,
1789fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1790fc7a7f3bSEnrico Granata 
1791fc7a7f3bSEnrico Granata                                     if (!target)
17929fc1944eSEnrico Granata                                     {
1793e992a089SEnrico Granata                                         if (log)
1794d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1795e992a089SEnrico Granata                                                " final_value_type %d",
1796fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1797fc7a7f3bSEnrico Granata                                         break;
17980a3958e0SEnrico Granata                                     }
1799a7187d00SEnrico Granata                                     else
1800fc7a7f3bSEnrico Granata                                     {
1801e992a089SEnrico Granata                                         if (log)
1802d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1803e992a089SEnrico Granata                                                " final_value_type %d",
1804fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1805a7187d00SEnrico Granata                                     }
18060a3958e0SEnrico Granata                                 }
18070a3958e0SEnrico Granata                                 else
18080a3958e0SEnrico Granata                                     break;
18099fc1944eSEnrico Granata 
181086cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
181186cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1812fc7a7f3bSEnrico Granata 
181386cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1814fc7a7f3bSEnrico Granata 
1815a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
18160a3958e0SEnrico Granata                                 {
18179fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
18189fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
18199fc1944eSEnrico Granata                                     // to get to the target ValueObject
18209fc1944eSEnrico Granata                                     Error error;
18219fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1822dc940730SEnrico Granata                                     if (error.Fail())
1823dc940730SEnrico Granata                                     {
1824dc940730SEnrico Granata                                         if (log)
1825d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1826dc940730SEnrico Granata                                         break;
1827dc940730SEnrico Granata                                     }
18289fc1944eSEnrico Granata                                     do_deref_pointer = false;
18290a3958e0SEnrico Granata                                 }
18300a3958e0SEnrico Granata 
1831f164d940SJim Ingham                                 if (!target)
1832f164d940SJim Ingham                                 {
1833f164d940SJim Ingham                                     if (log)
1834f164d940SJim Ingham                                         log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
1835f164d940SJim Ingham                                     break;
1836f164d940SJim Ingham                                 }
1837f164d940SJim Ingham 
1838a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1839a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1840a777dc2aSEnrico Granata                                 // us into an endless recursion
1841a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1842a777dc2aSEnrico Granata                                 {
1843a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1844a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1845a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1846a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1847a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1848a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1849a777dc2aSEnrico Granata                                 }
1850a777dc2aSEnrico Granata 
185185933ed4SEnrico Granata                                 // TODO use flags for these
185257ee3067SGreg Clayton                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
1853*622be238SEnrico Granata                                 bool is_array = (type_info_flags & eTypeIsArray) != 0;
1854*622be238SEnrico Granata                                 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
185557ee3067SGreg Clayton                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1856f4efecd9SEnrico Granata 
185786cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1858f4efecd9SEnrico Granata                                 {
185985933ed4SEnrico Granata                                     StreamString str_temp;
1860e992a089SEnrico Granata                                     if (log)
1861d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1862d64d0bc0SEnrico Granata 
18635088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1864d64d0bc0SEnrico Granata                                     {
1865f4efecd9SEnrico Granata                                         // try to use the special cases
186685933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
186785933ed4SEnrico Granata                                                                                           val_obj_display,
186885933ed4SEnrico Granata                                                                                           custom_format);
1869e992a089SEnrico Granata                                         if (log)
1870d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1871d64d0bc0SEnrico Granata 
1872d64d0bc0SEnrico Granata                                         // should not happen
18735088c486SGreg Clayton                                         if (var_success)
187485933ed4SEnrico Granata                                             s << str_temp.GetData();
1875d64d0bc0SEnrico Granata                                         var_success = true;
1876d64d0bc0SEnrico Granata                                         break;
1877d64d0bc0SEnrico Granata                                     }
1878d64d0bc0SEnrico Granata                                     else
1879d64d0bc0SEnrico Granata                                     {
188088da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1881d64d0bc0SEnrico Granata                                         {
1882d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1883d64d0bc0SEnrico Granata                                         }
188488da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
188588da35f8SEnrico Granata                                         {
188623f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
188788da35f8SEnrico Granata                                                                                  val_obj_display,
188886cc9829SEnrico Granata                                                                                  custom_format,
188986cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
189088da35f8SEnrico Granata                                         }
1891d64d0bc0SEnrico Granata                                         var_success = true;
1892d64d0bc0SEnrico Granata                                         break;
1893d64d0bc0SEnrico Granata                                     }
1894d64d0bc0SEnrico Granata                                 }
1895d64d0bc0SEnrico Granata 
1896d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1897d64d0bc0SEnrico Granata                                 // type @ location message
1898d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1899d64d0bc0SEnrico Granata                                 {
1900d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1901d64d0bc0SEnrico Granata                                     var_success = true;
190285933ed4SEnrico Granata                                     break;
190385933ed4SEnrico Granata                                 }
190485933ed4SEnrico Granata 
1905d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
190686cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
190785933ed4SEnrico Granata                                 {
190885933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
190985933ed4SEnrico Granata                                     var_success = true;
1910f4efecd9SEnrico Granata                                     break;
1911f4efecd9SEnrico Granata                                 }
1912f4efecd9SEnrico Granata 
19139fc1944eSEnrico Granata                                 if (!is_array_range)
1914e992a089SEnrico Granata                                 {
1915e992a089SEnrico Granata                                     if (log)
1916d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
19179fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1918e992a089SEnrico Granata                                 }
19199fc1944eSEnrico Granata                                 else
19209fc1944eSEnrico Granata                                 {
1921e992a089SEnrico Granata                                     if (log)
1922d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
19239fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
19249fc1944eSEnrico Granata                                         break;
1925e992a089SEnrico Granata                                     if (log)
1926d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1927fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1928fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
19290a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
19300a3958e0SEnrico Granata                                     {
1931fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1932fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1933fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1934fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1935fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1936fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
19370a3958e0SEnrico Granata                                     }
19380a3958e0SEnrico Granata 
19390a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
19400a3958e0SEnrico Granata                                     s.PutChar('[');
19410a3958e0SEnrico Granata                                     var_success = true;
19420a3958e0SEnrico Granata 
19439fc1944eSEnrico Granata                                     if (index_higher < 0)
1944c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
19450a3958e0SEnrico Granata 
1946cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
194722c55d18SEnrico Granata 
19480a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
19490a3958e0SEnrico Granata                                     {
1950fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
19519fc1944eSEnrico Granata                                                                                      index_lower,
1952c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1953fc7a7f3bSEnrico Granata                                                                                      false).get();
19540a3958e0SEnrico Granata 
1955fc7a7f3bSEnrico Granata                                         if (!item)
1956fc7a7f3bSEnrico Granata                                         {
1957e992a089SEnrico Granata                                             if (log)
1958d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1959fc7a7f3bSEnrico Granata                                         }
1960fc7a7f3bSEnrico Granata                                         else
1961fc7a7f3bSEnrico Granata                                         {
1962e992a089SEnrico Granata                                             if (log)
1963d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1964fc7a7f3bSEnrico Granata                                         }
1965fc7a7f3bSEnrico Granata 
19660a3958e0SEnrico Granata                                         if (!special_directions)
19679fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
19680a3958e0SEnrico Granata                                         else
1969aff1b357SJason Molenda                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function);
19700a3958e0SEnrico Granata 
197122c55d18SEnrico Granata                                         if (--max_num_children == 0)
197222c55d18SEnrico Granata                                         {
197322c55d18SEnrico Granata                                             s.PutCString(", ...");
197422c55d18SEnrico Granata                                             break;
197522c55d18SEnrico Granata                                         }
197622c55d18SEnrico Granata 
19770a3958e0SEnrico Granata                                         if (index_lower < index_higher)
19780a3958e0SEnrico Granata                                             s.PutChar(',');
19790a3958e0SEnrico Granata                                     }
19800a3958e0SEnrico Granata                                     s.PutChar(']');
19814becb37eSEnrico Granata                                 }
19824becb37eSEnrico Granata                             }
198334132754SGreg Clayton                             break;
19841b654882SGreg Clayton                         case 'a':
1985aff1b357SJason Molenda                             if (IsToken (var_name_begin, "addr-file-or-load}"))
1986aff1b357SJason Molenda                             {
1987aff1b357SJason Molenda                                 print_file_addr_or_load_addr = true;
1988aff1b357SJason Molenda                             }
1989aff1b357SJason Molenda                             if (IsToken (var_name_begin, "addr}")
1990aff1b357SJason Molenda                                 || IsToken (var_name_begin, "addr-file-or-load}"))
19911b654882SGreg Clayton                             {
19921b654882SGreg Clayton                                 if (addr && addr->IsValid())
19931b654882SGreg Clayton                                 {
19941b654882SGreg Clayton                                     var_success = true;
19951b654882SGreg Clayton                                     format_addr = *addr;
19961b654882SGreg Clayton                                 }
19971b654882SGreg Clayton                             }
19981b654882SGreg Clayton                             break;
19991b654882SGreg Clayton 
20001b654882SGreg Clayton                         case 'p':
20010769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "process."))
20021b654882SGreg Clayton                             {
2003c14ee32dSGreg Clayton                                 if (exe_ctx)
2004c14ee32dSGreg Clayton                                 {
2005c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
2006c14ee32dSGreg Clayton                                     if (process)
20071b654882SGreg Clayton                                     {
20081b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
20090769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
20101b654882SGreg Clayton                                         {
20110769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), process->GetID());
20121b654882SGreg Clayton                                             var_success = true;
20131b654882SGreg Clayton                                         }
20140769b2b1SMichael Sartain                                         else if ((IsToken (var_name_begin, "name}")) ||
20150769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.basename}")) ||
20160769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.fullpath}")))
20171b654882SGreg Clayton                                         {
2018c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
2019aa149cbdSGreg Clayton                                             if (exe_module)
20201b654882SGreg Clayton                                             {
20211b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
20221b654882SGreg Clayton                                                 {
2023aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
20249076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
20251b654882SGreg Clayton                                                 }
20261b654882SGreg Clayton                                                 else
20271b654882SGreg Clayton                                                 {
2028aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
20299076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
20301b654882SGreg Clayton                                                 }
20311b654882SGreg Clayton                                             }
20321b654882SGreg Clayton                                         }
20330769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2034aad8e480SEnrico Granata                                         {
2035aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2036aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2037aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
20380769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
2039aad8e480SEnrico Granata                                                 var_success = true;
2040aad8e480SEnrico Granata                                         }
20411b654882SGreg Clayton                                     }
20421b654882SGreg Clayton                                 }
2043c14ee32dSGreg Clayton                             }
20441b654882SGreg Clayton                             break;
20451b654882SGreg Clayton 
20461b654882SGreg Clayton                         case 't':
20470769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "thread."))
20481b654882SGreg Clayton                             {
2049c14ee32dSGreg Clayton                                 if (exe_ctx)
2050c14ee32dSGreg Clayton                                 {
2051c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
2052c14ee32dSGreg Clayton                                     if (thread)
20531b654882SGreg Clayton                                     {
20541b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
20550769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
20561b654882SGreg Clayton                                         {
20570769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetID());
20581b654882SGreg Clayton                                             var_success = true;
20591b654882SGreg Clayton                                         }
20600769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2061160c9d81SGreg Clayton                                         {
20620769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
2063160c9d81SGreg Clayton                                             var_success = true;
2064160c9d81SGreg Clayton                                         }
20650769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
20661b654882SGreg Clayton                                         {
20670769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
20681b654882SGreg Clayton                                             var_success = true;
20691b654882SGreg Clayton                                         }
20700769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "name}"))
20711b654882SGreg Clayton                                         {
2072c14ee32dSGreg Clayton                                             cstr = thread->GetName();
20731b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20741b654882SGreg Clayton                                             if (var_success)
20751b654882SGreg Clayton                                                 s.PutCString(cstr);
20761b654882SGreg Clayton                                         }
20770769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "queue}"))
20781b654882SGreg Clayton                                         {
2079c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
20801b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20811b654882SGreg Clayton                                             if (var_success)
20821b654882SGreg Clayton                                                 s.PutCString(cstr);
20831b654882SGreg Clayton                                         }
20840769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "stop-reason}"))
20851b654882SGreg Clayton                                         {
2086c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20875d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
20881b654882SGreg Clayton                                             {
2089b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
20901b654882SGreg Clayton                                                 if (cstr && cstr[0])
20911b654882SGreg Clayton                                                 {
20921b654882SGreg Clayton                                                     s.PutCString(cstr);
20931b654882SGreg Clayton                                                     var_success = true;
20941b654882SGreg Clayton                                                 }
20951b654882SGreg Clayton                                             }
20961b654882SGreg Clayton                                         }
20970769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "return-value}"))
209873ca05a2SJim Ingham                                         {
209973ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
21005d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
210173ca05a2SJim Ingham                                             {
210273ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
210373ca05a2SJim Ingham                                                 if (return_valobj_sp)
210473ca05a2SJim Ingham                                                 {
21054d93b8cdSEnrico Granata                                                     return_valobj_sp->Dump(s);
210673ca05a2SJim Ingham                                                     var_success = true;
210773ca05a2SJim Ingham                                                 }
210873ca05a2SJim Ingham                                             }
210973ca05a2SJim Ingham                                         }
211030fadafeSJim Ingham                                         else if (IsToken (var_name_begin, "completed-expression}"))
211130fadafeSJim Ingham                                         {
211230fadafeSJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
211330fadafeSJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
211430fadafeSJim Ingham                                             {
211530fadafeSJim Ingham                                                 ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
211630fadafeSJim Ingham                                                 if (expression_var_sp && expression_var_sp->GetValueObject())
211730fadafeSJim Ingham                                                 {
211830fadafeSJim Ingham                                                     expression_var_sp->GetValueObject()->Dump(s);
211930fadafeSJim Ingham                                                     var_success = true;
212030fadafeSJim Ingham                                                 }
212130fadafeSJim Ingham                                             }
212230fadafeSJim Ingham                                         }
21230769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2124aad8e480SEnrico Granata                                         {
2125aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2126aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2127aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
21280769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2129aad8e480SEnrico Granata                                                 var_success = true;
2130aad8e480SEnrico Granata                                         }
2131705b1809SJason Molenda                                         else if (IsToken (var_name_begin, "info."))
2132705b1809SJason Molenda                                         {
2133705b1809SJason Molenda                                             var_name_begin += ::strlen("info.");
2134705b1809SJason Molenda                                             StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
2135705b1809SJason Molenda                                             if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
2136705b1809SJason Molenda                                             {
2137705b1809SJason Molenda                                                 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
2138705b1809SJason Molenda                                             }
2139705b1809SJason Molenda                                         }
2140aad8e480SEnrico Granata                                     }
2141aad8e480SEnrico Granata                                 }
214273ca05a2SJim Ingham                             }
21430769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "target."))
21441b654882SGreg Clayton                             {
214567cc0636SGreg Clayton                                 // TODO: hookup properties
214667cc0636SGreg Clayton //                                if (!target_properties_sp)
214767cc0636SGreg Clayton //                                {
214867cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
214967cc0636SGreg Clayton //                                    if (target)
215067cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
215167cc0636SGreg Clayton //                                }
215267cc0636SGreg Clayton //
215367cc0636SGreg Clayton //                                if (target_properties_sp)
215467cc0636SGreg Clayton //                                {
215567cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
215667cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
215767cc0636SGreg Clayton //                                    if (end_property)
215867cc0636SGreg Clayton //                                    {
215967cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
216067cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
216167cc0636SGreg Clayton //                                        if (!property_value.empty())
216267cc0636SGreg Clayton //                                        {
216367cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
216467cc0636SGreg Clayton //                                            var_success = true;
216567cc0636SGreg Clayton //                                        }
216667cc0636SGreg Clayton //                                    }
216767cc0636SGreg Clayton //                                }
21680603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
21690603aa9dSGreg Clayton                                 if (target)
21701b654882SGreg Clayton                                 {
21711b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
21720769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "arch}"))
21731b654882SGreg Clayton                                     {
21741b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
21751b654882SGreg Clayton                                         if (arch.IsValid())
21761b654882SGreg Clayton                                         {
217764195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
21781b654882SGreg Clayton                                             var_success = true;
21791b654882SGreg Clayton                                         }
21801b654882SGreg Clayton                                     }
21810769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "script:"))
2182aad8e480SEnrico Granata                                     {
2183aad8e480SEnrico Granata                                         var_name_begin += ::strlen("script:");
2184aad8e480SEnrico Granata                                         std::string script_name(var_name_begin,var_name_end);
2185aad8e480SEnrico Granata                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
21860769b2b1SMichael Sartain                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2187aad8e480SEnrico Granata                                             var_success = true;
2188aad8e480SEnrico Granata                                     }
21891b654882SGreg Clayton                                 }
21901b654882SGreg Clayton                             }
21911b654882SGreg Clayton                             break;
21921b654882SGreg Clayton 
21931b654882SGreg Clayton                         case 'm':
21940769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "module."))
21951b654882SGreg Clayton                             {
21960603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
21971b654882SGreg Clayton                                 {
21980603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
21991b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
22001b654882SGreg Clayton 
22010769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
22021b654882SGreg Clayton                                     {
22031b654882SGreg Clayton                                         if (module->GetFileSpec())
22041b654882SGreg Clayton                                         {
22051b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
22061b654882SGreg Clayton 
22070769b2b1SMichael Sartain                                             if (IsToken (var_name_begin, "basename}"))
22081b654882SGreg Clayton                                             {
22091b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
22109076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
22111b654882SGreg Clayton                                             }
22120769b2b1SMichael Sartain                                             else if (IsToken (var_name_begin, "fullpath}"))
22131b654882SGreg Clayton                                             {
22141b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
22159076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
22161b654882SGreg Clayton                                             }
22171b654882SGreg Clayton                                         }
22181b654882SGreg Clayton                                     }
22191b654882SGreg Clayton                                 }
22201b654882SGreg Clayton                             }
22211b654882SGreg Clayton                             break;
22221b654882SGreg Clayton 
22231b654882SGreg Clayton 
22241b654882SGreg Clayton                         case 'f':
22250769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "file."))
22261b654882SGreg Clayton                             {
22271b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
22281b654882SGreg Clayton                                 {
22291b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
22301b654882SGreg Clayton 
22310769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "basename}"))
22321b654882SGreg Clayton                                     {
22331b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
22349076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22351b654882SGreg Clayton                                     }
22360769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "fullpath}"))
22371b654882SGreg Clayton                                     {
22381b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
22399076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22401b654882SGreg Clayton                                     }
22411b654882SGreg Clayton                                 }
22421b654882SGreg Clayton                             }
22430769b2b1SMichael Sartain                            else if (IsToken (var_name_begin, "frame."))
22441b654882SGreg Clayton                             {
2245c14ee32dSGreg Clayton                                 if (exe_ctx)
2246c14ee32dSGreg Clayton                                 {
2247b57e4a1bSJason Molenda                                     StackFrame *frame = exe_ctx->GetFramePtr();
2248c14ee32dSGreg Clayton                                     if (frame)
22491b654882SGreg Clayton                                     {
22501b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
22510769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "index}"))
22521b654882SGreg Clayton                                         {
2253c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
22541b654882SGreg Clayton                                             var_success = true;
22551b654882SGreg Clayton                                         }
22560769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "pc}"))
22571b654882SGreg Clayton                                         {
22581b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22591b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
22601b654882SGreg Clayton                                             var_success = true;
22611b654882SGreg Clayton                                         }
22620769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "sp}"))
22631b654882SGreg Clayton                                         {
22641b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22651b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
22661b654882SGreg Clayton                                             var_success = true;
22671b654882SGreg Clayton                                         }
22680769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fp}"))
22691b654882SGreg Clayton                                         {
22701b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22711b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
22721b654882SGreg Clayton                                             var_success = true;
22731b654882SGreg Clayton                                         }
22740769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "flags}"))
22751b654882SGreg Clayton                                         {
22761b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22771b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
22781b654882SGreg Clayton                                             var_success = true;
22791b654882SGreg Clayton                                         }
22800769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "reg."))
22811b654882SGreg Clayton                                         {
2282c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
22831b654882SGreg Clayton                                             if (reg_ctx)
22841b654882SGreg Clayton                                             {
22851b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
22861b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
22871b654882SGreg Clayton                                                 {
22881b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
22891b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
22901b654882SGreg Clayton                                                     if (reg_info)
22911b654882SGreg Clayton                                                         var_success = true;
22921b654882SGreg Clayton                                                 }
22931b654882SGreg Clayton                                             }
22941b654882SGreg Clayton                                         }
22950769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2296aad8e480SEnrico Granata                                         {
2297aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2298aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2299aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
23000769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2301aad8e480SEnrico Granata                                                 var_success = true;
2302aad8e480SEnrico Granata                                         }
2303aad8e480SEnrico Granata                                     }
2304aad8e480SEnrico Granata                                 }
23051b654882SGreg Clayton                             }
23060769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "function."))
23071b654882SGreg Clayton                             {
23081b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
23091b654882SGreg Clayton                                 {
23101b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
23110769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "id}"))
23121b654882SGreg Clayton                                     {
23131b654882SGreg Clayton                                         if (sc->function)
2314d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
23151b654882SGreg Clayton                                         else
23161b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
23171b654882SGreg Clayton 
23181b654882SGreg Clayton                                         var_success = true;
23191b654882SGreg Clayton                                     }
2320aff1b357SJason Molenda                                     if (IsToken (var_name_begin, "changed}") && function_changed)
2321aff1b357SJason Molenda                                     {
2322aff1b357SJason Molenda                                         var_success = true;
2323aff1b357SJason Molenda                                     }
2324aff1b357SJason Molenda                                     if (IsToken (var_name_begin, "initial-function}") && initial_function)
2325aff1b357SJason Molenda                                     {
2326aff1b357SJason Molenda                                         var_success = true;
2327aff1b357SJason Molenda                                     }
23280769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name}"))
23291b654882SGreg Clayton                                     {
23301b654882SGreg Clayton                                         if (sc->function)
23311b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
23321b654882SGreg Clayton                                         else if (sc->symbol)
23331b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
23341b654882SGreg Clayton                                         if (cstr)
23351b654882SGreg Clayton                                         {
23361b654882SGreg Clayton                                             s.PutCString(cstr);
23370d9c9934SGreg Clayton 
23380d9c9934SGreg Clayton                                             if (sc->block)
23390d9c9934SGreg Clayton                                             {
23400d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
23410d9c9934SGreg Clayton                                                 if (inline_block)
23420d9c9934SGreg Clayton                                                 {
23430d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
23440d9c9934SGreg Clayton                                                     if (inline_info)
23450d9c9934SGreg Clayton                                                     {
23460d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
23470d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
23480d9c9934SGreg Clayton                                                     }
23490d9c9934SGreg Clayton                                                 }
23500d9c9934SGreg Clayton                                             }
23511b654882SGreg Clayton                                             var_success = true;
23521b654882SGreg Clayton                                         }
23531b654882SGreg Clayton                                     }
2354aff1b357SJason Molenda                                     else if (IsToken (var_name_begin, "name-without-args}"))
2355aff1b357SJason Molenda                                     {
2356aff1b357SJason Molenda                                         ConstString name;
2357aff1b357SJason Molenda                                         if (sc->function)
2358aff1b357SJason Molenda                                             name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2359aff1b357SJason Molenda                                         else if (sc->symbol)
2360aff1b357SJason Molenda                                             name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2361aff1b357SJason Molenda                                         if (name)
2362aff1b357SJason Molenda                                         {
2363aff1b357SJason Molenda                                             s.PutCString(name.GetCString());
2364aff1b357SJason Molenda                                             var_success = true;
2365aff1b357SJason Molenda                                         }
2366aff1b357SJason Molenda                                     }
23670769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name-with-args}"))
23686d3dbf51SGreg Clayton                                     {
23696d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
23706d3dbf51SGreg Clayton 
23716d3dbf51SGreg Clayton                                         if (sc->function)
23726d3dbf51SGreg Clayton                                         {
23736d3dbf51SGreg Clayton                                             var_success = true;
23746d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
23756d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
23766d3dbf51SGreg Clayton                                             if (cstr)
23776d3dbf51SGreg Clayton                                             {
23786d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
23796d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
23806d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
23816d3dbf51SGreg Clayton                                                 if (sc->block)
23826d3dbf51SGreg Clayton                                                 {
23836d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
23846d3dbf51SGreg Clayton 
23856d3dbf51SGreg Clayton                                                     if (inline_block)
23866d3dbf51SGreg Clayton                                                     {
23876d3dbf51SGreg Clayton                                                         get_function_vars = false;
23886d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
23896d3dbf51SGreg Clayton                                                         if (inline_info)
23906d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
23916d3dbf51SGreg Clayton                                                     }
23926d3dbf51SGreg Clayton                                                 }
23936d3dbf51SGreg Clayton 
23946d3dbf51SGreg Clayton                                                 if (get_function_vars)
23956d3dbf51SGreg Clayton                                                 {
23966d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
23976d3dbf51SGreg Clayton                                                 }
23986d3dbf51SGreg Clayton 
23996d3dbf51SGreg Clayton                                                 if (inline_info)
24006d3dbf51SGreg Clayton                                                 {
24016d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
24026d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
24036d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
24046d3dbf51SGreg Clayton                                                 }
24056d3dbf51SGreg Clayton 
24066d3dbf51SGreg Clayton                                                 VariableList args;
24076d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2408cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
24096d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
24106d3dbf51SGreg Clayton                                                 {
24116d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
2412e4a4f5d5SEnrico Granata                                                     const char *close_paren = nullptr;
2413e4a4f5d5SEnrico Granata                                                     const char *generic = strchr(cstr, '<');
2414e4a4f5d5SEnrico Granata                                                     // if before the arguments list begins there is a template sign
2415e4a4f5d5SEnrico Granata                                                     // then scan to the end of the generic args before you try to find
2416e4a4f5d5SEnrico Granata                                                     // the arguments list
2417e4a4f5d5SEnrico Granata                                                     if (generic && open_paren && generic < open_paren)
2418e4a4f5d5SEnrico Granata                                                     {
2419e4a4f5d5SEnrico Granata                                                         int generic_depth = 1;
2420e4a4f5d5SEnrico Granata                                                         ++generic;
2421e4a4f5d5SEnrico Granata                                                         for (;
2422e4a4f5d5SEnrico Granata                                                              *generic && generic_depth > 0;
2423e4a4f5d5SEnrico Granata                                                              generic++)
2424e4a4f5d5SEnrico Granata                                                         {
2425e4a4f5d5SEnrico Granata                                                             if (*generic == '<')
2426e4a4f5d5SEnrico Granata                                                                 generic_depth++;
2427e4a4f5d5SEnrico Granata                                                             if (*generic == '>')
2428e4a4f5d5SEnrico Granata                                                                 generic_depth--;
2429e4a4f5d5SEnrico Granata                                                         }
2430e4a4f5d5SEnrico Granata                                                         if (*generic)
2431e4a4f5d5SEnrico Granata                                                             open_paren = strchr(generic, '(');
2432e4a4f5d5SEnrico Granata                                                         else
2433e4a4f5d5SEnrico Granata                                                             open_paren = nullptr;
2434e4a4f5d5SEnrico Granata                                                     }
24356d3dbf51SGreg Clayton                                                     if (open_paren)
2436855958caSGreg Clayton                                                     {
24370769b2b1SMichael Sartain                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2438855958caSGreg Clayton                                                         {
2439855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2440855958caSGreg Clayton                                                             if (open_paren)
24416d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2442855958caSGreg Clayton                                                         }
2443855958caSGreg Clayton                                                         else
2444855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2445855958caSGreg Clayton                                                     }
24466d3dbf51SGreg Clayton 
24476d3dbf51SGreg Clayton                                                     if (open_paren)
24486d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
24496d3dbf51SGreg Clayton                                                     else
24506d3dbf51SGreg Clayton                                                     {
24516d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
24526d3dbf51SGreg Clayton                                                         s.PutChar ('(');
24536d3dbf51SGreg Clayton                                                     }
24545b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
24556d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
24566d3dbf51SGreg Clayton                                                     {
2457894f7359SEnrico Granata                                                         std::string buffer;
2458894f7359SEnrico Granata 
24596d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
24606d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2461894f7359SEnrico Granata                                                         const char *var_representation = nullptr;
24626d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
2463894f7359SEnrico Granata                                                         if (var_value_sp->GetClangType().IsAggregateType() &&
2464894f7359SEnrico Granata                                                             DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
2465894f7359SEnrico Granata                                                         {
2466894f7359SEnrico Granata                                                             static StringSummaryFormat format(TypeSummaryImpl::Flags()
2467894f7359SEnrico Granata                                                                                               .SetHideItemNames(false)
2468894f7359SEnrico Granata                                                                                               .SetShowMembersOneLiner(true),
2469894f7359SEnrico Granata                                                                                               "");
2470894f7359SEnrico Granata                                                             format.FormatObject(var_value_sp.get(), buffer);
2471894f7359SEnrico Granata                                                             var_representation = buffer.c_str();
2472894f7359SEnrico Granata                                                         }
2473894f7359SEnrico Granata                                                         else
2474894f7359SEnrico Granata                                                             var_representation = var_value_sp->GetValueAsCString();
24756d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
24766d3dbf51SGreg Clayton                                                             s.PutCString (", ");
24773b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2478cc7f9bf5SEnrico Granata                                                         {
2479894f7359SEnrico Granata                                                             if (var_representation)
2480894f7359SEnrico Granata                                                                 s.Printf ("%s=%s", var_name, var_representation);
24813b188b17SGreg Clayton                                                             else
2482cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2483cc7f9bf5SEnrico Granata                                                         }
2484cc7f9bf5SEnrico Granata                                                         else
24853b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
24866d3dbf51SGreg Clayton                                                     }
24876d3dbf51SGreg Clayton 
24886d3dbf51SGreg Clayton                                                     if (close_paren)
24896d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
24906d3dbf51SGreg Clayton                                                     else
24916d3dbf51SGreg Clayton                                                         s.PutChar(')');
24926d3dbf51SGreg Clayton 
24936d3dbf51SGreg Clayton                                                 }
24946d3dbf51SGreg Clayton                                                 else
24956d3dbf51SGreg Clayton                                                 {
24966d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
24976d3dbf51SGreg Clayton                                                 }
24986d3dbf51SGreg Clayton                                             }
24996d3dbf51SGreg Clayton                                         }
25006d3dbf51SGreg Clayton                                         else if (sc->symbol)
25016d3dbf51SGreg Clayton                                         {
25026d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
25036d3dbf51SGreg Clayton                                             if (cstr)
25046d3dbf51SGreg Clayton                                             {
25056d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
25066d3dbf51SGreg Clayton                                                 var_success = true;
25076d3dbf51SGreg Clayton                                             }
25086d3dbf51SGreg Clayton                                         }
25096d3dbf51SGreg Clayton                                     }
2510aff1b357SJason Molenda                                     else if (IsToken (var_name_begin, "addr-offset}")
2511aff1b357SJason Molenda                                             || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
25121b654882SGreg Clayton                                     {
2513aff1b357SJason Molenda                                         if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
2514aff1b357SJason Molenda                                         {
2515aff1b357SJason Molenda                                             addr_offset_print_with_no_padding = true;
2516aff1b357SJason Molenda                                             addr_offset_concrete_func_only = true;
2517aff1b357SJason Molenda                                         }
25181b654882SGreg Clayton                                         var_success = addr != NULL;
25191b654882SGreg Clayton                                         if (var_success)
25201b654882SGreg Clayton                                         {
25211b654882SGreg Clayton                                             format_addr = *addr;
25221b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25231b654882SGreg Clayton                                         }
25241b654882SGreg Clayton                                     }
25250769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "line-offset}"))
25261b654882SGreg Clayton                                     {
25271b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
25281b654882SGreg Clayton                                         if (var_success)
25291b654882SGreg Clayton                                         {
25301b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
25311b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25321b654882SGreg Clayton                                         }
25331b654882SGreg Clayton                                     }
25340769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "pc-offset}"))
25351b654882SGreg Clayton                                     {
2536b57e4a1bSJason Molenda                                         StackFrame *frame = exe_ctx->GetFramePtr();
2537c14ee32dSGreg Clayton                                         var_success = frame != NULL;
25381b654882SGreg Clayton                                         if (var_success)
25391b654882SGreg Clayton                                         {
2540c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
25411b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25421b654882SGreg Clayton                                         }
25431b654882SGreg Clayton                                     }
25441b654882SGreg Clayton                                 }
25451b654882SGreg Clayton                             }
25461b654882SGreg Clayton                             break;
25471b654882SGreg Clayton 
25481b654882SGreg Clayton                         case 'l':
25490769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "line."))
25501b654882SGreg Clayton                             {
25511b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
25521b654882SGreg Clayton                                 {
25531b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
25540769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
25551b654882SGreg Clayton                                     {
25561b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
25571b654882SGreg Clayton 
25580769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "basename}"))
25591b654882SGreg Clayton                                         {
25601b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
25619076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25621b654882SGreg Clayton                                         }
25630769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fullpath}"))
25641b654882SGreg Clayton                                         {
25651b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
25669076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25671b654882SGreg Clayton                                         }
25681b654882SGreg Clayton                                     }
25690769b2b1SMichael Sartain                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
25701b654882SGreg Clayton                                     {
25711b654882SGreg Clayton                                         var_success = true;
25720769b2b1SMichael Sartain                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
25731b654882SGreg Clayton                                     }
25740769b2b1SMichael Sartain                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
25750769b2b1SMichael Sartain                                              (IsToken (var_name_begin, "end-addr}")))
25761b654882SGreg Clayton                                     {
25771b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
25781b654882SGreg Clayton                                         if (var_success)
25791b654882SGreg Clayton                                         {
25801b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
25811b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
25821b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
25831b654882SGreg Clayton                                         }
25841b654882SGreg Clayton                                     }
25851b654882SGreg Clayton                                 }
25861b654882SGreg Clayton                             }
25871b654882SGreg Clayton                             break;
2588aff1b357SJason Molenda                         case 'c':
2589aff1b357SJason Molenda                             if (IsToken (var_name_begin, "current-pc-arrow"))
2590aff1b357SJason Molenda                             {
2591aff1b357SJason Molenda                                 if (addr && exe_ctx && exe_ctx->GetFramePtr())
2592aff1b357SJason Molenda                                 {
2593aff1b357SJason Molenda                                     RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
2594aff1b357SJason Molenda                                     if (reg_ctx.get())
2595aff1b357SJason Molenda                                     {
2596aff1b357SJason Molenda                                         addr_t pc_loadaddr = reg_ctx->GetPC();
2597aff1b357SJason Molenda                                         if (pc_loadaddr != LLDB_INVALID_ADDRESS)
2598aff1b357SJason Molenda                                         {
2599aff1b357SJason Molenda                                             Address pc;
2600aff1b357SJason Molenda                                             pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
2601aff1b357SJason Molenda                                             if (pc == *addr)
2602aff1b357SJason Molenda                                             {
2603aff1b357SJason Molenda                                                 s.Printf ("->");
2604aff1b357SJason Molenda                                                 var_success = true;
2605aff1b357SJason Molenda                                             }
2606aff1b357SJason Molenda                                             else
2607aff1b357SJason Molenda                                             {
2608aff1b357SJason Molenda                                                 s.Printf("  ");
2609aff1b357SJason Molenda                                                 var_success = true;
2610aff1b357SJason Molenda                                             }
2611aff1b357SJason Molenda                                         }
2612aff1b357SJason Molenda                                     }
2613aff1b357SJason Molenda                                 }
2614aff1b357SJason Molenda                             }
2615aff1b357SJason Molenda                             break;
26161b654882SGreg Clayton                         }
26171b654882SGreg Clayton 
26181b654882SGreg Clayton                         if (var_success)
26191b654882SGreg Clayton                         {
26201b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
26211b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
26221b654882SGreg Clayton                             {
2623b57e4a1bSJason Molenda                                 StackFrame *frame = exe_ctx->GetFramePtr();
26241b654882SGreg Clayton                                 // We have a register value to display...
26251b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
26261b654882SGreg Clayton                                 {
2627c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
26281b654882SGreg Clayton                                 }
26291b654882SGreg Clayton                                 else
26301b654882SGreg Clayton                                 {
26311b654882SGreg Clayton                                     if (reg_ctx == NULL)
2632c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
26331b654882SGreg Clayton 
26341b654882SGreg Clayton                                     if (reg_ctx)
26351b654882SGreg Clayton                                     {
26361b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
26371b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
26381b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
26391b654882SGreg Clayton                                         var_success = reg_info != NULL;
26401b654882SGreg Clayton                                     }
26411b654882SGreg Clayton                                 }
26421b654882SGreg Clayton                             }
26431b654882SGreg Clayton 
26441b654882SGreg Clayton                             if (reg_info != NULL)
26451b654882SGreg Clayton                             {
26467349bd90SGreg Clayton                                 RegisterValue reg_value;
26477349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
26487349bd90SGreg Clayton                                 if (var_success)
26491b654882SGreg Clayton                                 {
26509a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
26511b654882SGreg Clayton                                 }
26521b654882SGreg Clayton                             }
26531b654882SGreg Clayton 
26541b654882SGreg Clayton                             if (format_file_spec)
26551b654882SGreg Clayton                             {
26561b654882SGreg Clayton                                 s << format_file_spec;
26571b654882SGreg Clayton                             }
26581b654882SGreg Clayton 
26591b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
26601b654882SGreg Clayton                             if (format_addr.IsValid())
26611b654882SGreg Clayton                             {
26620603aa9dSGreg Clayton                                 var_success = false;
26630603aa9dSGreg Clayton 
26641b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
26651b654882SGreg Clayton                                 {
26661b654882SGreg Clayton                                     Address func_addr;
26670603aa9dSGreg Clayton 
26680603aa9dSGreg Clayton                                     if (sc)
26690603aa9dSGreg Clayton                                     {
26701b654882SGreg Clayton                                         if (sc->function)
26710d9c9934SGreg Clayton                                         {
26721b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2673aff1b357SJason Molenda                                             if (sc->block && addr_offset_concrete_func_only == false)
26740d9c9934SGreg Clayton                                             {
26750d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
26760d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
26770d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
26780d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
26790d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
26800d9c9934SGreg Clayton                                                 AddressRange inline_range;
26810d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
26820d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
26830d9c9934SGreg Clayton                                             }
26840d9c9934SGreg Clayton                                         }
2685e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2686e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
26870603aa9dSGreg Clayton                                     }
26881b654882SGreg Clayton 
26890603aa9dSGreg Clayton                                     if (func_addr.IsValid())
26901b654882SGreg Clayton                                     {
2691aff1b357SJason Molenda                                         const char *addr_offset_padding  =  " ";
2692aff1b357SJason Molenda                                         if (addr_offset_print_with_no_padding)
2693aff1b357SJason Molenda                                         {
2694aff1b357SJason Molenda                                             addr_offset_padding = "";
2695aff1b357SJason Molenda                                         }
26961b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
26971b654882SGreg Clayton                                         {
26981b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
26991b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
27001b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2701aff1b357SJason Molenda                                                 s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
27021b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2703aff1b357SJason Molenda                                                 s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
27040603aa9dSGreg Clayton                                             var_success = true;
27051b654882SGreg Clayton                                         }
27061b654882SGreg Clayton                                         else
27070603aa9dSGreg Clayton                                         {
27080603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
27090603aa9dSGreg Clayton                                             if (target)
27100603aa9dSGreg Clayton                                             {
27110603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
27120603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
27130603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2714aff1b357SJason Molenda                                                     s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
27150603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2716aff1b357SJason Molenda                                                     s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
27170603aa9dSGreg Clayton                                                 var_success = true;
27180603aa9dSGreg Clayton                                             }
27190603aa9dSGreg Clayton                                         }
27201b654882SGreg Clayton                                     }
27211b654882SGreg Clayton                                 }
27221b654882SGreg Clayton                                 else
27231b654882SGreg Clayton                                 {
27240603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
27251b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
27260603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
27270603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
27281b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
27291b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
27301b654882SGreg Clayton 
27311b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
27320603aa9dSGreg Clayton                                     {
2733aff1b357SJason Molenda                                         int addr_width = 0;
2734aff1b357SJason Molenda                                         if (exe_ctx && target)
2735aff1b357SJason Molenda                                         {
2736fd1a9362SEric Christopher                                             addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2737aff1b357SJason Molenda                                         }
273835f1a0d5SGreg Clayton                                         if (addr_width == 0)
273935f1a0d5SGreg Clayton                                             addr_width = 16;
2740aff1b357SJason Molenda                                         if (print_file_addr_or_load_addr)
2741aff1b357SJason Molenda                                         {
2742aff1b357SJason Molenda                                             format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
2743aff1b357SJason Molenda                                         }
2744aff1b357SJason Molenda                                         else
2745aff1b357SJason Molenda                                         {
2746d01b2953SDaniel Malea                                             s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
2747aff1b357SJason Molenda                                         }
27480603aa9dSGreg Clayton                                         var_success = true;
27490603aa9dSGreg Clayton                                     }
27501b654882SGreg Clayton                                 }
27511b654882SGreg Clayton                             }
27521b654882SGreg Clayton                         }
27531b654882SGreg Clayton 
27541b654882SGreg Clayton                         if (var_success == false)
27551b654882SGreg Clayton                             success = false;
27561b654882SGreg Clayton                     }
27571b654882SGreg Clayton                     p = var_name_end;
27581b654882SGreg Clayton                 }
27591b654882SGreg Clayton                 else
27601b654882SGreg Clayton                     break;
27611b654882SGreg Clayton             }
27621b654882SGreg Clayton             else
27631b654882SGreg Clayton             {
27641b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
27651b654882SGreg Clayton                 s.PutChar(*p);
27661b654882SGreg Clayton             }
27671b654882SGreg Clayton         }
27681b654882SGreg Clayton         else if (*p == '\\')
27691b654882SGreg Clayton         {
27701b654882SGreg Clayton             ++p; // skip the slash
27711b654882SGreg Clayton             switch (*p)
27721b654882SGreg Clayton             {
27731b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
27741b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
27751b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
27761b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
27771b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
27781b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
27791b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
27801b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
27811b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
27821b654882SGreg Clayton             case '0':
27831b654882SGreg Clayton                 // 1 to 3 octal chars
27841b654882SGreg Clayton                 {
27850603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
27860603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
27870603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
27880603aa9dSGreg Clayton 
27890603aa9dSGreg Clayton                     int i;
27900603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
27910603aa9dSGreg Clayton                         oct_str[i] = p[i];
27920603aa9dSGreg Clayton 
27930603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
27940603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
27950603aa9dSGreg Clayton                     // one less than i (even if i is zero)
27960603aa9dSGreg Clayton                     p += i - 1;
27970603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
27980603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
27991b654882SGreg Clayton                     {
2800c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
28011b654882SGreg Clayton                     }
28021b654882SGreg Clayton                 }
28031b654882SGreg Clayton                 break;
28041b654882SGreg Clayton 
28051b654882SGreg Clayton             case 'x':
28061b654882SGreg Clayton                 // hex number in the format
28070603aa9dSGreg Clayton                 if (isxdigit(p[1]))
28081b654882SGreg Clayton                 {
28090603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
28101b654882SGreg Clayton 
28110603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
28120603aa9dSGreg Clayton                     // NULL terminator
28131b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
28141b654882SGreg Clayton                     hex_str[0] = *p;
28150603aa9dSGreg Clayton                     if (isxdigit(p[1]))
28160603aa9dSGreg Clayton                     {
28170603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
28181b654882SGreg Clayton                         hex_str[1] = *p;
28190603aa9dSGreg Clayton                     }
28200603aa9dSGreg Clayton 
28211b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
28220603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2823c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
28241b654882SGreg Clayton                 }
28251b654882SGreg Clayton                 else
28261b654882SGreg Clayton                 {
28270603aa9dSGreg Clayton                     s.PutChar('x');
28281b654882SGreg Clayton                 }
28291b654882SGreg Clayton                 break;
28301b654882SGreg Clayton 
28311b654882SGreg Clayton             default:
28320603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
28330603aa9dSGreg Clayton                 // came after the '\'
28340603aa9dSGreg Clayton                 s << *p;
28351b654882SGreg Clayton                 break;
28361b654882SGreg Clayton 
28371b654882SGreg Clayton             }
28381b654882SGreg Clayton 
28391b654882SGreg Clayton         }
28401b654882SGreg Clayton     }
28411b654882SGreg Clayton     if (end)
28421b654882SGreg Clayton         *end = p;
28431b654882SGreg Clayton     return success;
28441b654882SGreg Clayton }
28451b654882SGreg Clayton 
2846c3ce7f27SMichael Sartain bool
2847c3ce7f27SMichael Sartain Debugger::FormatPrompt
2848c3ce7f27SMichael Sartain (
2849c3ce7f27SMichael Sartain     const char *format,
2850c3ce7f27SMichael Sartain     const SymbolContext *sc,
2851c3ce7f27SMichael Sartain     const ExecutionContext *exe_ctx,
2852c3ce7f27SMichael Sartain     const Address *addr,
2853c3ce7f27SMichael Sartain     Stream &s,
2854c3ce7f27SMichael Sartain     ValueObject* valobj
2855c3ce7f27SMichael Sartain )
2856c3ce7f27SMichael Sartain {
2857c3ce7f27SMichael Sartain     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2858c3ce7f27SMichael Sartain     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2859c3ce7f27SMichael Sartain     if (format_str.length())
2860c3ce7f27SMichael Sartain         format = format_str.c_str();
2861aff1b357SJason Molenda     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false);
2862c3ce7f27SMichael Sartain }
2863c3ce7f27SMichael Sartain 
2864aff1b357SJason Molenda bool
2865aff1b357SJason Molenda Debugger::FormatDisassemblerAddress (const char *format,
2866aff1b357SJason Molenda                                      const SymbolContext *sc,
2867aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
2868aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
2869aff1b357SJason Molenda                                      const Address *addr,
2870aff1b357SJason Molenda                                      Stream &s)
2871aff1b357SJason Molenda {
2872aff1b357SJason Molenda     if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope())
2873aff1b357SJason Molenda     {
2874aff1b357SJason Molenda         format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
2875aff1b357SJason Molenda     }
2876aff1b357SJason Molenda     bool function_changed = false;
2877aff1b357SJason Molenda     bool initial_function = false;
2878aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
2879aff1b357SJason Molenda     {
2880aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
2881aff1b357SJason Molenda         {
2882aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
2883aff1b357SJason Molenda             {
2884aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
2885aff1b357SJason Molenda                 {
2886aff1b357SJason Molenda                     function_changed = true;
2887aff1b357SJason Molenda                 }
2888aff1b357SJason Molenda             }
2889aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
2890aff1b357SJason Molenda             {
2891aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
2892aff1b357SJason Molenda                 {
2893aff1b357SJason Molenda                     function_changed = true;
2894aff1b357SJason Molenda                 }
2895aff1b357SJason Molenda             }
2896aff1b357SJason Molenda         }
2897aff1b357SJason Molenda     }
2898aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
2899aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
2900aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
2901aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
2902aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
2903aff1b357SJason Molenda     {
2904aff1b357SJason Molenda         initial_function = true;
2905aff1b357SJason Molenda     }
2906aff1b357SJason Molenda     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function);
2907aff1b357SJason Molenda }
2908aff1b357SJason Molenda 
2909aff1b357SJason Molenda 
2910228063cdSJim Ingham void
2911228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2912228063cdSJim Ingham {
29134f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
29144f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
29154f02b22dSJim Ingham     // callback.
2916228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2917228063cdSJim Ingham }
2918228063cdSJim Ingham 
2919228063cdSJim Ingham bool
2920228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2921228063cdSJim Ingham {
2922228063cdSJim Ingham     Log::Callbacks log_callbacks;
2923228063cdSJim Ingham 
2924228063cdSJim Ingham     StreamSP log_stream_sp;
29259a028519SSean Callanan     if (m_log_callback_stream_sp)
2926228063cdSJim Ingham     {
2927228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2928228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2929228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2930228063cdSJim Ingham     }
2931228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2932228063cdSJim Ingham     {
293344d93782SGreg Clayton         log_stream_sp = GetOutputFile();
2934228063cdSJim Ingham     }
2935228063cdSJim Ingham     else
2936228063cdSJim Ingham     {
2937228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2938c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2939c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2940c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2941228063cdSJim Ingham         {
2942228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2943228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2944228063cdSJim Ingham         }
2945228063cdSJim Ingham     }
2946228063cdSJim Ingham     assert (log_stream_sp.get());
2947228063cdSJim Ingham 
2948228063cdSJim Ingham     if (log_options == 0)
2949228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2950228063cdSJim Ingham 
295157abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2952228063cdSJim Ingham     {
2953228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2954228063cdSJim Ingham         return true;
2955228063cdSJim Ingham     }
2956228063cdSJim Ingham     else
2957228063cdSJim Ingham     {
2958228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2959228063cdSJim Ingham         if (log_channel_sp)
2960228063cdSJim Ingham         {
2961228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2962228063cdSJim Ingham             {
2963228063cdSJim Ingham                 return true;
2964228063cdSJim Ingham             }
2965228063cdSJim Ingham             else
2966228063cdSJim Ingham             {
2967228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2968228063cdSJim Ingham                 return false;
2969228063cdSJim Ingham             }
2970228063cdSJim Ingham         }
2971228063cdSJim Ingham         else
2972228063cdSJim Ingham         {
2973228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2974228063cdSJim Ingham             return false;
2975228063cdSJim Ingham         }
2976228063cdSJim Ingham     }
2977228063cdSJim Ingham     return false;
2978228063cdSJim Ingham }
2979228063cdSJim Ingham 
29809585fbfcSGreg Clayton SourceManager &
29819585fbfcSGreg Clayton Debugger::GetSourceManager ()
29829585fbfcSGreg Clayton {
29839585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
29849585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
29859585fbfcSGreg Clayton     return *m_source_manager_ap;
29869585fbfcSGreg Clayton }
29879585fbfcSGreg Clayton 
29889585fbfcSGreg Clayton 
298944d93782SGreg Clayton 
299044d93782SGreg Clayton // This function handles events that were broadcast by the process.
299144d93782SGreg Clayton void
299244d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
299344d93782SGreg Clayton {
299444d93782SGreg Clayton     using namespace lldb;
299544d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
299644d93782SGreg Clayton 
299744d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
299844d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
299944d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
300044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
300144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
300244d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
300344d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
300444d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
300544d93782SGreg Clayton //    {
300644d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
300744d93782SGreg Clayton //    }
300844d93782SGreg Clayton //
300944d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
301044d93782SGreg Clayton     {
301144d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
301244d93782SGreg Clayton         if (num_new_locations > 0)
301344d93782SGreg Clayton         {
301444d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
301544d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
301644d93782SGreg Clayton             if (output_sp)
301744d93782SGreg Clayton             {
301844d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
301944d93782SGreg Clayton                                   num_new_locations,
302044d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
302144d93782SGreg Clayton                                   breakpoint->GetID());
302244d93782SGreg Clayton                 RefreshTopIOHandler();
302344d93782SGreg Clayton             }
302444d93782SGreg Clayton         }
302544d93782SGreg Clayton     }
302644d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
302744d93782SGreg Clayton //    {
302844d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
302944d93782SGreg Clayton //    }
303044d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
303144d93782SGreg Clayton //    {
303244d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
303344d93782SGreg Clayton //    }
303444d93782SGreg Clayton }
303544d93782SGreg Clayton 
303644d93782SGreg Clayton size_t
303744d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
303844d93782SGreg Clayton {
303944d93782SGreg Clayton     size_t total_bytes = 0;
304044d93782SGreg Clayton     if (stream == NULL)
304144d93782SGreg Clayton         stream = GetOutputFile().get();
304244d93782SGreg Clayton 
304344d93782SGreg Clayton     if (stream)
304444d93782SGreg Clayton     {
304544d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
304644d93782SGreg Clayton         if (process == NULL)
304744d93782SGreg Clayton         {
304844d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
304944d93782SGreg Clayton             if (target_sp)
305044d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
305144d93782SGreg Clayton         }
305244d93782SGreg Clayton         if (process)
305344d93782SGreg Clayton         {
305444d93782SGreg Clayton             Error error;
305544d93782SGreg Clayton             size_t len;
305644d93782SGreg Clayton             char stdio_buffer[1024];
305744d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
305844d93782SGreg Clayton             {
305944d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
306044d93782SGreg Clayton                 total_bytes += len;
306144d93782SGreg Clayton             }
306244d93782SGreg Clayton         }
306344d93782SGreg Clayton         stream->Flush();
306444d93782SGreg Clayton     }
306544d93782SGreg Clayton     return total_bytes;
306644d93782SGreg Clayton }
306744d93782SGreg Clayton 
306844d93782SGreg Clayton size_t
306944d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
307044d93782SGreg Clayton {
307144d93782SGreg Clayton     size_t total_bytes = 0;
307244d93782SGreg Clayton     if (stream == NULL)
307344d93782SGreg Clayton         stream = GetOutputFile().get();
307444d93782SGreg Clayton 
307544d93782SGreg Clayton     if (stream)
307644d93782SGreg Clayton     {
307744d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
307844d93782SGreg Clayton         if (process == NULL)
307944d93782SGreg Clayton         {
308044d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
308144d93782SGreg Clayton             if (target_sp)
308244d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
308344d93782SGreg Clayton         }
308444d93782SGreg Clayton         if (process)
308544d93782SGreg Clayton         {
308644d93782SGreg Clayton             Error error;
308744d93782SGreg Clayton             size_t len;
308844d93782SGreg Clayton             char stdio_buffer[1024];
308944d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
309044d93782SGreg Clayton             {
309144d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
309244d93782SGreg Clayton                 total_bytes += len;
309344d93782SGreg Clayton             }
309444d93782SGreg Clayton         }
309544d93782SGreg Clayton         stream->Flush();
309644d93782SGreg Clayton     }
309744d93782SGreg Clayton     return total_bytes;
309844d93782SGreg Clayton }
309944d93782SGreg Clayton 
3100dc6224e0SGreg Clayton 
310144d93782SGreg Clayton // This function handles events that were broadcast by the process.
310244d93782SGreg Clayton void
310344d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
310444d93782SGreg Clayton {
310544d93782SGreg Clayton     using namespace lldb;
310644d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
310744d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
310844d93782SGreg Clayton 
3109b4874f1aSGreg Clayton     StreamString output_stream;
3110b4874f1aSGreg Clayton     StreamString error_stream;
311144d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
311244d93782SGreg Clayton 
3113b4874f1aSGreg Clayton     if (!gui_enabled)
3114b4874f1aSGreg Clayton     {
3115b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
311644d93782SGreg Clayton         assert (process_sp);
311744d93782SGreg Clayton 
3118b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
311944d93782SGreg Clayton         {
3120b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
312144d93782SGreg Clayton         }
3122b4874f1aSGreg Clayton 
3123b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
312444d93782SGreg Clayton         {
3125b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
312644d93782SGreg Clayton         }
3127b4874f1aSGreg Clayton 
3128b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
312944d93782SGreg Clayton         {
3130dc6224e0SGreg Clayton             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
313144d93782SGreg Clayton         }
3132b4874f1aSGreg Clayton 
3133b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
3134b4874f1aSGreg Clayton         {
3135b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
31366fea17e8SGreg Clayton             bool top_io_handler_hid = false;
31376fea17e8SGreg Clayton 
31386fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
31396fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
3140b4874f1aSGreg Clayton 
3141b4874f1aSGreg Clayton             if (output_stream.GetSize())
3142b4874f1aSGreg Clayton             {
3143b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
3144b4874f1aSGreg Clayton                 if (output_stream_sp)
3145b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
3146b4874f1aSGreg Clayton             }
3147b4874f1aSGreg Clayton 
3148b4874f1aSGreg Clayton             if (error_stream.GetSize())
3149b4874f1aSGreg Clayton             {
3150b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
3151b4874f1aSGreg Clayton                 if (error_stream_sp)
3152b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
315344d93782SGreg Clayton             }
315444d93782SGreg Clayton 
315544d93782SGreg Clayton             if (top_io_handler_hid)
315644d93782SGreg Clayton                 RefreshTopIOHandler();
315744d93782SGreg Clayton         }
315844d93782SGreg Clayton 
3159b4874f1aSGreg Clayton         if (pop_process_io_handler)
3160b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
3161b4874f1aSGreg Clayton     }
3162b4874f1aSGreg Clayton }
3163b4874f1aSGreg Clayton 
316444d93782SGreg Clayton void
316544d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
316644d93782SGreg Clayton {
316744d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
316844d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
316944d93782SGreg Clayton     using namespace lldb;
317044d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
317144d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
317244d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
317344d93782SGreg Clayton     {
317444d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
317544d93782SGreg Clayton         if (thread_sp)
317644d93782SGreg Clayton         {
317744d93782SGreg Clayton             HideTopIOHandler();
317844d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
317944d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
318044d93782SGreg Clayton             RefreshTopIOHandler();
318144d93782SGreg Clayton         }
318244d93782SGreg Clayton     }
318344d93782SGreg Clayton }
318444d93782SGreg Clayton 
318544d93782SGreg Clayton bool
318644d93782SGreg Clayton Debugger::IsForwardingEvents ()
318744d93782SGreg Clayton {
318844d93782SGreg Clayton     return (bool)m_forward_listener_sp;
318944d93782SGreg Clayton }
319044d93782SGreg Clayton 
319144d93782SGreg Clayton void
319244d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
319344d93782SGreg Clayton {
319444d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
319544d93782SGreg Clayton }
319644d93782SGreg Clayton 
319744d93782SGreg Clayton void
319844d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
319944d93782SGreg Clayton {
320044d93782SGreg Clayton     m_forward_listener_sp.reset();
320144d93782SGreg Clayton }
320244d93782SGreg Clayton 
320344d93782SGreg Clayton 
320444d93782SGreg Clayton void
320544d93782SGreg Clayton Debugger::DefaultEventHandler()
320644d93782SGreg Clayton {
320744d93782SGreg Clayton     Listener& listener(GetListener());
320844d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
320944d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
321044d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
321144d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
321244d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
321344d93782SGreg Clayton 
321444d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
321544d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
321644d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
321744d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
321844d93782SGreg Clayton 
321944d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
322044d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
322144d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
322244d93782SGreg Clayton 
322344d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
322444d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
322544d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
322644d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
322744d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
322844d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
322944d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
323044d93782SGreg Clayton 
323144d93782SGreg Clayton     bool done = false;
323244d93782SGreg Clayton     while (!done)
323344d93782SGreg Clayton     {
323444d93782SGreg Clayton //        Mutex::Locker locker;
323544d93782SGreg Clayton //        if (locker.TryLock(m_input_reader_stack.GetMutex()))
323644d93782SGreg Clayton //        {
323744d93782SGreg Clayton //            if (m_input_reader_stack.IsEmpty())
323844d93782SGreg Clayton //                break;
323944d93782SGreg Clayton //        }
324044d93782SGreg Clayton //
324144d93782SGreg Clayton         EventSP event_sp;
324244d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
324344d93782SGreg Clayton         {
324444d93782SGreg Clayton             if (event_sp)
324544d93782SGreg Clayton             {
324644d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
324744d93782SGreg Clayton                 if (broadcaster)
324844d93782SGreg Clayton                 {
324944d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
325044d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
325144d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
325244d93782SGreg Clayton                     {
325344d93782SGreg Clayton                         HandleProcessEvent (event_sp);
325444d93782SGreg Clayton                     }
325544d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
325644d93782SGreg Clayton                     {
325744d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
325844d93782SGreg Clayton                         {
325944d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
326044d93782SGreg Clayton                         }
326144d93782SGreg Clayton                     }
326244d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
326344d93782SGreg Clayton                     {
326444d93782SGreg Clayton                         HandleThreadEvent (event_sp);
326544d93782SGreg Clayton                     }
326644d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
326744d93782SGreg Clayton                     {
326844d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
326944d93782SGreg Clayton                         {
327044d93782SGreg Clayton                             done = true;
327144d93782SGreg Clayton                         }
327244d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
327344d93782SGreg Clayton                         {
327444d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
327544d93782SGreg Clayton                             if (data && data[0])
327644d93782SGreg Clayton                             {
327744d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
327844d93782SGreg Clayton                                 if (error_sp)
327944d93782SGreg Clayton                                 {
328044d93782SGreg Clayton                                     HideTopIOHandler();
328144d93782SGreg Clayton                                     error_sp->PutCString(data);
328244d93782SGreg Clayton                                     error_sp->Flush();
328344d93782SGreg Clayton                                     RefreshTopIOHandler();
328444d93782SGreg Clayton                                 }
328544d93782SGreg Clayton                             }
328644d93782SGreg Clayton                         }
328744d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
328844d93782SGreg Clayton                         {
328944d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
329044d93782SGreg Clayton                             if (data && data[0])
329144d93782SGreg Clayton                             {
329244d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
329344d93782SGreg Clayton                                 if (output_sp)
329444d93782SGreg Clayton                                 {
329544d93782SGreg Clayton                                     HideTopIOHandler();
329644d93782SGreg Clayton                                     output_sp->PutCString(data);
329744d93782SGreg Clayton                                     output_sp->Flush();
329844d93782SGreg Clayton                                     RefreshTopIOHandler();
329944d93782SGreg Clayton                                 }
330044d93782SGreg Clayton                             }
330144d93782SGreg Clayton                         }
330244d93782SGreg Clayton                     }
330344d93782SGreg Clayton                 }
330444d93782SGreg Clayton 
330544d93782SGreg Clayton                 if (m_forward_listener_sp)
330644d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
330744d93782SGreg Clayton             }
330844d93782SGreg Clayton         }
330944d93782SGreg Clayton     }
331044d93782SGreg Clayton }
331144d93782SGreg Clayton 
331244d93782SGreg Clayton lldb::thread_result_t
331344d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
331444d93782SGreg Clayton {
331544d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
331644d93782SGreg Clayton     return NULL;
331744d93782SGreg Clayton }
331844d93782SGreg Clayton 
331944d93782SGreg Clayton bool
332044d93782SGreg Clayton Debugger::StartEventHandlerThread()
332144d93782SGreg Clayton {
3322acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
3323807b6b32SGreg Clayton     {
3324807b6b32SGreg Clayton         m_event_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.event-handler",
3325807b6b32SGreg Clayton                                                                EventHandlerThread,
3326807b6b32SGreg Clayton                                                                this,
3327807b6b32SGreg Clayton                                                                NULL,
3328807b6b32SGreg Clayton                                                                8*1024*1024); // Use larger 8MB stack for this thread
3329807b6b32SGreg Clayton     }
3330acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
333144d93782SGreg Clayton }
333244d93782SGreg Clayton 
333344d93782SGreg Clayton void
333444d93782SGreg Clayton Debugger::StopEventHandlerThread()
333544d93782SGreg Clayton {
3336acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
333744d93782SGreg Clayton     {
333844d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
333939de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
334044d93782SGreg Clayton     }
334144d93782SGreg Clayton }
334244d93782SGreg Clayton 
334344d93782SGreg Clayton 
334444d93782SGreg Clayton lldb::thread_result_t
334544d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
334644d93782SGreg Clayton {
334744d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
334844d93782SGreg Clayton     debugger->ExecuteIOHanders();
334944d93782SGreg Clayton     debugger->StopEventHandlerThread();
335044d93782SGreg Clayton     return NULL;
335144d93782SGreg Clayton }
335244d93782SGreg Clayton 
335344d93782SGreg Clayton bool
335444d93782SGreg Clayton Debugger::StartIOHandlerThread()
335544d93782SGreg Clayton {
3356acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
3357807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
3358807b6b32SGreg Clayton                                                             IOHandlerThread,
3359807b6b32SGreg Clayton                                                             this,
3360807b6b32SGreg Clayton                                                             NULL,
3361807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
3362acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
336344d93782SGreg Clayton }
336444d93782SGreg Clayton 
336544d93782SGreg Clayton void
336644d93782SGreg Clayton Debugger::StopIOHandlerThread()
336744d93782SGreg Clayton {
3368acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
336944d93782SGreg Clayton     {
337044d93782SGreg Clayton         if (m_input_file_sp)
337144d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
337239de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
337344d93782SGreg Clayton     }
337444d93782SGreg Clayton }
337544d93782SGreg Clayton 
337644d93782SGreg Clayton 
3377