130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
124a33d318SGreg Clayton #include "lldb/Core/Debugger.h"
134a33d318SGreg Clayton 
144a33d318SGreg Clayton #include <map>
154a33d318SGreg Clayton 
164becb37eSEnrico Granata #include "clang/AST/DeclCXX.h"
174becb37eSEnrico Granata #include "clang/AST/Type.h"
18705b1809SJason Molenda #include "llvm/ADT/StringRef.h"
194becb37eSEnrico Granata 
2030fdc8d8SChris Lattner #include "lldb/lldb-private.h"
211f746071SGreg Clayton #include "lldb/Core/Module.h"
22e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
237349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2430fdc8d8SChris Lattner #include "lldb/Core/State.h"
255b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
26228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
2744d93782SGreg Clayton #include "lldb/Core/StreamFile.h"
281b654882SGreg Clayton #include "lldb/Core/StreamString.h"
29705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
3030fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
314becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
326d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
335548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
35894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h"
3693a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h"
3742ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h"
38a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
3939de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h"
406611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
4167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
431f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
441f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
451f746071SGreg Clayton #include "lldb/Symbol/Function.h"
461f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
476d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
48aff1b357SJason Molenda #include "lldb/Target/CPPLanguageRuntime.h"
49aff1b357SJason Molenda #include "lldb/Target/ObjCLanguageRuntime.h"
5030fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
5130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
521b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
535fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h"
541b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5584a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5630fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
575a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5830fdc8d8SChris Lattner 
5958a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h"
6058a559c0SZachary Turner 
6130fdc8d8SChris Lattner using namespace lldb;
6230fdc8d8SChris Lattner using namespace lldb_private;
6330fdc8d8SChris Lattner 
6430fdc8d8SChris Lattner 
651b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
66ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
677c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
68ebc1bb27SCaroline Tice 
691b654882SGreg Clayton #pragma mark Static Functions
701b654882SGreg Clayton 
711b654882SGreg Clayton static Mutex &
721b654882SGreg Clayton GetDebuggerListMutex ()
731b654882SGreg Clayton {
741b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
751b654882SGreg Clayton     return g_mutex;
761b654882SGreg Clayton }
771b654882SGreg Clayton 
781b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
791b654882SGreg Clayton 
801b654882SGreg Clayton static DebuggerList &
811b654882SGreg Clayton GetDebuggerList()
821b654882SGreg Clayton {
831b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
846a7f3338SBruce Mitchener     // global init constructors
851b654882SGreg Clayton     static DebuggerList g_list;
861b654882SGreg Clayton     return g_list;
871b654882SGreg Clayton }
88e372b98dSGreg Clayton 
89e372b98dSGreg Clayton OptionEnumValueElement
9067cc0636SGreg Clayton g_show_disassembly_enum_values[] =
91e372b98dSGreg Clayton {
9267cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
9367cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
9467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
95e372b98dSGreg Clayton     { 0, NULL, NULL }
96e372b98dSGreg Clayton };
97e372b98dSGreg Clayton 
9867cc0636SGreg Clayton OptionEnumValueElement
9967cc0636SGreg Clayton g_language_enumerators[] =
10067cc0636SGreg Clayton {
10167cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
10267cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
10367cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
104a12993c9SGreg Clayton     { 0, NULL, NULL }
10567cc0636SGreg Clayton };
106e372b98dSGreg Clayton 
10767cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10867cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10967cc0636SGreg Clayton 
1100769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
11167cc0636SGreg Clayton     "{, ${frame.pc}}"\
11267cc0636SGreg Clayton     MODULE_WITH_FUNC\
11367cc0636SGreg Clayton     FILE_AND_LINE\
1140769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
1150769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
116705b1809SJason Molenda     "{, activity = '${thread.info.activity.name}'}" \
117705b1809SJason Molenda     "{, ${thread.info.trace_messages} messages}" \
11867cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
11967cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
12030fadafeSJim Ingham     "{\\nCompleted expression: ${thread.completed-expression}}"\
12167cc0636SGreg Clayton     "\\n"
12267cc0636SGreg Clayton 
12367cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
12467cc0636SGreg Clayton     MODULE_WITH_FUNC\
12567cc0636SGreg Clayton     FILE_AND_LINE\
12667cc0636SGreg Clayton     "\\n"
12767cc0636SGreg Clayton 
128466ffa56SJason Molenda #define DEFAULT_DISASSEMBLY_FORMAT "${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: "
12967cc0636SGreg Clayton 
130754a9369SGreg Clayton static PropertyDefinition
131754a9369SGreg Clayton g_properties[] =
13267cc0636SGreg Clayton {
13367cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
134aff1b357SJason Molenda {   "disassembly-format",       OptionValue::eTypeString , true, 0    , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
13567cc0636SGreg Clayton {   "frame-format",             OptionValue::eTypeString , true, 0    , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
13667cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1374c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
13867cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
13967cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
14067cc0636SGreg Clayton {   "stop-disassembly-display", OptionValue::eTypeEnum   , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
14167cc0636SGreg Clayton {   "stop-line-count-after",    OptionValue::eTypeSInt64 , true, 3    , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
14267cc0636SGreg Clayton {   "stop-line-count-before",   OptionValue::eTypeSInt64 , true, 3    , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
14367cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
14467cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
14567cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
146c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
14790a8db30SEnrico Granata {   "auto-one-line-summaries",  OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
148ebdc1ac0SEnrico Granata {   "escape-non-printables",    OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
149e8cd0c98SGreg Clayton 
15067cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
15167cc0636SGreg Clayton };
15267cc0636SGreg Clayton 
15367cc0636SGreg Clayton enum
15467cc0636SGreg Clayton {
15567cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
156aff1b357SJason Molenda     ePropertyDisassemblyFormat,
15767cc0636SGreg Clayton     ePropertyFrameFormat,
15867cc0636SGreg Clayton     ePropertyNotiftVoid,
15967cc0636SGreg Clayton     ePropertyPrompt,
16067cc0636SGreg Clayton     ePropertyScriptLanguage,
16167cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
16267cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
16367cc0636SGreg Clayton     ePropertyStopLineCountAfter,
16467cc0636SGreg Clayton     ePropertyStopLineCountBefore,
16567cc0636SGreg Clayton     ePropertyTerminalWidth,
16667cc0636SGreg Clayton     ePropertyThreadFormat,
167c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
168c3ce7f27SMichael Sartain     ePropertyUseColor,
169ebdc1ac0SEnrico Granata     ePropertyAutoOneLineSummaries,
170ebdc1ac0SEnrico Granata     ePropertyEscapeNonPrintables
17167cc0636SGreg Clayton };
17267cc0636SGreg Clayton 
1735fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1744c05410fSGreg Clayton 
1754c05410fSGreg Clayton Error
1764c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1774c05410fSGreg Clayton                             VarSetOperationType op,
1784c05410fSGreg Clayton                             const char *property_path,
1794c05410fSGreg Clayton                             const char *value)
1804c05410fSGreg Clayton {
18184a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
182ebdc1ac0SEnrico Granata     bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
18384a53dfbSEnrico Granata     TargetSP target_sp;
184397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
18584a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
18684a53dfbSEnrico Granata     {
18784a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
18884a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
18984a53dfbSEnrico Granata     }
1904c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1914c05410fSGreg Clayton     if (error.Success())
1924c05410fSGreg Clayton     {
19384a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
1944c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1954c05410fSGreg Clayton         {
1964c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
197c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
198c3ce7f27SMichael Sartain             if (str.length())
199c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
20044d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
2014c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
2024c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
2034c05410fSGreg Clayton         }
204c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
205c3ce7f27SMichael Sartain         {
206c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
207c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
208c3ce7f27SMichael Sartain         }
209397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
21084a53dfbSEnrico Granata         {
211397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
21284a53dfbSEnrico Granata             {
21384a53dfbSEnrico Granata                 std::list<Error> errors;
2149730339bSEnrico Granata                 StreamString feedback_stream;
2159730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
21684a53dfbSEnrico Granata                 {
21744d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
21844d93782SGreg Clayton                     if (stream_sp)
21944d93782SGreg Clayton                     {
22084a53dfbSEnrico Granata                         for (auto error : errors)
22184a53dfbSEnrico Granata                         {
22244d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
22384a53dfbSEnrico Granata                         }
2249730339bSEnrico Granata                         if (feedback_stream.GetSize())
22544d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
22644d93782SGreg Clayton                     }
22784a53dfbSEnrico Granata                 }
22884a53dfbSEnrico Granata             }
22984a53dfbSEnrico Granata         }
230ebdc1ac0SEnrico Granata         else if (is_escape_non_printables)
231ebdc1ac0SEnrico Granata         {
232ebdc1ac0SEnrico Granata             DataVisualization::ForceUpdate();
233ebdc1ac0SEnrico Granata         }
2344c05410fSGreg Clayton     }
2354c05410fSGreg Clayton     return error;
2364c05410fSGreg Clayton }
2374c05410fSGreg Clayton 
23867cc0636SGreg Clayton bool
23967cc0636SGreg Clayton Debugger::GetAutoConfirm () const
24067cc0636SGreg Clayton {
24167cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
242754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
24367cc0636SGreg Clayton }
24467cc0636SGreg Clayton 
24567cc0636SGreg Clayton const char *
246aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const
247aff1b357SJason Molenda {
248aff1b357SJason Molenda     const uint32_t idx = ePropertyDisassemblyFormat;
249aff1b357SJason Molenda     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
250aff1b357SJason Molenda }
251aff1b357SJason Molenda 
252aff1b357SJason Molenda const char *
25367cc0636SGreg Clayton Debugger::GetFrameFormat() const
25467cc0636SGreg Clayton {
25567cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
256754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
25767cc0636SGreg Clayton }
25867cc0636SGreg Clayton 
25967cc0636SGreg Clayton bool
26067cc0636SGreg Clayton Debugger::GetNotifyVoid () const
26167cc0636SGreg Clayton {
26267cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
263754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
26467cc0636SGreg Clayton }
26567cc0636SGreg Clayton 
26667cc0636SGreg Clayton const char *
26767cc0636SGreg Clayton Debugger::GetPrompt() const
26867cc0636SGreg Clayton {
26967cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
270754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
27167cc0636SGreg Clayton }
27267cc0636SGreg Clayton 
27367cc0636SGreg Clayton void
27467cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
27567cc0636SGreg Clayton {
27667cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
27767cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
27867cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
279c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
280c3ce7f27SMichael Sartain     if (str.length())
281c3ce7f27SMichael Sartain         new_prompt = str.c_str();
28244d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
28367cc0636SGreg Clayton }
28467cc0636SGreg Clayton 
28567cc0636SGreg Clayton const char *
28667cc0636SGreg Clayton Debugger::GetThreadFormat() const
28767cc0636SGreg Clayton {
28867cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
289754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
29067cc0636SGreg Clayton }
29167cc0636SGreg Clayton 
29267cc0636SGreg Clayton lldb::ScriptLanguage
29367cc0636SGreg Clayton Debugger::GetScriptLanguage() const
29467cc0636SGreg Clayton {
29567cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
296754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
29767cc0636SGreg Clayton }
29867cc0636SGreg Clayton 
29967cc0636SGreg Clayton bool
30067cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
30167cc0636SGreg Clayton {
30267cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
30367cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
30467cc0636SGreg Clayton }
30567cc0636SGreg Clayton 
30667cc0636SGreg Clayton uint32_t
30767cc0636SGreg Clayton Debugger::GetTerminalWidth () const
30867cc0636SGreg Clayton {
30967cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
310754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
31167cc0636SGreg Clayton }
31267cc0636SGreg Clayton 
31367cc0636SGreg Clayton bool
31467cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
31567cc0636SGreg Clayton {
31667cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
31767cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
31867cc0636SGreg Clayton }
31967cc0636SGreg Clayton 
32067cc0636SGreg Clayton bool
32167cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
32267cc0636SGreg Clayton {
32367cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
324754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
32567cc0636SGreg Clayton }
32667cc0636SGreg Clayton 
32767cc0636SGreg Clayton bool
32867cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
32967cc0636SGreg Clayton {
33067cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
33167cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
33267cc0636SGreg Clayton }
33367cc0636SGreg Clayton 
334c3ce7f27SMichael Sartain bool
335c3ce7f27SMichael Sartain Debugger::GetUseColor () const
336c3ce7f27SMichael Sartain {
337c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
338c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
339c3ce7f27SMichael Sartain }
340c3ce7f27SMichael Sartain 
341c3ce7f27SMichael Sartain bool
342c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
343c3ce7f27SMichael Sartain {
344c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
345c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
346c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
347c3ce7f27SMichael Sartain     return ret;
348c3ce7f27SMichael Sartain }
349c3ce7f27SMichael Sartain 
35067cc0636SGreg Clayton uint32_t
35167cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
35267cc0636SGreg Clayton {
35367cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
354754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
35567cc0636SGreg Clayton }
35667cc0636SGreg Clayton 
35767cc0636SGreg Clayton Debugger::StopDisassemblyType
35867cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
35967cc0636SGreg Clayton {
36067cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
361754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
36267cc0636SGreg Clayton }
36367cc0636SGreg Clayton 
36467cc0636SGreg Clayton uint32_t
36567cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
36667cc0636SGreg Clayton {
36767cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
368754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
36967cc0636SGreg Clayton }
370e372b98dSGreg Clayton 
371553fad5cSEnrico Granata bool
37290a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
373553fad5cSEnrico Granata {
37490a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
375553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
376ebdc1ac0SEnrico Granata }
377553fad5cSEnrico Granata 
378ebdc1ac0SEnrico Granata bool
379ebdc1ac0SEnrico Granata Debugger::GetEscapeNonPrintables () const
380ebdc1ac0SEnrico Granata {
381ebdc1ac0SEnrico Granata     const uint32_t idx = ePropertyEscapeNonPrintables;
382ebdc1ac0SEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
383553fad5cSEnrico Granata }
384553fad5cSEnrico Granata 
3851b654882SGreg Clayton #pragma mark Debugger
3861b654882SGreg Clayton 
38767cc0636SGreg Clayton //const DebuggerPropertiesSP &
38867cc0636SGreg Clayton //Debugger::GetSettings() const
38967cc0636SGreg Clayton //{
39067cc0636SGreg Clayton //    return m_properties_sp;
39167cc0636SGreg Clayton //}
39267cc0636SGreg Clayton //
39399d0faf2SGreg Clayton 
3942f88aadfSCaroline Tice int
3952f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3962f88aadfSCaroline Tice {
3972f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3982f88aadfSCaroline Tice }
3992f88aadfSCaroline Tice 
40030fdc8d8SChris Lattner void
4015fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
40230fdc8d8SChris Lattner {
4035fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
404c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
405dbe54508SGreg Clayton         lldb_private::Initialize();
40699d0faf2SGreg Clayton }
40730fdc8d8SChris Lattner 
40830fdc8d8SChris Lattner void
40930fdc8d8SChris Lattner Debugger::Terminate ()
41030fdc8d8SChris Lattner {
4116611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
4126611103cSGreg Clayton     {
41330fdc8d8SChris Lattner         g_shared_debugger_refcount--;
41430fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
41530fdc8d8SChris Lattner         {
416dbe54508SGreg Clayton             lldb_private::WillTerminate();
417dbe54508SGreg Clayton             lldb_private::Terminate();
4186760a517SCaroline Tice 
41999d0faf2SGreg Clayton             // Clear our master list of debugger objects
42099d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
42199d0faf2SGreg Clayton             GetDebuggerList().clear();
42230fdc8d8SChris Lattner         }
4236760a517SCaroline Tice     }
4246760a517SCaroline Tice }
42530fdc8d8SChris Lattner 
42620bd37f7SCaroline Tice void
42720bd37f7SCaroline Tice Debugger::SettingsInitialize ()
42820bd37f7SCaroline Tice {
4296920b52bSGreg Clayton     Target::SettingsInitialize ();
43020bd37f7SCaroline Tice }
43120bd37f7SCaroline Tice 
43220bd37f7SCaroline Tice void
43320bd37f7SCaroline Tice Debugger::SettingsTerminate ()
43420bd37f7SCaroline Tice {
4356920b52bSGreg Clayton     Target::SettingsTerminate ();
43620bd37f7SCaroline Tice }
43720bd37f7SCaroline Tice 
43821dfcd9dSEnrico Granata bool
439e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
44021dfcd9dSEnrico Granata {
4415fb8f797SGreg Clayton     if (g_load_plugin_callback)
442e743c782SEnrico Granata     {
44358a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
44458a559c0SZachary Turner         if (dynlib.isValid())
44521dfcd9dSEnrico Granata         {
44658a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
44721dfcd9dSEnrico Granata             return true;
44821dfcd9dSEnrico Granata         }
4495fb8f797SGreg Clayton     }
4505fb8f797SGreg Clayton     else
4515fb8f797SGreg Clayton     {
4525fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4535fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4545fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4555fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4565fb8f797SGreg Clayton     }
45721dfcd9dSEnrico Granata     return false;
45821dfcd9dSEnrico Granata }
45921dfcd9dSEnrico Granata 
46021dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
46121dfcd9dSEnrico Granata LoadPluginCallback
46221dfcd9dSEnrico Granata (
46321dfcd9dSEnrico Granata  void *baton,
46421dfcd9dSEnrico Granata  FileSpec::FileType file_type,
46521dfcd9dSEnrico Granata  const FileSpec &file_spec
46621dfcd9dSEnrico Granata  )
46721dfcd9dSEnrico Granata {
46821dfcd9dSEnrico Granata     Error error;
46921dfcd9dSEnrico Granata 
47021dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4713cf443ddSMichael Sartain     static ConstString g_solibext("so");
47221dfcd9dSEnrico Granata 
47321dfcd9dSEnrico Granata     if (!baton)
47421dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
47521dfcd9dSEnrico Granata 
47621dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
47721dfcd9dSEnrico Granata 
47821dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
47921dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
48021dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
48121dfcd9dSEnrico Granata     // file type information.
48221dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
48321dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
48421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
48521dfcd9dSEnrico Granata     {
48621dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
48721dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
48821dfcd9dSEnrico Granata 
4893cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4903cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4913cf443ddSMichael Sartain         {
49221dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4933cf443ddSMichael Sartain         }
49421dfcd9dSEnrico Granata 
495e743c782SEnrico Granata         Error plugin_load_error;
496e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
49721dfcd9dSEnrico Granata 
49821dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
49921dfcd9dSEnrico Granata     }
50021dfcd9dSEnrico Granata 
50121dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
50221dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
50321dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
50421dfcd9dSEnrico Granata     {
50521dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
50621dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
5076a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
50821dfcd9dSEnrico Granata         // information.
50921dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
51021dfcd9dSEnrico Granata     }
51121dfcd9dSEnrico Granata 
51221dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
51321dfcd9dSEnrico Granata }
51421dfcd9dSEnrico Granata 
51521dfcd9dSEnrico Granata void
51621dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
51721dfcd9dSEnrico Granata {
51821dfcd9dSEnrico Granata     FileSpec dir_spec;
51921dfcd9dSEnrico Granata     const bool find_directories = true;
52021dfcd9dSEnrico Granata     const bool find_files = true;
52121dfcd9dSEnrico Granata     const bool find_other = true;
52221dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
52342ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
52421dfcd9dSEnrico Granata     {
52521dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
52621dfcd9dSEnrico Granata         {
52721dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
52821dfcd9dSEnrico Granata                                           find_directories,
52921dfcd9dSEnrico Granata                                           find_files,
53021dfcd9dSEnrico Granata                                           find_other,
53121dfcd9dSEnrico Granata                                           LoadPluginCallback,
53221dfcd9dSEnrico Granata                                           this);
53321dfcd9dSEnrico Granata         }
53421dfcd9dSEnrico Granata     }
53521dfcd9dSEnrico Granata 
53642ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
53721dfcd9dSEnrico Granata     {
53821dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
53921dfcd9dSEnrico Granata         {
54021dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
54121dfcd9dSEnrico Granata                                           find_directories,
54221dfcd9dSEnrico Granata                                           find_files,
54321dfcd9dSEnrico Granata                                           find_other,
54421dfcd9dSEnrico Granata                                           LoadPluginCallback,
54521dfcd9dSEnrico Granata                                           this);
54621dfcd9dSEnrico Granata         }
54721dfcd9dSEnrico Granata     }
548e8cd0c98SGreg Clayton 
549e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
55021dfcd9dSEnrico Granata }
55121dfcd9dSEnrico Granata 
5526611103cSGreg Clayton DebuggerSP
553228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5546611103cSGreg Clayton {
555228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
556c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5576611103cSGreg Clayton     {
5586611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5596611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5606611103cSGreg Clayton     }
56121dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5626611103cSGreg Clayton     return debugger_sp;
5636611103cSGreg Clayton }
5646611103cSGreg Clayton 
565e02657b1SCaroline Tice void
5664d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
567e02657b1SCaroline Tice {
568e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
569e02657b1SCaroline Tice         return;
570e02657b1SCaroline Tice 
5718314c525SJim Ingham     debugger_sp->Clear();
5728314c525SJim Ingham 
573c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
574c15f55e2SGreg Clayton     {
575e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
576e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
577e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
578e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
579e02657b1SCaroline Tice         {
580e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
581e02657b1SCaroline Tice             {
582e02657b1SCaroline Tice                 debugger_list.erase (pos);
583e02657b1SCaroline Tice                 return;
584e02657b1SCaroline Tice             }
585e02657b1SCaroline Tice         }
586e02657b1SCaroline Tice     }
587c15f55e2SGreg Clayton }
588e02657b1SCaroline Tice 
5894d122c40SGreg Clayton DebuggerSP
5903df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5913df9a8dfSCaroline Tice {
5924d122c40SGreg Clayton     DebuggerSP debugger_sp;
5936920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5946920b52bSGreg Clayton     {
5956920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5966920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5976920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5986920b52bSGreg Clayton 
5996920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6006920b52bSGreg Clayton         {
6016920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
6026920b52bSGreg Clayton             {
6036920b52bSGreg Clayton                 debugger_sp = *pos;
6046920b52bSGreg Clayton                 break;
6056920b52bSGreg Clayton             }
6066920b52bSGreg Clayton         }
6076920b52bSGreg Clayton     }
6083df9a8dfSCaroline Tice     return debugger_sp;
6093df9a8dfSCaroline Tice }
6106611103cSGreg Clayton 
6116611103cSGreg Clayton TargetSP
6126611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6136611103cSGreg Clayton {
6144d122c40SGreg Clayton     TargetSP target_sp;
615c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
616c15f55e2SGreg Clayton     {
6176611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6186611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6196611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6206611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6216611103cSGreg Clayton         {
6226611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6236611103cSGreg Clayton             if (target_sp)
6246611103cSGreg Clayton                 break;
6256611103cSGreg Clayton         }
626c15f55e2SGreg Clayton     }
6276611103cSGreg Clayton     return target_sp;
6286611103cSGreg Clayton }
6296611103cSGreg Clayton 
630e4e45924SGreg Clayton TargetSP
631e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
632e4e45924SGreg Clayton {
633e4e45924SGreg Clayton     TargetSP target_sp;
634c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
635c15f55e2SGreg Clayton     {
636e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
637e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
638e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
639e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
640e4e45924SGreg Clayton         {
641e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
642e4e45924SGreg Clayton             if (target_sp)
643e4e45924SGreg Clayton                 break;
644e4e45924SGreg Clayton         }
645c15f55e2SGreg Clayton     }
646e4e45924SGreg Clayton     return target_sp;
647e4e45924SGreg Clayton }
648e4e45924SGreg Clayton 
649e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
650e6481c7eSJason Molenda     UserID(g_unique_id++),
651e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
652e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
653e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
654e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
655e6481c7eSJason Molenda     m_terminal_state(),
656e6481c7eSJason Molenda     m_target_list(*this),
657e6481c7eSJason Molenda     m_platform_list(),
658e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
659e6481c7eSJason Molenda     m_source_manager_ap(),
660e6481c7eSJason Molenda     m_source_file_cache(),
661e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
662e6481c7eSJason Molenda     m_input_reader_stack(),
663e6481c7eSJason Molenda     m_instance_name(),
664afa91e33SGreg Clayton     m_loaded_plugins(),
665afa91e33SGreg Clayton     m_event_handler_thread (),
666afa91e33SGreg Clayton     m_io_handler_thread (),
667afa91e33SGreg Clayton     m_sync_broadcaster (NULL, "lldb.debugger.sync")
66830fdc8d8SChris Lattner {
66967cc0636SGreg Clayton     char instance_cstr[256];
67067cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
67167cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
672228063cdSJim Ingham     if (log_callback)
673228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6746611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
675ded470d3SGreg Clayton     // Always add our default platform to the platform list
676615eb7e6SGreg Clayton     PlatformSP default_platform_sp (Platform::GetHostPlatform());
677ded470d3SGreg Clayton     assert (default_platform_sp.get());
678ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
67967cc0636SGreg Clayton 
680754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
68167cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
68267cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
68367cc0636SGreg Clayton                                      true,
68467cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
685754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
686754a9369SGreg Clayton     {
687754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
688754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
689754a9369SGreg Clayton                                          true,
690754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
691754a9369SGreg Clayton     }
69267cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
69367cc0636SGreg Clayton     term_width->SetMinimumValue(10);
69467cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
695c3ce7f27SMichael Sartain 
696c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
697c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
698c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
699c3ce7f27SMichael Sartain         SetUseColor (false);
70030fdc8d8SChris Lattner }
70130fdc8d8SChris Lattner 
70230fdc8d8SChris Lattner Debugger::~Debugger ()
70330fdc8d8SChris Lattner {
7048314c525SJim Ingham     Clear();
7058314c525SJim Ingham }
7068314c525SJim Ingham 
7078314c525SJim Ingham void
7088314c525SJim Ingham Debugger::Clear()
7098314c525SJim Ingham {
71044d93782SGreg Clayton     ClearIOHandlers();
71144d93782SGreg Clayton     StopIOHandlerThread();
71244d93782SGreg Clayton     StopEventHandlerThread();
7131ed54f50SGreg Clayton     m_listener.Clear();
7146611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
7156611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7166611103cSGreg Clayton     {
717ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
718ccbc08e6SGreg Clayton         if (target_sp)
719ccbc08e6SGreg Clayton         {
720ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7216611103cSGreg Clayton             if (process_sp)
7221fd07059SJim Ingham                 process_sp->Finalize();
723ccbc08e6SGreg Clayton             target_sp->Destroy();
7246611103cSGreg Clayton         }
72530fdc8d8SChris Lattner     }
7264bddaeb5SJim Ingham     BroadcasterManager::Clear ();
72730fdc8d8SChris Lattner 
7280d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7290d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
730c5917d9aSJim Ingham     m_terminal_state.Clear();
73144d93782SGreg Clayton     if (m_input_file_sp)
73244d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7330c4129f2SGreg Clayton 
7340c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7358314c525SJim Ingham }
73630fdc8d8SChris Lattner 
73730fdc8d8SChris Lattner bool
738fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
739fc3f027dSGreg Clayton {
74044d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
74144d93782SGreg Clayton     return false;
742fc3f027dSGreg Clayton }
743fc3f027dSGreg Clayton 
744fc3f027dSGreg Clayton void
745fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
746fc3f027dSGreg Clayton {
74744d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
748fc3f027dSGreg Clayton }
749fc3f027dSGreg Clayton 
750fc3f027dSGreg Clayton bool
75130fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
75230fdc8d8SChris Lattner {
7536611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
75430fdc8d8SChris Lattner }
75530fdc8d8SChris Lattner 
75630fdc8d8SChris Lattner void
75730fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
75830fdc8d8SChris Lattner {
7596611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
76030fdc8d8SChris Lattner }
76130fdc8d8SChris Lattner 
76230fdc8d8SChris Lattner 
76330fdc8d8SChris Lattner void
76430fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
76530fdc8d8SChris Lattner {
76644d93782SGreg Clayton     if (m_input_file_sp)
76744d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
76844d93782SGreg Clayton     else
76944d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
77044d93782SGreg Clayton 
77144d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
77251b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
77351b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
77430fdc8d8SChris Lattner 
775c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
776c5917d9aSJim Ingham     SaveInputTerminalState ();
77730fdc8d8SChris Lattner }
77830fdc8d8SChris Lattner 
77930fdc8d8SChris Lattner void
78030fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
78130fdc8d8SChris Lattner {
78244d93782SGreg Clayton     if (m_output_file_sp)
78344d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
78444d93782SGreg Clayton     else
78544d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
78644d93782SGreg Clayton 
78744d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
78851b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
78951b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7902f88aadfSCaroline Tice 
791b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
792b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
793b588726eSEnrico Granata     const bool can_create = false;
794b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
795b588726eSEnrico Granata     if (script_interpreter)
796b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
79730fdc8d8SChris Lattner }
79830fdc8d8SChris Lattner 
79930fdc8d8SChris Lattner void
80030fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
80130fdc8d8SChris Lattner {
80244d93782SGreg Clayton     if (m_error_file_sp)
80344d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
80444d93782SGreg Clayton     else
80544d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
80644d93782SGreg Clayton 
80744d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
80851b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
80951b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
81030fdc8d8SChris Lattner }
81130fdc8d8SChris Lattner 
812c5917d9aSJim Ingham void
813c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
814c5917d9aSJim Ingham {
81544d93782SGreg Clayton     if (m_input_file_sp)
81644d93782SGreg Clayton     {
81744d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
818c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
819c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
820c5917d9aSJim Ingham     }
82144d93782SGreg Clayton }
822c5917d9aSJim Ingham 
823c5917d9aSJim Ingham void
824c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
825c5917d9aSJim Ingham {
826c5917d9aSJim Ingham     m_terminal_state.Restore();
827c5917d9aSJim Ingham }
828c5917d9aSJim Ingham 
82930fdc8d8SChris Lattner ExecutionContext
8302976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
83130fdc8d8SChris Lattner {
83230fdc8d8SChris Lattner     ExecutionContext exe_ctx;
833c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
834c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
83530fdc8d8SChris Lattner 
83630fdc8d8SChris Lattner     if (target_sp)
83730fdc8d8SChris Lattner     {
838c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
839c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
840c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
84130fdc8d8SChris Lattner         {
842c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
843c14ee32dSGreg Clayton             if (thread_sp)
84430fdc8d8SChris Lattner             {
845c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
846c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
847c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
848c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
84930fdc8d8SChris Lattner             }
85030fdc8d8SChris Lattner         }
85130fdc8d8SChris Lattner     }
85230fdc8d8SChris Lattner     return exe_ctx;
85330fdc8d8SChris Lattner }
85430fdc8d8SChris Lattner 
85530fdc8d8SChris Lattner void
856efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
857efed6131SCaroline Tice {
85844d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
85944d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
860efed6131SCaroline Tice     if (reader_sp)
86144d93782SGreg Clayton         reader_sp->Interrupt();
862efed6131SCaroline Tice }
863efed6131SCaroline Tice 
864efed6131SCaroline Tice void
865efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
866efed6131SCaroline Tice {
86744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
86844d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
869efed6131SCaroline Tice     if (reader_sp)
87044d93782SGreg Clayton         reader_sp->GotEOF();
871efed6131SCaroline Tice }
872efed6131SCaroline Tice 
873efed6131SCaroline Tice void
87444d93782SGreg Clayton Debugger::ClearIOHandlers ()
8753d6086f6SCaroline Tice {
876b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
87744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
878d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8793d6086f6SCaroline Tice     {
88044d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8813d6086f6SCaroline Tice         if (reader_sp)
8823d6086f6SCaroline Tice         {
88344d93782SGreg Clayton             m_input_reader_stack.Pop();
8843d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
885e68f5d6bSGreg Clayton             reader_sp->Cancel();
8863d6086f6SCaroline Tice         }
8873d6086f6SCaroline Tice     }
8883d6086f6SCaroline Tice }
8893d6086f6SCaroline Tice 
8903d6086f6SCaroline Tice void
89144d93782SGreg Clayton Debugger::ExecuteIOHanders()
892969ed3d1SCaroline Tice {
89344d93782SGreg Clayton 
89444d93782SGreg Clayton     while (1)
895969ed3d1SCaroline Tice     {
89644d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
89730fdc8d8SChris Lattner         if (!reader_sp)
89830fdc8d8SChris Lattner             break;
89930fdc8d8SChris Lattner 
90044d93782SGreg Clayton         reader_sp->Activate();
90144d93782SGreg Clayton         reader_sp->Run();
90244d93782SGreg Clayton         reader_sp->Deactivate();
90344d93782SGreg Clayton 
90444d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
90544d93782SGreg Clayton         while (1)
90630fdc8d8SChris Lattner         {
90744d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
90844d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
90944d93782SGreg Clayton                 m_input_reader_stack.Pop();
91030fdc8d8SChris Lattner             else
91130fdc8d8SChris Lattner                 break;
91230fdc8d8SChris Lattner         }
91330fdc8d8SChris Lattner     }
91444d93782SGreg Clayton     ClearIOHandlers();
91544d93782SGreg Clayton }
91630fdc8d8SChris Lattner 
91744d93782SGreg Clayton bool
91844d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
91944d93782SGreg Clayton {
92044d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
92144d93782SGreg Clayton }
92230fdc8d8SChris Lattner 
92344d93782SGreg Clayton 
92444d93782SGreg Clayton ConstString
92544d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
92644d93782SGreg Clayton {
92744d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
92830fdc8d8SChris Lattner }
92930fdc8d8SChris Lattner 
93030fdc8d8SChris Lattner void
93144d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
93244d93782SGreg Clayton {
93344d93782SGreg Clayton     PushIOHandler (reader_sp);
934577508dfSGreg Clayton 
935577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
936577508dfSGreg Clayton     while (top_reader_sp)
937577508dfSGreg Clayton     {
938577508dfSGreg Clayton         top_reader_sp->Activate();
939577508dfSGreg Clayton         top_reader_sp->Run();
940577508dfSGreg Clayton         top_reader_sp->Deactivate();
941577508dfSGreg Clayton 
942577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
943577508dfSGreg Clayton         {
944577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
945577508dfSGreg Clayton                 break;
946577508dfSGreg Clayton         }
947577508dfSGreg Clayton 
948577508dfSGreg Clayton         while (1)
949577508dfSGreg Clayton         {
950577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
951577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
952577508dfSGreg Clayton                 m_input_reader_stack.Pop();
953577508dfSGreg Clayton             else
954577508dfSGreg Clayton                 break;
955577508dfSGreg Clayton         }
956577508dfSGreg Clayton     }
95744d93782SGreg Clayton }
95844d93782SGreg Clayton 
95944d93782SGreg Clayton void
96044d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
96144d93782SGreg Clayton {
96244d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
96344d93782SGreg Clayton     // This function is called when one ore more of the streams
96444d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
96544d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
96644d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
96744d93782SGreg Clayton 
96844d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
96944d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
97044d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
97144d93782SGreg Clayton     if (!in)
97244d93782SGreg Clayton     {
97344d93782SGreg Clayton         if (top_reader_sp)
97444d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
97544d93782SGreg Clayton         else
97644d93782SGreg Clayton             in = GetInputFile();
97744d93782SGreg Clayton 
97844d93782SGreg Clayton         // If there is nothing, use stdin
97944d93782SGreg Clayton         if (!in)
98044d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
98144d93782SGreg Clayton     }
98244d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
98344d93782SGreg Clayton     if (!out)
98444d93782SGreg Clayton     {
98544d93782SGreg Clayton         if (top_reader_sp)
98644d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
98744d93782SGreg Clayton         else
98844d93782SGreg Clayton             out = GetOutputFile();
98944d93782SGreg Clayton 
99044d93782SGreg Clayton         // If there is nothing, use stdout
99144d93782SGreg Clayton         if (!out)
99244d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
99344d93782SGreg Clayton     }
99444d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
99544d93782SGreg Clayton     if (!err)
99644d93782SGreg Clayton     {
99744d93782SGreg Clayton         if (top_reader_sp)
99844d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
99944d93782SGreg Clayton         else
100044d93782SGreg Clayton             err = GetErrorFile();
100144d93782SGreg Clayton 
100244d93782SGreg Clayton         // If there is nothing, use stderr
100344d93782SGreg Clayton         if (!err)
100444d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
100544d93782SGreg Clayton 
100644d93782SGreg Clayton     }
100744d93782SGreg Clayton }
100844d93782SGreg Clayton 
100944d93782SGreg Clayton void
101044d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
101130fdc8d8SChris Lattner {
101230fdc8d8SChris Lattner     if (!reader_sp)
101330fdc8d8SChris Lattner         return;
1014b44880caSCaroline Tice 
101544d93782SGreg Clayton     // Got the current top input reader...
101644d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1017b44880caSCaroline Tice 
1018b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
1019b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
1020b4874f1aSGreg Clayton     {
102144d93782SGreg Clayton         // Push our new input reader
1022d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
102344d93782SGreg Clayton 
102444d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
102544d93782SGreg Clayton         // and let this new input reader take over
102644d93782SGreg Clayton         if (top_reader_sp)
102744d93782SGreg Clayton             top_reader_sp->Deactivate();
102830fdc8d8SChris Lattner     }
1029b4874f1aSGreg Clayton }
103030fdc8d8SChris Lattner 
103130fdc8d8SChris Lattner bool
103244d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
103330fdc8d8SChris Lattner {
103430fdc8d8SChris Lattner     bool result = false;
103530fdc8d8SChris Lattner 
103644d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
103744d93782SGreg Clayton 
103830fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10396a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
1040d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
104130fdc8d8SChris Lattner     {
104244d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
104330fdc8d8SChris Lattner 
104430fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
104530fdc8d8SChris Lattner         {
104644d93782SGreg Clayton             reader_sp->Deactivate();
1047b4874f1aSGreg Clayton             reader_sp->Cancel();
1048d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
104930fdc8d8SChris Lattner 
1050d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
105130fdc8d8SChris Lattner             if (reader_sp)
105244d93782SGreg Clayton                 reader_sp->Activate();
105344d93782SGreg Clayton 
105444d93782SGreg Clayton             result = true;
105530fdc8d8SChris Lattner         }
105630fdc8d8SChris Lattner     }
105730fdc8d8SChris Lattner     return result;
105830fdc8d8SChris Lattner }
105930fdc8d8SChris Lattner 
106030fdc8d8SChris Lattner bool
106144d93782SGreg Clayton Debugger::HideTopIOHandler()
106230fdc8d8SChris Lattner {
106344d93782SGreg Clayton     Mutex::Locker locker;
106430fdc8d8SChris Lattner 
106544d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
106630fdc8d8SChris Lattner     {
106744d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
106844d93782SGreg Clayton         if (reader_sp)
106944d93782SGreg Clayton             reader_sp->Hide();
107044d93782SGreg Clayton         return true;
107130fdc8d8SChris Lattner     }
107244d93782SGreg Clayton     return false;
107330fdc8d8SChris Lattner }
107430fdc8d8SChris Lattner 
107530fdc8d8SChris Lattner void
107644d93782SGreg Clayton Debugger::RefreshTopIOHandler()
107730fdc8d8SChris Lattner {
107844d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
107944d93782SGreg Clayton     if (reader_sp)
108044d93782SGreg Clayton         reader_sp->Refresh();
108130fdc8d8SChris Lattner }
108244d93782SGreg Clayton 
10836611103cSGreg Clayton 
10845b52f0c7SJim Ingham StreamSP
10855b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10865b52f0c7SJim Ingham {
10875b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10885b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10895b52f0c7SJim Ingham }
10905b52f0c7SJim Ingham 
10915b52f0c7SJim Ingham StreamSP
10925b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10935b52f0c7SJim Ingham {
10945b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10955b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10965b52f0c7SJim Ingham }
10975b52f0c7SJim Ingham 
1098c7bece56SGreg Clayton size_t
1099061858ceSEnrico Granata Debugger::GetNumDebuggers()
1100061858ceSEnrico Granata {
1101c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1102c15f55e2SGreg Clayton     {
1103061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1104061858ceSEnrico Granata         return GetDebuggerList().size();
1105061858ceSEnrico Granata     }
1106c15f55e2SGreg Clayton     return 0;
1107c15f55e2SGreg Clayton }
1108061858ceSEnrico Granata 
1109061858ceSEnrico Granata lldb::DebuggerSP
1110c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1111061858ceSEnrico Granata {
1112061858ceSEnrico Granata     DebuggerSP debugger_sp;
1113061858ceSEnrico Granata 
1114c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1115c15f55e2SGreg Clayton     {
1116061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1117061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1118061858ceSEnrico Granata 
1119061858ceSEnrico Granata         if (index < debugger_list.size())
1120061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1121c15f55e2SGreg Clayton     }
1122061858ceSEnrico Granata 
1123061858ceSEnrico Granata     return debugger_sp;
1124061858ceSEnrico Granata }
1125061858ceSEnrico Granata 
1126ebc1bb27SCaroline Tice DebuggerSP
1127ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1128ebc1bb27SCaroline Tice {
11294d122c40SGreg Clayton     DebuggerSP debugger_sp;
1130ebc1bb27SCaroline Tice 
1131c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1132c15f55e2SGreg Clayton     {
1133ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1134ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1135ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1136ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1137ebc1bb27SCaroline Tice         {
1138ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1139ebc1bb27SCaroline Tice             {
1140ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1141ebc1bb27SCaroline Tice                 break;
1142ebc1bb27SCaroline Tice             }
1143ebc1bb27SCaroline Tice         }
1144c15f55e2SGreg Clayton     }
1145ebc1bb27SCaroline Tice     return debugger_sp;
1146ebc1bb27SCaroline Tice }
11473df9a8dfSCaroline Tice 
11482643b905SSaleem Abdulrasool #if 0
11491b654882SGreg Clayton static void
1150b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11511b654882SGreg Clayton {
11521b654882SGreg Clayton     if (frame == NULL)
11531b654882SGreg Clayton         return;
11541b654882SGreg Clayton 
11551b654882SGreg Clayton     StreamString s;
11561b654882SGreg Clayton     const char *prompt_format =
11571b654882SGreg Clayton     "{addr = '${addr}'\n}"
1158aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1159aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
11601b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11611b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11621b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11631b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11641b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11651b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11661b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11671b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11681b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11691b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11701b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11711b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11721b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11731b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11741b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11751b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11761b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11771b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11781b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11791b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11801b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11811b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11821b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11831b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11841b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11851b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11861b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1187aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1188aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
11891b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1190aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1191ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11921b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1193aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
11941b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11951b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11961b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11971b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11981b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11991b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
12001b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
12011b654882SGreg Clayton ;
12021b654882SGreg Clayton 
12031b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
12041b654882SGreg Clayton     ExecutionContext exe_ctx;
12050603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1206c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
12071b654882SGreg Clayton     {
12081b654882SGreg Clayton         printf("%s\n", s.GetData());
12091b654882SGreg Clayton     }
12101b654882SGreg Clayton     else
12111b654882SGreg Clayton     {
12121b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
12131b654882SGreg Clayton     }
12141b654882SGreg Clayton }
12152643b905SSaleem Abdulrasool #endif
12161b654882SGreg Clayton 
12179fc1944eSEnrico Granata static bool
12189fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
12199fc1944eSEnrico Granata                       const char* var_name_end,
12209fc1944eSEnrico Granata                       const char** var_name_final,
12219fc1944eSEnrico Granata                       const char** percent_position,
12224d122c40SGreg Clayton                       Format* custom_format,
12239fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
12249fc1944eSEnrico Granata {
12255160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12269fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
12279fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1228e992a089SEnrico Granata     {
1229e992a089SEnrico Granata         if (log)
1230d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
12319fc1944eSEnrico Granata         *var_name_final = var_name_end;
1232e992a089SEnrico Granata     }
12339fc1944eSEnrico Granata     else
12349fc1944eSEnrico Granata     {
12359fc1944eSEnrico Granata         *var_name_final = *percent_position;
123636aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1237e992a089SEnrico Granata         if (log)
123868ae4117SEnrico Granata             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
123936aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
12409fc1944eSEnrico Granata                                                   true,
12419fc1944eSEnrico Granata                                                   *custom_format) )
12429fc1944eSEnrico Granata         {
1243e992a089SEnrico Granata             if (log)
124468ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
124536aa5ae6SEnrico Granata 
124636aa5ae6SEnrico Granata             switch (format_name.front())
124736aa5ae6SEnrico Granata             {
124836aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
124986cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
125036aa5ae6SEnrico Granata                     break;
125136aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
125286cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
125336aa5ae6SEnrico Granata                     break;
125436aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
125586cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
125636aa5ae6SEnrico Granata                     break;
125736aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
125886cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
125936aa5ae6SEnrico Granata                     break;
126036aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
126186cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
126236aa5ae6SEnrico Granata                     break;
126336aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
126486cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
126536aa5ae6SEnrico Granata                     break;
12662c75f11eSEnrico Granata                 case 'N': // if this is a 'N', print the name
12672c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
12682c75f11eSEnrico Granata                     break;
12692c75f11eSEnrico Granata                 case '>': // if this is a '>', print the name
12702c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
12712c75f11eSEnrico Granata                     break;
127236aa5ae6SEnrico Granata                 default:
12735c42d8a8SJim Ingham                     if (log)
127436aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
127536aa5ae6SEnrico Granata                     break;
127636aa5ae6SEnrico Granata             }
12779fc1944eSEnrico Granata         }
12789fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
12799fc1944eSEnrico Granata         else
1280e992a089SEnrico Granata         {
1281e992a089SEnrico Granata             if (log)
128268ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
128386cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1284e992a089SEnrico Granata         }
12859fc1944eSEnrico Granata     }
1286e992a089SEnrico Granata     if (log)
128768ae4117SEnrico Granata         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1288e992a089SEnrico Granata                     *custom_format,
1289e992a089SEnrico Granata                     *val_obj_display);
12909fc1944eSEnrico Granata     return true;
12919fc1944eSEnrico Granata }
12929fc1944eSEnrico Granata 
12939fc1944eSEnrico Granata static bool
12949fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
12959fc1944eSEnrico Granata                     const char* var_name_end,
12969fc1944eSEnrico Granata                     const char* var_name_final,
12979fc1944eSEnrico Granata                     const char** open_bracket_position,
12989fc1944eSEnrico Granata                     const char** separator_position,
12999fc1944eSEnrico Granata                     const char** close_bracket_position,
13009fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
13019fc1944eSEnrico Granata                     int64_t* index_lower,
13029fc1944eSEnrico Granata                     int64_t* index_higher)
13039fc1944eSEnrico Granata {
13045160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
13059fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
13069fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
13079fc1944eSEnrico Granata     {
13089fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
13099fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
13109fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
13119fc1944eSEnrico Granata         //printf("trying to expand a []\n");
13129fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
13139fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
13149fc1944eSEnrico Granata         {
1315e992a089SEnrico Granata             if (log)
1316d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
13179fc1944eSEnrico Granata             *index_lower = 0;
13189fc1944eSEnrico Granata         }
13199fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
13209fc1944eSEnrico Granata         {
13219fc1944eSEnrico Granata             char *end = NULL;
13229fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13239fc1944eSEnrico Granata             *index_higher = *index_lower;
1324e992a089SEnrico Granata             if (log)
1325d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
13269fc1944eSEnrico Granata         }
13279fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
13289fc1944eSEnrico Granata         {
13299fc1944eSEnrico Granata             char *end = NULL;
13309fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13319fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1332e992a089SEnrico Granata             if (log)
1333d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
13349fc1944eSEnrico Granata         }
13359fc1944eSEnrico Granata         else
1336e992a089SEnrico Granata         {
1337e992a089SEnrico Granata             if (log)
1338d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
13399fc1944eSEnrico Granata             return false;
1340e992a089SEnrico Granata         }
13419fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
13429fc1944eSEnrico Granata         {
1343e992a089SEnrico Granata             if (log)
1344d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1345c7bece56SGreg Clayton             int64_t temp = *index_lower;
13469fc1944eSEnrico Granata             *index_lower = *index_higher;
13479fc1944eSEnrico Granata             *index_higher = temp;
13489fc1944eSEnrico Granata         }
13499fc1944eSEnrico Granata     }
1350e992a089SEnrico Granata     else if (log)
1351d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
13529fc1944eSEnrico Granata     return true;
13539fc1944eSEnrico Granata }
13549fc1944eSEnrico Granata 
13550769b2b1SMichael Sartain template <typename T>
13560769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
13570769b2b1SMichael Sartain {
13580769b2b1SMichael Sartain     if (script_interpreter)
13590769b2b1SMichael Sartain     {
13600769b2b1SMichael Sartain         Error script_error;
13610769b2b1SMichael Sartain         std::string script_output;
13620769b2b1SMichael Sartain 
13630769b2b1SMichael Sartain         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
13640769b2b1SMichael Sartain         {
13650769b2b1SMichael Sartain             s.Printf("%s", script_output.c_str());
13660769b2b1SMichael Sartain             return true;
13670769b2b1SMichael Sartain         }
13680769b2b1SMichael Sartain         else
13690769b2b1SMichael Sartain         {
13700769b2b1SMichael Sartain             s.Printf("<error: %s>",script_error.AsCString());
13710769b2b1SMichael Sartain         }
13720769b2b1SMichael Sartain     }
13730769b2b1SMichael Sartain     return false;
13740769b2b1SMichael Sartain }
13750769b2b1SMichael Sartain 
13769fc1944eSEnrico Granata static ValueObjectSP
1377c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1378c7bece56SGreg Clayton                          size_t index,
1379b57e4a1bSJason Molenda                          StackFrame* frame,
1380fc7a7f3bSEnrico Granata                          bool deref_pointer)
13819fc1944eSEnrico Granata {
13825160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1383fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1384599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1385599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1386e992a089SEnrico Granata     if (log)
1387599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1388fc7a7f3bSEnrico Granata     const char* first_unparsed;
1389fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1390fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1391fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
139286cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1393599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1394fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1395fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1396fc7a7f3bSEnrico Granata                                                           &final_value_type,
1397fc7a7f3bSEnrico Granata                                                           options,
1398fc7a7f3bSEnrico Granata                                                           &what_next);
1399fc7a7f3bSEnrico Granata     if (!item)
1400fc7a7f3bSEnrico Granata     {
1401e992a089SEnrico Granata         if (log)
1402d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1403e992a089SEnrico Granata                " final_value_type %d",
1404fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1405fc7a7f3bSEnrico Granata     }
14069fc1944eSEnrico Granata     else
14079fc1944eSEnrico Granata     {
1408e992a089SEnrico Granata         if (log)
1409d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1410e992a089SEnrico Granata                " final_value_type %d",
1411fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
14129fc1944eSEnrico Granata     }
14139fc1944eSEnrico Granata     return item;
14149fc1944eSEnrico Granata }
14159fc1944eSEnrico Granata 
14160769b2b1SMichael Sartain static inline bool
14170769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var)
14180769b2b1SMichael Sartain {
14190769b2b1SMichael Sartain     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
14200769b2b1SMichael Sartain }
14210769b2b1SMichael Sartain 
14220769b2b1SMichael Sartain static bool
14230769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
14240769b2b1SMichael Sartain     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
14250769b2b1SMichael Sartain {
14260769b2b1SMichael Sartain     int var_len = strlen(var);
14270769b2b1SMichael Sartain     if (::strncmp (var_name_begin, var, var_len) == 0)
14280769b2b1SMichael Sartain     {
14290769b2b1SMichael Sartain         var_name_begin += var_len;
14300769b2b1SMichael Sartain         if (*var_name_begin == '}')
14310769b2b1SMichael Sartain         {
14320769b2b1SMichael Sartain             format = default_format;
14330769b2b1SMichael Sartain             return true;
14340769b2b1SMichael Sartain         }
14350769b2b1SMichael Sartain         else if (*var_name_begin == '%')
14360769b2b1SMichael Sartain         {
14370769b2b1SMichael Sartain             // Allow format specifiers: x|X|u with optional width specifiers.
14380769b2b1SMichael Sartain             //   ${thread.id%x}    ; hex
14390769b2b1SMichael Sartain             //   ${thread.id%X}    ; uppercase hex
14400769b2b1SMichael Sartain             //   ${thread.id%u}    ; unsigned decimal
14410769b2b1SMichael Sartain             //   ${thread.id%8.8X} ; width.precision + specifier
14420769b2b1SMichael Sartain             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
14430769b2b1SMichael Sartain             int dot_count = 0;
14440769b2b1SMichael Sartain             const char *specifier = NULL;
14450769b2b1SMichael Sartain             int width_precision_length = 0;
14460769b2b1SMichael Sartain             const char *width_precision = ++var_name_begin;
14470769b2b1SMichael Sartain             while (isdigit(*var_name_begin) || *var_name_begin == '.')
14480769b2b1SMichael Sartain             {
14490769b2b1SMichael Sartain                 dot_count += (*var_name_begin == '.');
14500769b2b1SMichael Sartain                 if (dot_count > 1)
14510769b2b1SMichael Sartain                     break;
14520769b2b1SMichael Sartain                 var_name_begin++;
14530769b2b1SMichael Sartain                 width_precision_length++;
14540769b2b1SMichael Sartain             }
14550769b2b1SMichael Sartain 
14560769b2b1SMichael Sartain             if (IsToken (var_name_begin, "tid}"))
14570769b2b1SMichael Sartain             {
14580769b2b1SMichael Sartain                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
14590769b2b1SMichael Sartain                 if (target)
14600769b2b1SMichael Sartain                 {
14610769b2b1SMichael Sartain                     ArchSpec arch (target->GetArchitecture ());
14620769b2b1SMichael Sartain                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
14630769b2b1SMichael Sartain                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
14640769b2b1SMichael Sartain                         specifier = PRIu64;
14650769b2b1SMichael Sartain                 }
14660769b2b1SMichael Sartain                 if (!specifier)
14670769b2b1SMichael Sartain                 {
14680769b2b1SMichael Sartain                     format = default_format;
14690769b2b1SMichael Sartain                     return true;
14700769b2b1SMichael Sartain                 }
14710769b2b1SMichael Sartain             }
14720769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "x}"))
14730769b2b1SMichael Sartain                 specifier = PRIx64;
14740769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "X}"))
14750769b2b1SMichael Sartain                 specifier = PRIX64;
14760769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "u}"))
14770769b2b1SMichael Sartain                 specifier = PRIu64;
14780769b2b1SMichael Sartain 
14790769b2b1SMichael Sartain             if (specifier)
14800769b2b1SMichael Sartain             {
14810769b2b1SMichael Sartain                 format = "%";
14820769b2b1SMichael Sartain                 if (width_precision_length)
14830769b2b1SMichael Sartain                     format += std::string(width_precision, width_precision_length);
14840769b2b1SMichael Sartain                 format += specifier;
14850769b2b1SMichael Sartain                 return true;
14860769b2b1SMichael Sartain             }
14870769b2b1SMichael Sartain         }
14880769b2b1SMichael Sartain     }
14890769b2b1SMichael Sartain     return false;
14900769b2b1SMichael Sartain }
14910769b2b1SMichael Sartain 
1492705b1809SJason Molenda // Find information for the "thread.info.*" specifiers in a format string
1493705b1809SJason Molenda static bool
1494705b1809SJason Molenda FormatThreadExtendedInfoRecurse
1495705b1809SJason Molenda (
1496705b1809SJason Molenda     const char *var_name_begin,
1497705b1809SJason Molenda     StructuredData::ObjectSP thread_info_dictionary,
1498705b1809SJason Molenda     const SymbolContext *sc,
1499705b1809SJason Molenda     const ExecutionContext *exe_ctx,
1500705b1809SJason Molenda     Stream &s
1501705b1809SJason Molenda )
1502705b1809SJason Molenda {
1503705b1809SJason Molenda     bool var_success = false;
1504705b1809SJason Molenda     std::string token_format;
1505705b1809SJason Molenda 
1506705b1809SJason Molenda     llvm::StringRef var_name(var_name_begin);
1507705b1809SJason Molenda     size_t percent_idx = var_name.find('%');
1508705b1809SJason Molenda     size_t close_curly_idx = var_name.find('}');
1509705b1809SJason Molenda     llvm::StringRef path = var_name;
1510705b1809SJason Molenda     llvm::StringRef formatter = var_name;
1511705b1809SJason Molenda 
1512705b1809SJason Molenda     // 'path' will be the dot separated list of objects to transverse up until we hit
1513705b1809SJason Molenda     // a close curly brace, a percent sign, or an end of string.
1514705b1809SJason Molenda     if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
1515705b1809SJason Molenda     {
1516705b1809SJason Molenda         if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
1517705b1809SJason Molenda         {
1518705b1809SJason Molenda             if (percent_idx < close_curly_idx)
1519705b1809SJason Molenda             {
1520705b1809SJason Molenda                 path = var_name.slice(0, percent_idx);
1521705b1809SJason Molenda                 formatter = var_name.substr (percent_idx);
1522705b1809SJason Molenda             }
1523705b1809SJason Molenda             else
1524705b1809SJason Molenda             {
1525705b1809SJason Molenda                 path = var_name.slice(0, close_curly_idx);
1526705b1809SJason Molenda                 formatter = var_name.substr (close_curly_idx);
1527705b1809SJason Molenda             }
1528705b1809SJason Molenda         }
1529705b1809SJason Molenda         else if (percent_idx != llvm::StringRef::npos)
1530705b1809SJason Molenda         {
1531705b1809SJason Molenda             path = var_name.slice(0, percent_idx);
1532705b1809SJason Molenda             formatter = var_name.substr (percent_idx);
1533705b1809SJason Molenda         }
1534705b1809SJason Molenda         else if (close_curly_idx != llvm::StringRef::npos)
1535705b1809SJason Molenda         {
1536705b1809SJason Molenda             path = var_name.slice(0, close_curly_idx);
1537705b1809SJason Molenda             formatter = var_name.substr (close_curly_idx);
1538705b1809SJason Molenda         }
1539705b1809SJason Molenda     }
1540705b1809SJason Molenda 
1541705b1809SJason Molenda     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1542705b1809SJason Molenda 
1543705b1809SJason Molenda     if (value.get())
1544705b1809SJason Molenda     {
1545705b1809SJason Molenda         if (value->GetType() == StructuredData::Type::eTypeInteger)
1546705b1809SJason Molenda         {
1547705b1809SJason Molenda             if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1548705b1809SJason Molenda             {
1549705b1809SJason Molenda                 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
1550705b1809SJason Molenda                 var_success = true;
1551705b1809SJason Molenda             }
1552705b1809SJason Molenda         }
1553705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1554705b1809SJason Molenda         {
1555705b1809SJason Molenda             s.Printf ("%f", value->GetAsFloat()->GetValue());
1556705b1809SJason Molenda             var_success = true;
1557705b1809SJason Molenda         }
1558705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeString)
1559705b1809SJason Molenda         {
1560705b1809SJason Molenda             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1561705b1809SJason Molenda             var_success = true;
1562705b1809SJason Molenda         }
1563705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeArray)
1564705b1809SJason Molenda         {
1565705b1809SJason Molenda             if (value->GetAsArray()->GetSize() > 0)
1566705b1809SJason Molenda             {
1567705b1809SJason Molenda                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1568705b1809SJason Molenda                 var_success = true;
1569705b1809SJason Molenda             }
1570705b1809SJason Molenda         }
1571705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1572705b1809SJason Molenda         {
1573705b1809SJason Molenda             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1574705b1809SJason Molenda             var_success = true;
1575705b1809SJason Molenda         }
1576705b1809SJason Molenda     }
1577705b1809SJason Molenda 
1578705b1809SJason Molenda     return var_success;
1579705b1809SJason Molenda }
1580705b1809SJason Molenda 
1581705b1809SJason Molenda 
1582c3ce7f27SMichael Sartain static bool
1583c3ce7f27SMichael Sartain FormatPromptRecurse
15841b654882SGreg Clayton (
15851b654882SGreg Clayton     const char *format,
15861b654882SGreg Clayton     const SymbolContext *sc,
15871b654882SGreg Clayton     const ExecutionContext *exe_ctx,
15881b654882SGreg Clayton     const Address *addr,
15891b654882SGreg Clayton     Stream &s,
15904becb37eSEnrico Granata     const char **end,
1591aff1b357SJason Molenda     ValueObject* valobj,
1592aff1b357SJason Molenda     bool function_changed,
1593aff1b357SJason Molenda     bool initial_function
15941b654882SGreg Clayton )
15951b654882SGreg Clayton {
1596c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
15971b654882SGreg Clayton     bool success = true;
15981b654882SGreg Clayton     const char *p;
15995160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1600c3ce7f27SMichael Sartain 
16011b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
16021b654882SGreg Clayton     {
1603c482a192SEnrico Granata         if (realvalobj)
16044becb37eSEnrico Granata         {
1605c482a192SEnrico Granata             valobj = realvalobj;
1606c482a192SEnrico Granata             realvalobj = NULL;
16074becb37eSEnrico Granata         }
16081b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
16091b654882SGreg Clayton         if (non_special_chars > 0)
16101b654882SGreg Clayton         {
16111b654882SGreg Clayton             if (success)
16121b654882SGreg Clayton                 s.Write (p, non_special_chars);
16131b654882SGreg Clayton             p += non_special_chars;
16141b654882SGreg Clayton         }
16151b654882SGreg Clayton 
16161b654882SGreg Clayton         if (*p == '\0')
16171b654882SGreg Clayton         {
16181b654882SGreg Clayton             break;
16191b654882SGreg Clayton         }
16201b654882SGreg Clayton         else if (*p == '{')
16211b654882SGreg Clayton         {
16221b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
16231b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
16241b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
16251b654882SGreg Clayton             // is one in the symbol context you can use:
16261b654882SGreg Clayton             //      "{function =${function.name}}"
16271b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
16281b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
16291b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
16301b654882SGreg Clayton             // or symbol with a valid name.
16311b654882SGreg Clayton             StreamString sub_strm;
16321b654882SGreg Clayton 
16331b654882SGreg Clayton             ++p;  // Skip the '{'
16341b654882SGreg Clayton 
1635aff1b357SJason Molenda             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function))
16361b654882SGreg Clayton             {
16371b654882SGreg Clayton                 // The stream had all it needed
16381b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
16391b654882SGreg Clayton             }
16401b654882SGreg Clayton             if (*p != '}')
16411b654882SGreg Clayton             {
16421b654882SGreg Clayton                 success = false;
16431b654882SGreg Clayton                 break;
16441b654882SGreg Clayton             }
16451b654882SGreg Clayton         }
16461b654882SGreg Clayton         else if (*p == '}')
16471b654882SGreg Clayton         {
16481b654882SGreg Clayton             // End of a enclosing scope
16491b654882SGreg Clayton             break;
16501b654882SGreg Clayton         }
16511b654882SGreg Clayton         else if (*p == '$')
16521b654882SGreg Clayton         {
16531b654882SGreg Clayton             // We have a prompt variable to print
16541b654882SGreg Clayton             ++p;
16551b654882SGreg Clayton             if (*p == '{')
16561b654882SGreg Clayton             {
16571b654882SGreg Clayton                 ++p;
16581b654882SGreg Clayton                 const char *var_name_begin = p;
16591b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
16601b654882SGreg Clayton 
16611b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
16621b654882SGreg Clayton                 {
16631b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
16641b654882SGreg Clayton                     if (success)
16651b654882SGreg Clayton                     {
16661b654882SGreg Clayton                         const char *cstr = NULL;
16670769b2b1SMichael Sartain                         std::string token_format;
16681b654882SGreg Clayton                         Address format_addr;
1669aff1b357SJason Molenda 
1670aff1b357SJason Molenda                         // normally "addr" means print a raw address but
1671aff1b357SJason Molenda                         // "file-addr-or-load-addr" means print a module + file addr if there's no load addr
1672aff1b357SJason Molenda                         bool print_file_addr_or_load_addr = false;
1673aff1b357SJason Molenda                         bool addr_offset_concrete_func_only = false;
1674aff1b357SJason Molenda                         bool addr_offset_print_with_no_padding = false;
16751b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
16761b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
16771b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
16781b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
16791b654882SGreg Clayton                         FileSpec format_file_spec;
1680e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
16811b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
16829fc1944eSEnrico Granata                         bool do_deref_pointer = false;
168386cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
168486cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
16851b654882SGreg Clayton 
16861b654882SGreg Clayton                         // Each variable must set success to true below...
16871b654882SGreg Clayton                         bool var_success = false;
16881b654882SGreg Clayton                         switch (var_name_begin[0])
16891b654882SGreg Clayton                         {
16904becb37eSEnrico Granata                         case '*':
16916f3533fbSEnrico Granata                         case 'v':
16926f3533fbSEnrico Granata                         case 's':
16934becb37eSEnrico Granata                             {
1694c482a192SEnrico Granata                                 if (!valobj)
169534132754SGreg Clayton                                     break;
16966f3533fbSEnrico Granata 
1697c3e320a7SEnrico Granata                                 if (log)
1698d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1699c3e320a7SEnrico Granata 
17006f3533fbSEnrico Granata                                 // check for *var and *svar
17016f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
17026f3533fbSEnrico Granata                                 {
17039fc1944eSEnrico Granata                                     do_deref_pointer = true;
17049fc1944eSEnrico Granata                                     var_name_begin++;
1705c3e320a7SEnrico Granata                                     if (log)
170668ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
170768ae4117SEnrico Granata                                 }
1708c3e320a7SEnrico Granata 
17096f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
17104becb37eSEnrico Granata                                 {
1711c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
171286cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
171386cc9829SEnrico Granata                                     if (!valobj)
171486cc9829SEnrico Granata                                         break;
17156f3533fbSEnrico Granata                                     var_name_begin++;
1716c3e320a7SEnrico Granata                                     if (log)
171768ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
171868ae4117SEnrico Granata                                 }
1719c3e320a7SEnrico Granata 
17206f3533fbSEnrico Granata                                 // should be a 'v' by now
17216f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
17226f3533fbSEnrico Granata                                     break;
17236f3533fbSEnrico Granata 
1724c3e320a7SEnrico Granata                                 if (log)
172568ae4117SEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1726c3e320a7SEnrico Granata 
1727fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
172886cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1729fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
17308c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
173186cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
173234132754SGreg Clayton                                 ValueObject* target = NULL;
17334d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
173434132754SGreg Clayton                                 const char* var_name_final = NULL;
17359fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
173634132754SGreg Clayton                                 const char* close_bracket_position = NULL;
173734132754SGreg Clayton                                 int64_t index_lower = -1;
173834132754SGreg Clayton                                 int64_t index_higher = -1;
17399fc1944eSEnrico Granata                                 bool is_array_range = false;
1740fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
174185933ed4SEnrico Granata                                 bool was_plain_var = false;
174285933ed4SEnrico Granata                                 bool was_var_format = false;
1743a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1744fc7a7f3bSEnrico Granata 
1745c482a192SEnrico Granata                                 if (!valobj) break;
1746c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
17470769b2b1SMichael Sartain                                 if (IsToken (var_name_begin, "var}"))
17480a3958e0SEnrico Granata                                 {
174985933ed4SEnrico Granata                                     was_plain_var = true;
1750c482a192SEnrico Granata                                     target = valobj;
175186cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17520a3958e0SEnrico Granata                                 }
175388282c69SEnrico Granata                                 else if (IsToken (var_name_begin, "var.script:"))
175488282c69SEnrico Granata                                 {
175588282c69SEnrico Granata                                     var_name_begin += ::strlen("var.script:");
175688282c69SEnrico Granata                                     std::string script_name(var_name_begin,var_name_end);
175788282c69SEnrico Granata                                     ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
175888282c69SEnrico Granata                                     if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name))
175988282c69SEnrico Granata                                         var_success = true;
176088282c69SEnrico Granata                                     break;
176188282c69SEnrico Granata                                 }
17620769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin,"var%"))
17639fc1944eSEnrico Granata                                 {
176485933ed4SEnrico Granata                                     was_var_format = true;
17659fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
17669fc1944eSEnrico Granata                                     const char* percent_position;
1767c482a192SEnrico Granata                                     target = valobj;
176886cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17699fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17709fc1944eSEnrico Granata                                                           var_name_end,
17719fc1944eSEnrico Granata                                                           &var_name_final,
17729fc1944eSEnrico Granata                                                           &percent_position,
17739fc1944eSEnrico Granata                                                           &custom_format,
17749fc1944eSEnrico Granata                                                           &val_obj_display);
17750a3958e0SEnrico Granata                                 }
17769fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
17770769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin, "var"))
17789fc1944eSEnrico Granata                                 {
17790769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "var["))
1780a777dc2aSEnrico Granata                                         was_var_indexed = true;
17819fc1944eSEnrico Granata                                     const char* percent_position;
17829fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17839fc1944eSEnrico Granata                                                           var_name_end,
17849fc1944eSEnrico Granata                                                           &var_name_final,
17859fc1944eSEnrico Granata                                                           &percent_position,
17869fc1944eSEnrico Granata                                                           &custom_format,
17879fc1944eSEnrico Granata                                                           &val_obj_display);
17889fc1944eSEnrico Granata 
17899fc1944eSEnrico Granata                                     const char* open_bracket_position;
17909fc1944eSEnrico Granata                                     const char* separator_position;
17919fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
17929fc1944eSEnrico Granata                                                         var_name_end,
17939fc1944eSEnrico Granata                                                         var_name_final,
17949fc1944eSEnrico Granata                                                         &open_bracket_position,
17959fc1944eSEnrico Granata                                                         &separator_position,
17969fc1944eSEnrico Granata                                                         &close_bracket_position,
17979fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
17989fc1944eSEnrico Granata                                                         &index_lower,
17999fc1944eSEnrico Granata                                                         &index_higher);
18009fc1944eSEnrico Granata 
18019fc1944eSEnrico Granata                                     Error error;
18029fc1944eSEnrico Granata 
1803599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1804599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1805fc7a7f3bSEnrico Granata 
1806e992a089SEnrico Granata                                     if (log)
1807599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1808fc7a7f3bSEnrico Granata 
1809599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1810fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1811fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1812fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1813fc7a7f3bSEnrico Granata                                                                              options,
1814fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1815fc7a7f3bSEnrico Granata 
1816fc7a7f3bSEnrico Granata                                     if (!target)
18179fc1944eSEnrico Granata                                     {
1818e992a089SEnrico Granata                                         if (log)
1819d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1820e992a089SEnrico Granata                                                " final_value_type %d",
1821fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1822fc7a7f3bSEnrico Granata                                         break;
18230a3958e0SEnrico Granata                                     }
1824a7187d00SEnrico Granata                                     else
1825fc7a7f3bSEnrico Granata                                     {
1826e992a089SEnrico Granata                                         if (log)
1827d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1828e992a089SEnrico Granata                                                " final_value_type %d",
1829fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
183050bed5e8SEnrico Granata                                         target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
1831a7187d00SEnrico Granata                                     }
18320a3958e0SEnrico Granata                                 }
18330a3958e0SEnrico Granata                                 else
18340a3958e0SEnrico Granata                                     break;
18359fc1944eSEnrico Granata 
183686cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
183786cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1838fc7a7f3bSEnrico Granata 
183986cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1840fc7a7f3bSEnrico Granata 
1841a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
18420a3958e0SEnrico Granata                                 {
18439fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
18449fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
18459fc1944eSEnrico Granata                                     // to get to the target ValueObject
18469fc1944eSEnrico Granata                                     Error error;
18479fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1848dc940730SEnrico Granata                                     if (error.Fail())
1849dc940730SEnrico Granata                                     {
1850dc940730SEnrico Granata                                         if (log)
1851d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1852dc940730SEnrico Granata                                         break;
1853dc940730SEnrico Granata                                     }
18549fc1944eSEnrico Granata                                     do_deref_pointer = false;
18550a3958e0SEnrico Granata                                 }
18560a3958e0SEnrico Granata 
1857f164d940SJim Ingham                                 if (!target)
1858f164d940SJim Ingham                                 {
1859f164d940SJim Ingham                                     if (log)
1860f164d940SJim Ingham                                         log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
1861f164d940SJim Ingham                                     break;
1862f164d940SJim Ingham                                 }
1863f164d940SJim Ingham 
1864a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1865a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1866a777dc2aSEnrico Granata                                 // us into an endless recursion
1867a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1868a777dc2aSEnrico Granata                                 {
1869a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1870a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1871a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1872a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1873a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1874a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1875a777dc2aSEnrico Granata                                 }
1876a777dc2aSEnrico Granata 
187785933ed4SEnrico Granata                                 // TODO use flags for these
187857ee3067SGreg Clayton                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
1879622be238SEnrico Granata                                 bool is_array = (type_info_flags & eTypeIsArray) != 0;
1880622be238SEnrico Granata                                 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
188157ee3067SGreg Clayton                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1882f4efecd9SEnrico Granata 
188386cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1884f4efecd9SEnrico Granata                                 {
188585933ed4SEnrico Granata                                     StreamString str_temp;
1886e992a089SEnrico Granata                                     if (log)
1887d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1888d64d0bc0SEnrico Granata 
18895088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1890d64d0bc0SEnrico Granata                                     {
1891f4efecd9SEnrico Granata                                         // try to use the special cases
189285933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
189385933ed4SEnrico Granata                                                                                           val_obj_display,
189485933ed4SEnrico Granata                                                                                           custom_format);
1895e992a089SEnrico Granata                                         if (log)
1896d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1897d64d0bc0SEnrico Granata 
1898d64d0bc0SEnrico Granata                                         // should not happen
18995088c486SGreg Clayton                                         if (var_success)
190085933ed4SEnrico Granata                                             s << str_temp.GetData();
1901d64d0bc0SEnrico Granata                                         var_success = true;
1902d64d0bc0SEnrico Granata                                         break;
1903d64d0bc0SEnrico Granata                                     }
1904d64d0bc0SEnrico Granata                                     else
1905d64d0bc0SEnrico Granata                                     {
190688da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1907d64d0bc0SEnrico Granata                                         {
1908d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1909d64d0bc0SEnrico Granata                                         }
191088da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
191188da35f8SEnrico Granata                                         {
191223f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
191388da35f8SEnrico Granata                                                                                  val_obj_display,
191486cc9829SEnrico Granata                                                                                  custom_format,
191586cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
191688da35f8SEnrico Granata                                         }
1917d64d0bc0SEnrico Granata                                         var_success = true;
1918d64d0bc0SEnrico Granata                                         break;
1919d64d0bc0SEnrico Granata                                     }
1920d64d0bc0SEnrico Granata                                 }
1921d64d0bc0SEnrico Granata 
1922d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1923d64d0bc0SEnrico Granata                                 // type @ location message
1924d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1925d64d0bc0SEnrico Granata                                 {
1926d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1927d64d0bc0SEnrico Granata                                     var_success = true;
192885933ed4SEnrico Granata                                     break;
192985933ed4SEnrico Granata                                 }
193085933ed4SEnrico Granata 
1931d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
193286cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
193385933ed4SEnrico Granata                                 {
193485933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
193585933ed4SEnrico Granata                                     var_success = true;
1936f4efecd9SEnrico Granata                                     break;
1937f4efecd9SEnrico Granata                                 }
1938f4efecd9SEnrico Granata 
19399fc1944eSEnrico Granata                                 if (!is_array_range)
1940e992a089SEnrico Granata                                 {
1941e992a089SEnrico Granata                                     if (log)
1942d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
19439fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1944e992a089SEnrico Granata                                 }
19459fc1944eSEnrico Granata                                 else
19469fc1944eSEnrico Granata                                 {
1947e992a089SEnrico Granata                                     if (log)
1948d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
19499fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
19509fc1944eSEnrico Granata                                         break;
1951e992a089SEnrico Granata                                     if (log)
1952d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1953fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1954fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
19550a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
19560a3958e0SEnrico Granata                                     {
1957fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1958fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1959fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1960fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1961fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1962fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
19630a3958e0SEnrico Granata                                     }
19640a3958e0SEnrico Granata 
19650a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
19660a3958e0SEnrico Granata                                     s.PutChar('[');
19670a3958e0SEnrico Granata                                     var_success = true;
19680a3958e0SEnrico Granata 
19699fc1944eSEnrico Granata                                     if (index_higher < 0)
1970c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
19710a3958e0SEnrico Granata 
1972cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
197322c55d18SEnrico Granata 
19740a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
19750a3958e0SEnrico Granata                                     {
1976fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
19779fc1944eSEnrico Granata                                                                                      index_lower,
1978c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1979fc7a7f3bSEnrico Granata                                                                                      false).get();
19800a3958e0SEnrico Granata 
1981fc7a7f3bSEnrico Granata                                         if (!item)
1982fc7a7f3bSEnrico Granata                                         {
1983e992a089SEnrico Granata                                             if (log)
1984d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1985fc7a7f3bSEnrico Granata                                         }
1986fc7a7f3bSEnrico Granata                                         else
1987fc7a7f3bSEnrico Granata                                         {
1988e992a089SEnrico Granata                                             if (log)
1989d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1990fc7a7f3bSEnrico Granata                                         }
1991fc7a7f3bSEnrico Granata 
19920a3958e0SEnrico Granata                                         if (!special_directions)
19939fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
19940a3958e0SEnrico Granata                                         else
1995aff1b357SJason Molenda                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function);
19960a3958e0SEnrico Granata 
199722c55d18SEnrico Granata                                         if (--max_num_children == 0)
199822c55d18SEnrico Granata                                         {
199922c55d18SEnrico Granata                                             s.PutCString(", ...");
200022c55d18SEnrico Granata                                             break;
200122c55d18SEnrico Granata                                         }
200222c55d18SEnrico Granata 
20030a3958e0SEnrico Granata                                         if (index_lower < index_higher)
20040a3958e0SEnrico Granata                                             s.PutChar(',');
20050a3958e0SEnrico Granata                                     }
20060a3958e0SEnrico Granata                                     s.PutChar(']');
20074becb37eSEnrico Granata                                 }
20084becb37eSEnrico Granata                             }
200934132754SGreg Clayton                             break;
20101b654882SGreg Clayton                         case 'a':
2011aff1b357SJason Molenda                             if (IsToken (var_name_begin, "addr-file-or-load}"))
2012aff1b357SJason Molenda                             {
2013aff1b357SJason Molenda                                 print_file_addr_or_load_addr = true;
2014aff1b357SJason Molenda                             }
2015aff1b357SJason Molenda                             if (IsToken (var_name_begin, "addr}")
2016aff1b357SJason Molenda                                 || IsToken (var_name_begin, "addr-file-or-load}"))
20171b654882SGreg Clayton                             {
20181b654882SGreg Clayton                                 if (addr && addr->IsValid())
20191b654882SGreg Clayton                                 {
20201b654882SGreg Clayton                                     var_success = true;
20211b654882SGreg Clayton                                     format_addr = *addr;
20221b654882SGreg Clayton                                 }
20231b654882SGreg Clayton                             }
20241b654882SGreg Clayton                             break;
20251b654882SGreg Clayton 
20261b654882SGreg Clayton                         case 'p':
20270769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "process."))
20281b654882SGreg Clayton                             {
2029c14ee32dSGreg Clayton                                 if (exe_ctx)
2030c14ee32dSGreg Clayton                                 {
2031c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
2032c14ee32dSGreg Clayton                                     if (process)
20331b654882SGreg Clayton                                     {
20341b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
20350769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
20361b654882SGreg Clayton                                         {
20370769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), process->GetID());
20381b654882SGreg Clayton                                             var_success = true;
20391b654882SGreg Clayton                                         }
20400769b2b1SMichael Sartain                                         else if ((IsToken (var_name_begin, "name}")) ||
20410769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.basename}")) ||
20420769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.fullpath}")))
20431b654882SGreg Clayton                                         {
2044c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
2045aa149cbdSGreg Clayton                                             if (exe_module)
20461b654882SGreg Clayton                                             {
20471b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
20481b654882SGreg Clayton                                                 {
2049aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
20509076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
20511b654882SGreg Clayton                                                 }
20521b654882SGreg Clayton                                                 else
20531b654882SGreg Clayton                                                 {
2054aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
20559076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
20561b654882SGreg Clayton                                                 }
20571b654882SGreg Clayton                                             }
20581b654882SGreg Clayton                                         }
20590769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2060aad8e480SEnrico Granata                                         {
2061aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2062aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2063aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
20640769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
2065aad8e480SEnrico Granata                                                 var_success = true;
2066aad8e480SEnrico Granata                                         }
20671b654882SGreg Clayton                                     }
20681b654882SGreg Clayton                                 }
2069c14ee32dSGreg Clayton                             }
20701b654882SGreg Clayton                             break;
20711b654882SGreg Clayton 
20721b654882SGreg Clayton                         case 't':
20730769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "thread."))
20741b654882SGreg Clayton                             {
2075c14ee32dSGreg Clayton                                 if (exe_ctx)
2076c14ee32dSGreg Clayton                                 {
2077c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
2078c14ee32dSGreg Clayton                                     if (thread)
20791b654882SGreg Clayton                                     {
20801b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
20810769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
20821b654882SGreg Clayton                                         {
20830769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetID());
20841b654882SGreg Clayton                                             var_success = true;
20851b654882SGreg Clayton                                         }
20860769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2087160c9d81SGreg Clayton                                         {
20880769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
2089160c9d81SGreg Clayton                                             var_success = true;
2090160c9d81SGreg Clayton                                         }
20910769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
20921b654882SGreg Clayton                                         {
20930769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
20941b654882SGreg Clayton                                             var_success = true;
20951b654882SGreg Clayton                                         }
20960769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "name}"))
20971b654882SGreg Clayton                                         {
2098c14ee32dSGreg Clayton                                             cstr = thread->GetName();
20991b654882SGreg Clayton                                             var_success = cstr && cstr[0];
21001b654882SGreg Clayton                                             if (var_success)
21011b654882SGreg Clayton                                                 s.PutCString(cstr);
21021b654882SGreg Clayton                                         }
21030769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "queue}"))
21041b654882SGreg Clayton                                         {
2105c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
21061b654882SGreg Clayton                                             var_success = cstr && cstr[0];
21071b654882SGreg Clayton                                             if (var_success)
21081b654882SGreg Clayton                                                 s.PutCString(cstr);
21091b654882SGreg Clayton                                         }
21100769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "stop-reason}"))
21111b654882SGreg Clayton                                         {
2112c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
21135d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
21141b654882SGreg Clayton                                             {
2115b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
21161b654882SGreg Clayton                                                 if (cstr && cstr[0])
21171b654882SGreg Clayton                                                 {
21181b654882SGreg Clayton                                                     s.PutCString(cstr);
21191b654882SGreg Clayton                                                     var_success = true;
21201b654882SGreg Clayton                                                 }
21211b654882SGreg Clayton                                             }
21221b654882SGreg Clayton                                         }
21230769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "return-value}"))
212473ca05a2SJim Ingham                                         {
212573ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
21265d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
212773ca05a2SJim Ingham                                             {
212873ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
212973ca05a2SJim Ingham                                                 if (return_valobj_sp)
213073ca05a2SJim Ingham                                                 {
21314d93b8cdSEnrico Granata                                                     return_valobj_sp->Dump(s);
213273ca05a2SJim Ingham                                                     var_success = true;
213373ca05a2SJim Ingham                                                 }
213473ca05a2SJim Ingham                                             }
213573ca05a2SJim Ingham                                         }
213630fadafeSJim Ingham                                         else if (IsToken (var_name_begin, "completed-expression}"))
213730fadafeSJim Ingham                                         {
213830fadafeSJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
213930fadafeSJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
214030fadafeSJim Ingham                                             {
214130fadafeSJim Ingham                                                 ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
214230fadafeSJim Ingham                                                 if (expression_var_sp && expression_var_sp->GetValueObject())
214330fadafeSJim Ingham                                                 {
214430fadafeSJim Ingham                                                     expression_var_sp->GetValueObject()->Dump(s);
214530fadafeSJim Ingham                                                     var_success = true;
214630fadafeSJim Ingham                                                 }
214730fadafeSJim Ingham                                             }
214830fadafeSJim Ingham                                         }
21490769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2150aad8e480SEnrico Granata                                         {
2151aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2152aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2153aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
21540769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2155aad8e480SEnrico Granata                                                 var_success = true;
2156aad8e480SEnrico Granata                                         }
2157705b1809SJason Molenda                                         else if (IsToken (var_name_begin, "info."))
2158705b1809SJason Molenda                                         {
2159705b1809SJason Molenda                                             var_name_begin += ::strlen("info.");
2160705b1809SJason Molenda                                             StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
2161705b1809SJason Molenda                                             if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
2162705b1809SJason Molenda                                             {
2163705b1809SJason Molenda                                                 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
2164705b1809SJason Molenda                                             }
2165705b1809SJason Molenda                                         }
2166aad8e480SEnrico Granata                                     }
2167aad8e480SEnrico Granata                                 }
216873ca05a2SJim Ingham                             }
21690769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "target."))
21701b654882SGreg Clayton                             {
217167cc0636SGreg Clayton                                 // TODO: hookup properties
217267cc0636SGreg Clayton //                                if (!target_properties_sp)
217367cc0636SGreg Clayton //                                {
217467cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
217567cc0636SGreg Clayton //                                    if (target)
217667cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
217767cc0636SGreg Clayton //                                }
217867cc0636SGreg Clayton //
217967cc0636SGreg Clayton //                                if (target_properties_sp)
218067cc0636SGreg Clayton //                                {
218167cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
218267cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
218367cc0636SGreg Clayton //                                    if (end_property)
218467cc0636SGreg Clayton //                                    {
218567cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
218667cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
218767cc0636SGreg Clayton //                                        if (!property_value.empty())
218867cc0636SGreg Clayton //                                        {
218967cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
219067cc0636SGreg Clayton //                                            var_success = true;
219167cc0636SGreg Clayton //                                        }
219267cc0636SGreg Clayton //                                    }
219367cc0636SGreg Clayton //                                }
21940603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
21950603aa9dSGreg Clayton                                 if (target)
21961b654882SGreg Clayton                                 {
21971b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
21980769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "arch}"))
21991b654882SGreg Clayton                                     {
22001b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
22011b654882SGreg Clayton                                         if (arch.IsValid())
22021b654882SGreg Clayton                                         {
220364195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
22041b654882SGreg Clayton                                             var_success = true;
22051b654882SGreg Clayton                                         }
22061b654882SGreg Clayton                                     }
22070769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "script:"))
2208aad8e480SEnrico Granata                                     {
2209aad8e480SEnrico Granata                                         var_name_begin += ::strlen("script:");
2210aad8e480SEnrico Granata                                         std::string script_name(var_name_begin,var_name_end);
2211aad8e480SEnrico Granata                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
22120769b2b1SMichael Sartain                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2213aad8e480SEnrico Granata                                             var_success = true;
2214aad8e480SEnrico Granata                                     }
22151b654882SGreg Clayton                                 }
22161b654882SGreg Clayton                             }
22171b654882SGreg Clayton                             break;
22181b654882SGreg Clayton 
22191b654882SGreg Clayton                         case 'm':
22200769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "module."))
22211b654882SGreg Clayton                             {
22220603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
22231b654882SGreg Clayton                                 {
22240603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
22251b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
22261b654882SGreg Clayton 
22270769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
22281b654882SGreg Clayton                                     {
22291b654882SGreg Clayton                                         if (module->GetFileSpec())
22301b654882SGreg Clayton                                         {
22311b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
22321b654882SGreg Clayton 
22330769b2b1SMichael Sartain                                             if (IsToken (var_name_begin, "basename}"))
22341b654882SGreg Clayton                                             {
22351b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
22369076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
22371b654882SGreg Clayton                                             }
22380769b2b1SMichael Sartain                                             else if (IsToken (var_name_begin, "fullpath}"))
22391b654882SGreg Clayton                                             {
22401b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
22419076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
22421b654882SGreg Clayton                                             }
22431b654882SGreg Clayton                                         }
22441b654882SGreg Clayton                                     }
22451b654882SGreg Clayton                                 }
22461b654882SGreg Clayton                             }
22471b654882SGreg Clayton                             break;
22481b654882SGreg Clayton 
22491b654882SGreg Clayton 
22501b654882SGreg Clayton                         case 'f':
22510769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "file."))
22521b654882SGreg Clayton                             {
22531b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
22541b654882SGreg Clayton                                 {
22551b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
22561b654882SGreg Clayton 
22570769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "basename}"))
22581b654882SGreg Clayton                                     {
22591b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
22609076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22611b654882SGreg Clayton                                     }
22620769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "fullpath}"))
22631b654882SGreg Clayton                                     {
22641b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
22659076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22661b654882SGreg Clayton                                     }
22671b654882SGreg Clayton                                 }
22681b654882SGreg Clayton                             }
22690769b2b1SMichael Sartain                            else if (IsToken (var_name_begin, "frame."))
22701b654882SGreg Clayton                             {
2271c14ee32dSGreg Clayton                                 if (exe_ctx)
2272c14ee32dSGreg Clayton                                 {
2273b57e4a1bSJason Molenda                                     StackFrame *frame = exe_ctx->GetFramePtr();
2274c14ee32dSGreg Clayton                                     if (frame)
22751b654882SGreg Clayton                                     {
22761b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
22770769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "index}"))
22781b654882SGreg Clayton                                         {
2279c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
22801b654882SGreg Clayton                                             var_success = true;
22811b654882SGreg Clayton                                         }
22820769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "pc}"))
22831b654882SGreg Clayton                                         {
22841b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22851b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
22861b654882SGreg Clayton                                             var_success = true;
22871b654882SGreg Clayton                                         }
22880769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "sp}"))
22891b654882SGreg Clayton                                         {
22901b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22911b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
22921b654882SGreg Clayton                                             var_success = true;
22931b654882SGreg Clayton                                         }
22940769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fp}"))
22951b654882SGreg Clayton                                         {
22961b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22971b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
22981b654882SGreg Clayton                                             var_success = true;
22991b654882SGreg Clayton                                         }
23000769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "flags}"))
23011b654882SGreg Clayton                                         {
23021b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
23031b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
23041b654882SGreg Clayton                                             var_success = true;
23051b654882SGreg Clayton                                         }
23060769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "reg."))
23071b654882SGreg Clayton                                         {
2308c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
23091b654882SGreg Clayton                                             if (reg_ctx)
23101b654882SGreg Clayton                                             {
23111b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
23121b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
23131b654882SGreg Clayton                                                 {
23141b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
23151b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
23161b654882SGreg Clayton                                                     if (reg_info)
23171b654882SGreg Clayton                                                         var_success = true;
23181b654882SGreg Clayton                                                 }
23191b654882SGreg Clayton                                             }
23201b654882SGreg Clayton                                         }
23210769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2322aad8e480SEnrico Granata                                         {
2323aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2324aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2325aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
23260769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2327aad8e480SEnrico Granata                                                 var_success = true;
2328aad8e480SEnrico Granata                                         }
2329aad8e480SEnrico Granata                                     }
2330aad8e480SEnrico Granata                                 }
23311b654882SGreg Clayton                             }
23320769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "function."))
23331b654882SGreg Clayton                             {
23341b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
23351b654882SGreg Clayton                                 {
23361b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
23370769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "id}"))
23381b654882SGreg Clayton                                     {
23391b654882SGreg Clayton                                         if (sc->function)
2340d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
23411b654882SGreg Clayton                                         else
23421b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
23431b654882SGreg Clayton 
23441b654882SGreg Clayton                                         var_success = true;
23451b654882SGreg Clayton                                     }
2346aff1b357SJason Molenda                                     if (IsToken (var_name_begin, "changed}") && function_changed)
2347aff1b357SJason Molenda                                     {
2348aff1b357SJason Molenda                                         var_success = true;
2349aff1b357SJason Molenda                                     }
2350aff1b357SJason Molenda                                     if (IsToken (var_name_begin, "initial-function}") && initial_function)
2351aff1b357SJason Molenda                                     {
2352aff1b357SJason Molenda                                         var_success = true;
2353aff1b357SJason Molenda                                     }
23540769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name}"))
23551b654882SGreg Clayton                                     {
23561b654882SGreg Clayton                                         if (sc->function)
23571b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
23581b654882SGreg Clayton                                         else if (sc->symbol)
23591b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
23601b654882SGreg Clayton                                         if (cstr)
23611b654882SGreg Clayton                                         {
23621b654882SGreg Clayton                                             s.PutCString(cstr);
23630d9c9934SGreg Clayton 
23640d9c9934SGreg Clayton                                             if (sc->block)
23650d9c9934SGreg Clayton                                             {
23660d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
23670d9c9934SGreg Clayton                                                 if (inline_block)
23680d9c9934SGreg Clayton                                                 {
23690d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
23700d9c9934SGreg Clayton                                                     if (inline_info)
23710d9c9934SGreg Clayton                                                     {
23720d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
23730d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
23740d9c9934SGreg Clayton                                                     }
23750d9c9934SGreg Clayton                                                 }
23760d9c9934SGreg Clayton                                             }
23771b654882SGreg Clayton                                             var_success = true;
23781b654882SGreg Clayton                                         }
23791b654882SGreg Clayton                                     }
2380aff1b357SJason Molenda                                     else if (IsToken (var_name_begin, "name-without-args}"))
2381aff1b357SJason Molenda                                     {
2382aff1b357SJason Molenda                                         ConstString name;
2383aff1b357SJason Molenda                                         if (sc->function)
2384aff1b357SJason Molenda                                             name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2385aff1b357SJason Molenda                                         else if (sc->symbol)
2386aff1b357SJason Molenda                                             name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2387aff1b357SJason Molenda                                         if (name)
2388aff1b357SJason Molenda                                         {
2389aff1b357SJason Molenda                                             s.PutCString(name.GetCString());
2390aff1b357SJason Molenda                                             var_success = true;
2391aff1b357SJason Molenda                                         }
2392aff1b357SJason Molenda                                     }
23930769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name-with-args}"))
23946d3dbf51SGreg Clayton                                     {
23956d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
23966d3dbf51SGreg Clayton 
23976d3dbf51SGreg Clayton                                         if (sc->function)
23986d3dbf51SGreg Clayton                                         {
23996d3dbf51SGreg Clayton                                             var_success = true;
24006d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
24016d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
24026d3dbf51SGreg Clayton                                             if (cstr)
24036d3dbf51SGreg Clayton                                             {
24046d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
24056d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
24066d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
24076d3dbf51SGreg Clayton                                                 if (sc->block)
24086d3dbf51SGreg Clayton                                                 {
24096d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
24106d3dbf51SGreg Clayton 
24116d3dbf51SGreg Clayton                                                     if (inline_block)
24126d3dbf51SGreg Clayton                                                     {
24136d3dbf51SGreg Clayton                                                         get_function_vars = false;
24146d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
24156d3dbf51SGreg Clayton                                                         if (inline_info)
24166d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
24176d3dbf51SGreg Clayton                                                     }
24186d3dbf51SGreg Clayton                                                 }
24196d3dbf51SGreg Clayton 
24206d3dbf51SGreg Clayton                                                 if (get_function_vars)
24216d3dbf51SGreg Clayton                                                 {
24226d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
24236d3dbf51SGreg Clayton                                                 }
24246d3dbf51SGreg Clayton 
24256d3dbf51SGreg Clayton                                                 if (inline_info)
24266d3dbf51SGreg Clayton                                                 {
24276d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
24286d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
24296d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
24306d3dbf51SGreg Clayton                                                 }
24316d3dbf51SGreg Clayton 
24326d3dbf51SGreg Clayton                                                 VariableList args;
24336d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2434cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
24356d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
24366d3dbf51SGreg Clayton                                                 {
24376d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
2438e4a4f5d5SEnrico Granata                                                     const char *close_paren = nullptr;
2439e4a4f5d5SEnrico Granata                                                     const char *generic = strchr(cstr, '<');
2440e4a4f5d5SEnrico Granata                                                     // if before the arguments list begins there is a template sign
2441e4a4f5d5SEnrico Granata                                                     // then scan to the end of the generic args before you try to find
2442e4a4f5d5SEnrico Granata                                                     // the arguments list
2443e4a4f5d5SEnrico Granata                                                     if (generic && open_paren && generic < open_paren)
2444e4a4f5d5SEnrico Granata                                                     {
2445e4a4f5d5SEnrico Granata                                                         int generic_depth = 1;
2446e4a4f5d5SEnrico Granata                                                         ++generic;
2447e4a4f5d5SEnrico Granata                                                         for (;
2448e4a4f5d5SEnrico Granata                                                              *generic && generic_depth > 0;
2449e4a4f5d5SEnrico Granata                                                              generic++)
2450e4a4f5d5SEnrico Granata                                                         {
2451e4a4f5d5SEnrico Granata                                                             if (*generic == '<')
2452e4a4f5d5SEnrico Granata                                                                 generic_depth++;
2453e4a4f5d5SEnrico Granata                                                             if (*generic == '>')
2454e4a4f5d5SEnrico Granata                                                                 generic_depth--;
2455e4a4f5d5SEnrico Granata                                                         }
2456e4a4f5d5SEnrico Granata                                                         if (*generic)
2457e4a4f5d5SEnrico Granata                                                             open_paren = strchr(generic, '(');
2458e4a4f5d5SEnrico Granata                                                         else
2459e4a4f5d5SEnrico Granata                                                             open_paren = nullptr;
2460e4a4f5d5SEnrico Granata                                                     }
24616d3dbf51SGreg Clayton                                                     if (open_paren)
2462855958caSGreg Clayton                                                     {
24630769b2b1SMichael Sartain                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2464855958caSGreg Clayton                                                         {
2465855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2466855958caSGreg Clayton                                                             if (open_paren)
24676d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2468855958caSGreg Clayton                                                         }
2469855958caSGreg Clayton                                                         else
2470855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2471855958caSGreg Clayton                                                     }
24726d3dbf51SGreg Clayton 
24736d3dbf51SGreg Clayton                                                     if (open_paren)
24746d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
24756d3dbf51SGreg Clayton                                                     else
24766d3dbf51SGreg Clayton                                                     {
24776d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
24786d3dbf51SGreg Clayton                                                         s.PutChar ('(');
24796d3dbf51SGreg Clayton                                                     }
24805b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
24816d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
24826d3dbf51SGreg Clayton                                                     {
2483894f7359SEnrico Granata                                                         std::string buffer;
2484894f7359SEnrico Granata 
24856d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
24866d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2487894f7359SEnrico Granata                                                         const char *var_representation = nullptr;
24886d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
2489894f7359SEnrico Granata                                                         if (var_value_sp->GetClangType().IsAggregateType() &&
2490894f7359SEnrico Granata                                                             DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
2491894f7359SEnrico Granata                                                         {
2492894f7359SEnrico Granata                                                             static StringSummaryFormat format(TypeSummaryImpl::Flags()
2493894f7359SEnrico Granata                                                                                               .SetHideItemNames(false)
2494894f7359SEnrico Granata                                                                                               .SetShowMembersOneLiner(true),
2495894f7359SEnrico Granata                                                                                               "");
2496f35bc632SEnrico Granata                                                             format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
2497894f7359SEnrico Granata                                                             var_representation = buffer.c_str();
2498894f7359SEnrico Granata                                                         }
2499894f7359SEnrico Granata                                                         else
2500894f7359SEnrico Granata                                                             var_representation = var_value_sp->GetValueAsCString();
25016d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
25026d3dbf51SGreg Clayton                                                             s.PutCString (", ");
25033b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2504cc7f9bf5SEnrico Granata                                                         {
2505894f7359SEnrico Granata                                                             if (var_representation)
2506894f7359SEnrico Granata                                                                 s.Printf ("%s=%s", var_name, var_representation);
25073b188b17SGreg Clayton                                                             else
2508cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2509cc7f9bf5SEnrico Granata                                                         }
2510cc7f9bf5SEnrico Granata                                                         else
25113b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
25126d3dbf51SGreg Clayton                                                     }
25136d3dbf51SGreg Clayton 
25146d3dbf51SGreg Clayton                                                     if (close_paren)
25156d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
25166d3dbf51SGreg Clayton                                                     else
25176d3dbf51SGreg Clayton                                                         s.PutChar(')');
25186d3dbf51SGreg Clayton 
25196d3dbf51SGreg Clayton                                                 }
25206d3dbf51SGreg Clayton                                                 else
25216d3dbf51SGreg Clayton                                                 {
25226d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
25236d3dbf51SGreg Clayton                                                 }
25246d3dbf51SGreg Clayton                                             }
25256d3dbf51SGreg Clayton                                         }
25266d3dbf51SGreg Clayton                                         else if (sc->symbol)
25276d3dbf51SGreg Clayton                                         {
25286d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
25296d3dbf51SGreg Clayton                                             if (cstr)
25306d3dbf51SGreg Clayton                                             {
25316d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
25326d3dbf51SGreg Clayton                                                 var_success = true;
25336d3dbf51SGreg Clayton                                             }
25346d3dbf51SGreg Clayton                                         }
25356d3dbf51SGreg Clayton                                     }
2536aff1b357SJason Molenda                                     else if (IsToken (var_name_begin, "addr-offset}")
2537aff1b357SJason Molenda                                             || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
25381b654882SGreg Clayton                                     {
2539aff1b357SJason Molenda                                         if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
2540aff1b357SJason Molenda                                         {
2541aff1b357SJason Molenda                                             addr_offset_print_with_no_padding = true;
2542aff1b357SJason Molenda                                             addr_offset_concrete_func_only = true;
2543aff1b357SJason Molenda                                         }
25441b654882SGreg Clayton                                         var_success = addr != NULL;
25451b654882SGreg Clayton                                         if (var_success)
25461b654882SGreg Clayton                                         {
25471b654882SGreg Clayton                                             format_addr = *addr;
25481b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25491b654882SGreg Clayton                                         }
25501b654882SGreg Clayton                                     }
25510769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "line-offset}"))
25521b654882SGreg Clayton                                     {
25531b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
25541b654882SGreg Clayton                                         if (var_success)
25551b654882SGreg Clayton                                         {
25561b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
25571b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25581b654882SGreg Clayton                                         }
25591b654882SGreg Clayton                                     }
25600769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "pc-offset}"))
25611b654882SGreg Clayton                                     {
2562b57e4a1bSJason Molenda                                         StackFrame *frame = exe_ctx->GetFramePtr();
2563c14ee32dSGreg Clayton                                         var_success = frame != NULL;
25641b654882SGreg Clayton                                         if (var_success)
25651b654882SGreg Clayton                                         {
2566c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
25671b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25681b654882SGreg Clayton                                         }
25691b654882SGreg Clayton                                     }
25701b654882SGreg Clayton                                 }
25711b654882SGreg Clayton                             }
25721b654882SGreg Clayton                             break;
25731b654882SGreg Clayton 
25741b654882SGreg Clayton                         case 'l':
25750769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "line."))
25761b654882SGreg Clayton                             {
25771b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
25781b654882SGreg Clayton                                 {
25791b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
25800769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
25811b654882SGreg Clayton                                     {
25821b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
25831b654882SGreg Clayton 
25840769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "basename}"))
25851b654882SGreg Clayton                                         {
25861b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
25879076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25881b654882SGreg Clayton                                         }
25890769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fullpath}"))
25901b654882SGreg Clayton                                         {
25911b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
25929076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25931b654882SGreg Clayton                                         }
25941b654882SGreg Clayton                                     }
25950769b2b1SMichael Sartain                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
25961b654882SGreg Clayton                                     {
25971b654882SGreg Clayton                                         var_success = true;
25980769b2b1SMichael Sartain                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
25991b654882SGreg Clayton                                     }
26000769b2b1SMichael Sartain                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
26010769b2b1SMichael Sartain                                              (IsToken (var_name_begin, "end-addr}")))
26021b654882SGreg Clayton                                     {
26031b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
26041b654882SGreg Clayton                                         if (var_success)
26051b654882SGreg Clayton                                         {
26061b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
26071b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
26081b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
26091b654882SGreg Clayton                                         }
26101b654882SGreg Clayton                                     }
26111b654882SGreg Clayton                                 }
26121b654882SGreg Clayton                             }
26131b654882SGreg Clayton                             break;
2614aff1b357SJason Molenda                         case 'c':
2615aff1b357SJason Molenda                             if (IsToken (var_name_begin, "current-pc-arrow"))
2616aff1b357SJason Molenda                             {
2617aff1b357SJason Molenda                                 if (addr && exe_ctx && exe_ctx->GetFramePtr())
2618aff1b357SJason Molenda                                 {
2619aff1b357SJason Molenda                                     RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
2620aff1b357SJason Molenda                                     if (reg_ctx.get())
2621aff1b357SJason Molenda                                     {
2622aff1b357SJason Molenda                                         addr_t pc_loadaddr = reg_ctx->GetPC();
2623aff1b357SJason Molenda                                         if (pc_loadaddr != LLDB_INVALID_ADDRESS)
2624aff1b357SJason Molenda                                         {
2625aff1b357SJason Molenda                                             Address pc;
2626aff1b357SJason Molenda                                             pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
2627aff1b357SJason Molenda                                             if (pc == *addr)
2628aff1b357SJason Molenda                                             {
2629aff1b357SJason Molenda                                                 s.Printf ("-> ");
2630aff1b357SJason Molenda                                                 var_success = true;
2631aff1b357SJason Molenda                                             }
263298b3fde8SJason Molenda                                         }
263398b3fde8SJason Molenda                                     }
263498b3fde8SJason Molenda                                     if (var_success == false)
2635aff1b357SJason Molenda                                     {
2636aff1b357SJason Molenda                                         s.Printf("   ");
2637aff1b357SJason Molenda                                         var_success = true;
2638aff1b357SJason Molenda                                     }
2639aff1b357SJason Molenda                                 }
264098b3fde8SJason Molenda                                 var_success = true;
2641aff1b357SJason Molenda                             }
2642aff1b357SJason Molenda                             break;
26431b654882SGreg Clayton                         }
26441b654882SGreg Clayton 
26451b654882SGreg Clayton                         if (var_success)
26461b654882SGreg Clayton                         {
26471b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
26481b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
26491b654882SGreg Clayton                             {
2650b57e4a1bSJason Molenda                                 StackFrame *frame = exe_ctx->GetFramePtr();
26511b654882SGreg Clayton                                 // We have a register value to display...
26521b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
26531b654882SGreg Clayton                                 {
2654c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
26551b654882SGreg Clayton                                 }
26561b654882SGreg Clayton                                 else
26571b654882SGreg Clayton                                 {
26581b654882SGreg Clayton                                     if (reg_ctx == NULL)
2659c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
26601b654882SGreg Clayton 
26611b654882SGreg Clayton                                     if (reg_ctx)
26621b654882SGreg Clayton                                     {
26631b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
26641b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
26651b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
26661b654882SGreg Clayton                                         var_success = reg_info != NULL;
26671b654882SGreg Clayton                                     }
26681b654882SGreg Clayton                                 }
26691b654882SGreg Clayton                             }
26701b654882SGreg Clayton 
26711b654882SGreg Clayton                             if (reg_info != NULL)
26721b654882SGreg Clayton                             {
26737349bd90SGreg Clayton                                 RegisterValue reg_value;
26747349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
26757349bd90SGreg Clayton                                 if (var_success)
26761b654882SGreg Clayton                                 {
26779a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
26781b654882SGreg Clayton                                 }
26791b654882SGreg Clayton                             }
26801b654882SGreg Clayton 
26811b654882SGreg Clayton                             if (format_file_spec)
26821b654882SGreg Clayton                             {
26831b654882SGreg Clayton                                 s << format_file_spec;
26841b654882SGreg Clayton                             }
26851b654882SGreg Clayton 
26861b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
26871b654882SGreg Clayton                             if (format_addr.IsValid())
26881b654882SGreg Clayton                             {
26890603aa9dSGreg Clayton                                 var_success = false;
26900603aa9dSGreg Clayton 
26911b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
26921b654882SGreg Clayton                                 {
26931b654882SGreg Clayton                                     Address func_addr;
26940603aa9dSGreg Clayton 
26950603aa9dSGreg Clayton                                     if (sc)
26960603aa9dSGreg Clayton                                     {
26971b654882SGreg Clayton                                         if (sc->function)
26980d9c9934SGreg Clayton                                         {
26991b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2700aff1b357SJason Molenda                                             if (sc->block && addr_offset_concrete_func_only == false)
27010d9c9934SGreg Clayton                                             {
27020d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
27030d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
27040d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
27050d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
27060d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
27070d9c9934SGreg Clayton                                                 AddressRange inline_range;
27080d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
27090d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
27100d9c9934SGreg Clayton                                             }
27110d9c9934SGreg Clayton                                         }
2712e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2713e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
27140603aa9dSGreg Clayton                                     }
27151b654882SGreg Clayton 
27160603aa9dSGreg Clayton                                     if (func_addr.IsValid())
27171b654882SGreg Clayton                                     {
2718aff1b357SJason Molenda                                         const char *addr_offset_padding  =  " ";
2719aff1b357SJason Molenda                                         if (addr_offset_print_with_no_padding)
2720aff1b357SJason Molenda                                         {
2721aff1b357SJason Molenda                                             addr_offset_padding = "";
2722aff1b357SJason Molenda                                         }
27231b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
27241b654882SGreg Clayton                                         {
27251b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
27261b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
27271b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2728aff1b357SJason Molenda                                                 s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
27291b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2730aff1b357SJason Molenda                                                 s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
27310603aa9dSGreg Clayton                                             var_success = true;
27321b654882SGreg Clayton                                         }
27331b654882SGreg Clayton                                         else
27340603aa9dSGreg Clayton                                         {
27350603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
27360603aa9dSGreg Clayton                                             if (target)
27370603aa9dSGreg Clayton                                             {
27380603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
27390603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
27400603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2741aff1b357SJason Molenda                                                     s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
27420603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2743aff1b357SJason Molenda                                                     s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
27440603aa9dSGreg Clayton                                                 var_success = true;
27450603aa9dSGreg Clayton                                             }
27460603aa9dSGreg Clayton                                         }
27471b654882SGreg Clayton                                     }
27481b654882SGreg Clayton                                 }
27491b654882SGreg Clayton                                 else
27501b654882SGreg Clayton                                 {
27510603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
27521b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
27530603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
27540603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
27551b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
27561b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
27571b654882SGreg Clayton 
27581b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
27590603aa9dSGreg Clayton                                     {
2760aff1b357SJason Molenda                                         int addr_width = 0;
2761aff1b357SJason Molenda                                         if (exe_ctx && target)
2762aff1b357SJason Molenda                                         {
2763fd1a9362SEric Christopher                                             addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2764aff1b357SJason Molenda                                         }
276535f1a0d5SGreg Clayton                                         if (addr_width == 0)
276635f1a0d5SGreg Clayton                                             addr_width = 16;
2767aff1b357SJason Molenda                                         if (print_file_addr_or_load_addr)
2768aff1b357SJason Molenda                                         {
2769aff1b357SJason Molenda                                             format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
2770aff1b357SJason Molenda                                         }
2771aff1b357SJason Molenda                                         else
2772aff1b357SJason Molenda                                         {
2773d01b2953SDaniel Malea                                             s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
2774aff1b357SJason Molenda                                         }
27750603aa9dSGreg Clayton                                         var_success = true;
27760603aa9dSGreg Clayton                                     }
27771b654882SGreg Clayton                                 }
27781b654882SGreg Clayton                             }
27791b654882SGreg Clayton                         }
27801b654882SGreg Clayton 
27811b654882SGreg Clayton                         if (var_success == false)
27821b654882SGreg Clayton                             success = false;
27831b654882SGreg Clayton                     }
27841b654882SGreg Clayton                     p = var_name_end;
27851b654882SGreg Clayton                 }
27861b654882SGreg Clayton                 else
27871b654882SGreg Clayton                     break;
27881b654882SGreg Clayton             }
27891b654882SGreg Clayton             else
27901b654882SGreg Clayton             {
27911b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
27921b654882SGreg Clayton                 s.PutChar(*p);
27931b654882SGreg Clayton             }
27941b654882SGreg Clayton         }
27951b654882SGreg Clayton         else if (*p == '\\')
27961b654882SGreg Clayton         {
27971b654882SGreg Clayton             ++p; // skip the slash
27981b654882SGreg Clayton             switch (*p)
27991b654882SGreg Clayton             {
28001b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
28011b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
28021b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
28031b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
28041b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
28051b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
28061b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
28071b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
28081b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
28091b654882SGreg Clayton             case '0':
28101b654882SGreg Clayton                 // 1 to 3 octal chars
28111b654882SGreg Clayton                 {
28120603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
28130603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
28140603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
28150603aa9dSGreg Clayton 
28160603aa9dSGreg Clayton                     int i;
28170603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
28180603aa9dSGreg Clayton                         oct_str[i] = p[i];
28190603aa9dSGreg Clayton 
28200603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
28210603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
28220603aa9dSGreg Clayton                     // one less than i (even if i is zero)
28230603aa9dSGreg Clayton                     p += i - 1;
28240603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
28250603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
28261b654882SGreg Clayton                     {
2827c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
28281b654882SGreg Clayton                     }
28291b654882SGreg Clayton                 }
28301b654882SGreg Clayton                 break;
28311b654882SGreg Clayton 
28321b654882SGreg Clayton             case 'x':
28331b654882SGreg Clayton                 // hex number in the format
28340603aa9dSGreg Clayton                 if (isxdigit(p[1]))
28351b654882SGreg Clayton                 {
28360603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
28371b654882SGreg Clayton 
28380603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
28390603aa9dSGreg Clayton                     // NULL terminator
28401b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
28411b654882SGreg Clayton                     hex_str[0] = *p;
28420603aa9dSGreg Clayton                     if (isxdigit(p[1]))
28430603aa9dSGreg Clayton                     {
28440603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
28451b654882SGreg Clayton                         hex_str[1] = *p;
28460603aa9dSGreg Clayton                     }
28470603aa9dSGreg Clayton 
28481b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
28490603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2850c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
28511b654882SGreg Clayton                 }
28521b654882SGreg Clayton                 else
28531b654882SGreg Clayton                 {
28540603aa9dSGreg Clayton                     s.PutChar('x');
28551b654882SGreg Clayton                 }
28561b654882SGreg Clayton                 break;
28571b654882SGreg Clayton 
28581b654882SGreg Clayton             default:
28590603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
28600603aa9dSGreg Clayton                 // came after the '\'
28610603aa9dSGreg Clayton                 s << *p;
28621b654882SGreg Clayton                 break;
28631b654882SGreg Clayton 
28641b654882SGreg Clayton             }
28651b654882SGreg Clayton 
28661b654882SGreg Clayton         }
28671b654882SGreg Clayton     }
28681b654882SGreg Clayton     if (end)
28691b654882SGreg Clayton         *end = p;
28701b654882SGreg Clayton     return success;
28711b654882SGreg Clayton }
28721b654882SGreg Clayton 
2873c3ce7f27SMichael Sartain bool
2874c3ce7f27SMichael Sartain Debugger::FormatPrompt
2875c3ce7f27SMichael Sartain (
2876c3ce7f27SMichael Sartain     const char *format,
2877c3ce7f27SMichael Sartain     const SymbolContext *sc,
2878c3ce7f27SMichael Sartain     const ExecutionContext *exe_ctx,
2879c3ce7f27SMichael Sartain     const Address *addr,
2880c3ce7f27SMichael Sartain     Stream &s,
2881c3ce7f27SMichael Sartain     ValueObject* valobj
2882c3ce7f27SMichael Sartain )
2883c3ce7f27SMichael Sartain {
2884c3ce7f27SMichael Sartain     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2885c3ce7f27SMichael Sartain     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2886c3ce7f27SMichael Sartain     if (format_str.length())
2887c3ce7f27SMichael Sartain         format = format_str.c_str();
2888aff1b357SJason Molenda     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false);
2889c3ce7f27SMichael Sartain }
2890c3ce7f27SMichael Sartain 
2891aff1b357SJason Molenda bool
2892aff1b357SJason Molenda Debugger::FormatDisassemblerAddress (const char *format,
2893aff1b357SJason Molenda                                      const SymbolContext *sc,
2894aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
2895aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
2896aff1b357SJason Molenda                                      const Address *addr,
2897aff1b357SJason Molenda                                      Stream &s)
2898aff1b357SJason Molenda {
2899aff1b357SJason Molenda     if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope())
2900aff1b357SJason Molenda     {
2901aff1b357SJason Molenda         format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
2902aff1b357SJason Molenda     }
2903aff1b357SJason Molenda     bool function_changed = false;
2904aff1b357SJason Molenda     bool initial_function = false;
2905aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
2906aff1b357SJason Molenda     {
2907aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
2908aff1b357SJason Molenda         {
2909aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
2910aff1b357SJason Molenda             {
2911aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
2912aff1b357SJason Molenda                 {
2913aff1b357SJason Molenda                     function_changed = true;
2914aff1b357SJason Molenda                 }
2915aff1b357SJason Molenda             }
2916aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
2917aff1b357SJason Molenda             {
2918aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
2919aff1b357SJason Molenda                 {
2920aff1b357SJason Molenda                     function_changed = true;
2921aff1b357SJason Molenda                 }
2922aff1b357SJason Molenda             }
2923aff1b357SJason Molenda         }
2924aff1b357SJason Molenda     }
2925aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
2926aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
2927aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
2928aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
2929aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
2930aff1b357SJason Molenda     {
2931aff1b357SJason Molenda         initial_function = true;
2932aff1b357SJason Molenda     }
2933aff1b357SJason Molenda     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function);
2934aff1b357SJason Molenda }
2935aff1b357SJason Molenda 
2936aff1b357SJason Molenda 
2937228063cdSJim Ingham void
2938228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2939228063cdSJim Ingham {
29404f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
29414f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
29424f02b22dSJim Ingham     // callback.
2943228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2944228063cdSJim Ingham }
2945228063cdSJim Ingham 
2946228063cdSJim Ingham bool
2947228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2948228063cdSJim Ingham {
2949228063cdSJim Ingham     Log::Callbacks log_callbacks;
2950228063cdSJim Ingham 
2951228063cdSJim Ingham     StreamSP log_stream_sp;
29529a028519SSean Callanan     if (m_log_callback_stream_sp)
2953228063cdSJim Ingham     {
2954228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2955228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2956228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2957228063cdSJim Ingham     }
2958228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2959228063cdSJim Ingham     {
296044d93782SGreg Clayton         log_stream_sp = GetOutputFile();
2961228063cdSJim Ingham     }
2962228063cdSJim Ingham     else
2963228063cdSJim Ingham     {
2964228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2965c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2966c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2967c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2968228063cdSJim Ingham         {
2969228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2970228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2971228063cdSJim Ingham         }
2972228063cdSJim Ingham     }
2973228063cdSJim Ingham     assert (log_stream_sp.get());
2974228063cdSJim Ingham 
2975228063cdSJim Ingham     if (log_options == 0)
2976228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2977228063cdSJim Ingham 
297857abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2979228063cdSJim Ingham     {
2980228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2981228063cdSJim Ingham         return true;
2982228063cdSJim Ingham     }
2983228063cdSJim Ingham     else
2984228063cdSJim Ingham     {
2985228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2986228063cdSJim Ingham         if (log_channel_sp)
2987228063cdSJim Ingham         {
2988228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2989228063cdSJim Ingham             {
2990228063cdSJim Ingham                 return true;
2991228063cdSJim Ingham             }
2992228063cdSJim Ingham             else
2993228063cdSJim Ingham             {
2994228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2995228063cdSJim Ingham                 return false;
2996228063cdSJim Ingham             }
2997228063cdSJim Ingham         }
2998228063cdSJim Ingham         else
2999228063cdSJim Ingham         {
3000228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
3001228063cdSJim Ingham             return false;
3002228063cdSJim Ingham         }
3003228063cdSJim Ingham     }
3004228063cdSJim Ingham     return false;
3005228063cdSJim Ingham }
3006228063cdSJim Ingham 
30079585fbfcSGreg Clayton SourceManager &
30089585fbfcSGreg Clayton Debugger::GetSourceManager ()
30099585fbfcSGreg Clayton {
30109585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
30119585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
30129585fbfcSGreg Clayton     return *m_source_manager_ap;
30139585fbfcSGreg Clayton }
30149585fbfcSGreg Clayton 
30159585fbfcSGreg Clayton 
301644d93782SGreg Clayton 
301744d93782SGreg Clayton // This function handles events that were broadcast by the process.
301844d93782SGreg Clayton void
301944d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
302044d93782SGreg Clayton {
302144d93782SGreg Clayton     using namespace lldb;
302244d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
302344d93782SGreg Clayton 
302444d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
302544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
302644d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
302744d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
302844d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
302944d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
303044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
303144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
303244d93782SGreg Clayton //    {
303344d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
303444d93782SGreg Clayton //    }
303544d93782SGreg Clayton //
303644d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
303744d93782SGreg Clayton     {
303844d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
303944d93782SGreg Clayton         if (num_new_locations > 0)
304044d93782SGreg Clayton         {
304144d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
304244d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
304344d93782SGreg Clayton             if (output_sp)
304444d93782SGreg Clayton             {
304544d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
304644d93782SGreg Clayton                                   num_new_locations,
304744d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
304844d93782SGreg Clayton                                   breakpoint->GetID());
304944d93782SGreg Clayton                 RefreshTopIOHandler();
305044d93782SGreg Clayton             }
305144d93782SGreg Clayton         }
305244d93782SGreg Clayton     }
305344d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
305444d93782SGreg Clayton //    {
305544d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
305644d93782SGreg Clayton //    }
305744d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
305844d93782SGreg Clayton //    {
305944d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
306044d93782SGreg Clayton //    }
306144d93782SGreg Clayton }
306244d93782SGreg Clayton 
306344d93782SGreg Clayton size_t
306444d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
306544d93782SGreg Clayton {
306644d93782SGreg Clayton     size_t total_bytes = 0;
306744d93782SGreg Clayton     if (stream == NULL)
306844d93782SGreg Clayton         stream = GetOutputFile().get();
306944d93782SGreg Clayton 
307044d93782SGreg Clayton     if (stream)
307144d93782SGreg Clayton     {
307244d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
307344d93782SGreg Clayton         if (process == NULL)
307444d93782SGreg Clayton         {
307544d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
307644d93782SGreg Clayton             if (target_sp)
307744d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
307844d93782SGreg Clayton         }
307944d93782SGreg Clayton         if (process)
308044d93782SGreg Clayton         {
308144d93782SGreg Clayton             Error error;
308244d93782SGreg Clayton             size_t len;
308344d93782SGreg Clayton             char stdio_buffer[1024];
308444d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
308544d93782SGreg Clayton             {
308644d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
308744d93782SGreg Clayton                 total_bytes += len;
308844d93782SGreg Clayton             }
308944d93782SGreg Clayton         }
309044d93782SGreg Clayton         stream->Flush();
309144d93782SGreg Clayton     }
309244d93782SGreg Clayton     return total_bytes;
309344d93782SGreg Clayton }
309444d93782SGreg Clayton 
309544d93782SGreg Clayton size_t
309644d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
309744d93782SGreg Clayton {
309844d93782SGreg Clayton     size_t total_bytes = 0;
309944d93782SGreg Clayton     if (stream == NULL)
310044d93782SGreg Clayton         stream = GetOutputFile().get();
310144d93782SGreg Clayton 
310244d93782SGreg Clayton     if (stream)
310344d93782SGreg Clayton     {
310444d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
310544d93782SGreg Clayton         if (process == NULL)
310644d93782SGreg Clayton         {
310744d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
310844d93782SGreg Clayton             if (target_sp)
310944d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
311044d93782SGreg Clayton         }
311144d93782SGreg Clayton         if (process)
311244d93782SGreg Clayton         {
311344d93782SGreg Clayton             Error error;
311444d93782SGreg Clayton             size_t len;
311544d93782SGreg Clayton             char stdio_buffer[1024];
311644d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
311744d93782SGreg Clayton             {
311844d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
311944d93782SGreg Clayton                 total_bytes += len;
312044d93782SGreg Clayton             }
312144d93782SGreg Clayton         }
312244d93782SGreg Clayton         stream->Flush();
312344d93782SGreg Clayton     }
312444d93782SGreg Clayton     return total_bytes;
312544d93782SGreg Clayton }
312644d93782SGreg Clayton 
3127dc6224e0SGreg Clayton 
312844d93782SGreg Clayton // This function handles events that were broadcast by the process.
312944d93782SGreg Clayton void
313044d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
313144d93782SGreg Clayton {
313244d93782SGreg Clayton     using namespace lldb;
313344d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
313444d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
313544d93782SGreg Clayton 
3136b4874f1aSGreg Clayton     StreamString output_stream;
3137b4874f1aSGreg Clayton     StreamString error_stream;
313844d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
313944d93782SGreg Clayton 
3140b4874f1aSGreg Clayton     if (!gui_enabled)
3141b4874f1aSGreg Clayton     {
3142b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
314344d93782SGreg Clayton         assert (process_sp);
314444d93782SGreg Clayton 
3145b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
314644d93782SGreg Clayton         {
3147b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
314844d93782SGreg Clayton         }
3149b4874f1aSGreg Clayton 
3150b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
315144d93782SGreg Clayton         {
3152b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
315344d93782SGreg Clayton         }
3154b4874f1aSGreg Clayton 
3155b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
315644d93782SGreg Clayton         {
3157dc6224e0SGreg Clayton             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
315844d93782SGreg Clayton         }
3159b4874f1aSGreg Clayton 
3160b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
3161b4874f1aSGreg Clayton         {
3162b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
31636fea17e8SGreg Clayton             bool top_io_handler_hid = false;
31646fea17e8SGreg Clayton 
31656fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
31666fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
3167b4874f1aSGreg Clayton 
3168b4874f1aSGreg Clayton             if (output_stream.GetSize())
3169b4874f1aSGreg Clayton             {
3170b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
3171b4874f1aSGreg Clayton                 if (output_stream_sp)
3172b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
3173b4874f1aSGreg Clayton             }
3174b4874f1aSGreg Clayton 
3175b4874f1aSGreg Clayton             if (error_stream.GetSize())
3176b4874f1aSGreg Clayton             {
3177b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
3178b4874f1aSGreg Clayton                 if (error_stream_sp)
3179b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
318044d93782SGreg Clayton             }
318144d93782SGreg Clayton 
318244d93782SGreg Clayton             if (top_io_handler_hid)
318344d93782SGreg Clayton                 RefreshTopIOHandler();
318444d93782SGreg Clayton         }
318544d93782SGreg Clayton 
3186b4874f1aSGreg Clayton         if (pop_process_io_handler)
3187b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
3188b4874f1aSGreg Clayton     }
3189b4874f1aSGreg Clayton }
3190b4874f1aSGreg Clayton 
319144d93782SGreg Clayton void
319244d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
319344d93782SGreg Clayton {
319444d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
319544d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
319644d93782SGreg Clayton     using namespace lldb;
319744d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
319844d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
319944d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
320044d93782SGreg Clayton     {
320144d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
320244d93782SGreg Clayton         if (thread_sp)
320344d93782SGreg Clayton         {
320444d93782SGreg Clayton             HideTopIOHandler();
320544d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
320644d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
320744d93782SGreg Clayton             RefreshTopIOHandler();
320844d93782SGreg Clayton         }
320944d93782SGreg Clayton     }
321044d93782SGreg Clayton }
321144d93782SGreg Clayton 
321244d93782SGreg Clayton bool
321344d93782SGreg Clayton Debugger::IsForwardingEvents ()
321444d93782SGreg Clayton {
321544d93782SGreg Clayton     return (bool)m_forward_listener_sp;
321644d93782SGreg Clayton }
321744d93782SGreg Clayton 
321844d93782SGreg Clayton void
321944d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
322044d93782SGreg Clayton {
322144d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
322244d93782SGreg Clayton }
322344d93782SGreg Clayton 
322444d93782SGreg Clayton void
322544d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
322644d93782SGreg Clayton {
322744d93782SGreg Clayton     m_forward_listener_sp.reset();
322844d93782SGreg Clayton }
322944d93782SGreg Clayton 
323044d93782SGreg Clayton 
323144d93782SGreg Clayton void
323244d93782SGreg Clayton Debugger::DefaultEventHandler()
323344d93782SGreg Clayton {
323444d93782SGreg Clayton     Listener& listener(GetListener());
323544d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
323644d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
323744d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
323844d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
323944d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
324044d93782SGreg Clayton 
324144d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
324244d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
324344d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
324444d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
324544d93782SGreg Clayton 
324644d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
324744d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
324844d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
324944d93782SGreg Clayton 
325044d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
325144d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
325244d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
325344d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
325444d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
325544d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
325644d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
325744d93782SGreg Clayton 
3258afa91e33SGreg Clayton     // Let the thread that spawned us know that we have started up and
3259afa91e33SGreg Clayton     // that we are now listening to all required events so no events get missed
3260afa91e33SGreg Clayton     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
3261afa91e33SGreg Clayton 
326244d93782SGreg Clayton     bool done = false;
326344d93782SGreg Clayton     while (!done)
326444d93782SGreg Clayton     {
326544d93782SGreg Clayton         EventSP event_sp;
326644d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
326744d93782SGreg Clayton         {
326844d93782SGreg Clayton             if (event_sp)
326944d93782SGreg Clayton             {
327044d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
327144d93782SGreg Clayton                 if (broadcaster)
327244d93782SGreg Clayton                 {
327344d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
327444d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
327544d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
327644d93782SGreg Clayton                     {
327744d93782SGreg Clayton                         HandleProcessEvent (event_sp);
327844d93782SGreg Clayton                     }
327944d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
328044d93782SGreg Clayton                     {
328144d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
328244d93782SGreg Clayton                         {
328344d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
328444d93782SGreg Clayton                         }
328544d93782SGreg Clayton                     }
328644d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
328744d93782SGreg Clayton                     {
328844d93782SGreg Clayton                         HandleThreadEvent (event_sp);
328944d93782SGreg Clayton                     }
329044d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
329144d93782SGreg Clayton                     {
329244d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
329344d93782SGreg Clayton                         {
329444d93782SGreg Clayton                             done = true;
329544d93782SGreg Clayton                         }
329644d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
329744d93782SGreg Clayton                         {
329844d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
329944d93782SGreg Clayton                             if (data && data[0])
330044d93782SGreg Clayton                             {
330144d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
330244d93782SGreg Clayton                                 if (error_sp)
330344d93782SGreg Clayton                                 {
330444d93782SGreg Clayton                                     HideTopIOHandler();
330544d93782SGreg Clayton                                     error_sp->PutCString(data);
330644d93782SGreg Clayton                                     error_sp->Flush();
330744d93782SGreg Clayton                                     RefreshTopIOHandler();
330844d93782SGreg Clayton                                 }
330944d93782SGreg Clayton                             }
331044d93782SGreg Clayton                         }
331144d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
331244d93782SGreg Clayton                         {
331344d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
331444d93782SGreg Clayton                             if (data && data[0])
331544d93782SGreg Clayton                             {
331644d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
331744d93782SGreg Clayton                                 if (output_sp)
331844d93782SGreg Clayton                                 {
331944d93782SGreg Clayton                                     HideTopIOHandler();
332044d93782SGreg Clayton                                     output_sp->PutCString(data);
332144d93782SGreg Clayton                                     output_sp->Flush();
332244d93782SGreg Clayton                                     RefreshTopIOHandler();
332344d93782SGreg Clayton                                 }
332444d93782SGreg Clayton                             }
332544d93782SGreg Clayton                         }
332644d93782SGreg Clayton                     }
332744d93782SGreg Clayton                 }
332844d93782SGreg Clayton 
332944d93782SGreg Clayton                 if (m_forward_listener_sp)
333044d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
333144d93782SGreg Clayton             }
333244d93782SGreg Clayton         }
333344d93782SGreg Clayton     }
333444d93782SGreg Clayton }
333544d93782SGreg Clayton 
333644d93782SGreg Clayton lldb::thread_result_t
333744d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
333844d93782SGreg Clayton {
333944d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
334044d93782SGreg Clayton     return NULL;
334144d93782SGreg Clayton }
334244d93782SGreg Clayton 
334344d93782SGreg Clayton bool
334444d93782SGreg Clayton Debugger::StartEventHandlerThread()
334544d93782SGreg Clayton {
3346acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
3347807b6b32SGreg Clayton     {
3348afa91e33SGreg Clayton         // We must synchronize with the DefaultEventHandler() thread to ensure
3349afa91e33SGreg Clayton         // it is up and running and listening to events before we return from
3350afa91e33SGreg Clayton         // this function. We do this by listening to events for the
3351afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
3352afa91e33SGreg Clayton         Listener listener("lldb.debugger.event-handler");
3353afa91e33SGreg Clayton         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
3354afa91e33SGreg Clayton 
33557c2896a2SZachary Turner         // Use larger 8MB stack for this thread
3356afa91e33SGreg Clayton         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
3357afa91e33SGreg Clayton                                                               this,
3358afa91e33SGreg Clayton                                                               NULL,
33597c2896a2SZachary Turner                                                               g_debugger_event_thread_stack_bytes);
3360afa91e33SGreg Clayton 
3361afa91e33SGreg Clayton         // Make sure DefaultEventHandler() is running and listening to events before we return
3362afa91e33SGreg Clayton         // from this function. We are only listening for events of type
3363afa91e33SGreg Clayton         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
3364afa91e33SGreg Clayton         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
3365afa91e33SGreg Clayton         lldb::EventSP event_sp;
3366afa91e33SGreg Clayton         listener.WaitForEvent(NULL, event_sp);
3367807b6b32SGreg Clayton     }
3368acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
336944d93782SGreg Clayton }
337044d93782SGreg Clayton 
337144d93782SGreg Clayton void
337244d93782SGreg Clayton Debugger::StopEventHandlerThread()
337344d93782SGreg Clayton {
3374acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
337544d93782SGreg Clayton     {
337644d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
337739de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
337844d93782SGreg Clayton     }
337944d93782SGreg Clayton }
338044d93782SGreg Clayton 
338144d93782SGreg Clayton 
338244d93782SGreg Clayton lldb::thread_result_t
338344d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
338444d93782SGreg Clayton {
338544d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
338644d93782SGreg Clayton     debugger->ExecuteIOHanders();
338744d93782SGreg Clayton     debugger->StopEventHandlerThread();
338844d93782SGreg Clayton     return NULL;
338944d93782SGreg Clayton }
339044d93782SGreg Clayton 
339144d93782SGreg Clayton bool
339244d93782SGreg Clayton Debugger::StartIOHandlerThread()
339344d93782SGreg Clayton {
3394acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
3395807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
3396807b6b32SGreg Clayton                                                             IOHandlerThread,
3397807b6b32SGreg Clayton                                                             this,
3398807b6b32SGreg Clayton                                                             NULL,
3399807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
3400acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
340144d93782SGreg Clayton }
340244d93782SGreg Clayton 
340344d93782SGreg Clayton void
340444d93782SGreg Clayton Debugger::StopIOHandlerThread()
340544d93782SGreg Clayton {
3406acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
340744d93782SGreg Clayton     {
340844d93782SGreg Clayton         if (m_input_file_sp)
340944d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
341039de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
341144d93782SGreg Clayton     }
341244d93782SGreg Clayton }
341344d93782SGreg Clayton 
3414893c932aSJim Ingham Target *
3415893c932aSJim Ingham Debugger::GetDummyTarget()
3416893c932aSJim Ingham {
3417893c932aSJim Ingham     return m_target_list.GetDummyTarget (*this).get();
3418893c932aSJim Ingham }
3419893c932aSJim Ingham 
3420893c932aSJim Ingham Target *
3421*33df7cd3SJim Ingham Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
3422893c932aSJim Ingham {
3423*33df7cd3SJim Ingham     Target *target = nullptr;
3424*33df7cd3SJim Ingham     if (!prefer_dummy)
3425*33df7cd3SJim Ingham     {
3426*33df7cd3SJim Ingham         target = m_target_list.GetSelectedTarget().get();
3427*33df7cd3SJim Ingham         if (target)
3428*33df7cd3SJim Ingham             return target;
3429*33df7cd3SJim Ingham     }
3430893c932aSJim Ingham 
3431893c932aSJim Ingham     return GetDummyTarget();
3432893c932aSJim Ingham }
343344d93782SGreg Clayton 
3434