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"
2130fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h"
221f746071SGreg Clayton #include "lldb/Core/Module.h"
23e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
247349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2530fdc8d8SChris Lattner #include "lldb/Core/State.h"
265b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
27228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
2844d93782SGreg Clayton #include "lldb/Core/StreamFile.h"
291b654882SGreg Clayton #include "lldb/Core/StreamString.h"
30705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
3130fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
324becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
336d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
355548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
36894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h"
3721dfcd9dSEnrico Granata #include "lldb/Host/DynamicLibrary.h"
38a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
396611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
4067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
421f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
431f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
441f746071SGreg Clayton #include "lldb/Symbol/Function.h"
451f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
466d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
4730fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
4830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
491b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
505fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h"
511b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5284a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5330fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
545a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5530fdc8d8SChris Lattner 
5630fdc8d8SChris Lattner using namespace lldb;
5730fdc8d8SChris Lattner using namespace lldb_private;
5830fdc8d8SChris Lattner 
5930fdc8d8SChris Lattner 
601b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
61ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
62ebc1bb27SCaroline Tice 
631b654882SGreg Clayton #pragma mark Static Functions
641b654882SGreg Clayton 
651b654882SGreg Clayton static Mutex &
661b654882SGreg Clayton GetDebuggerListMutex ()
671b654882SGreg Clayton {
681b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
691b654882SGreg Clayton     return g_mutex;
701b654882SGreg Clayton }
711b654882SGreg Clayton 
721b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
731b654882SGreg Clayton 
741b654882SGreg Clayton static DebuggerList &
751b654882SGreg Clayton GetDebuggerList()
761b654882SGreg Clayton {
771b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
786a7f3338SBruce Mitchener     // global init constructors
791b654882SGreg Clayton     static DebuggerList g_list;
801b654882SGreg Clayton     return g_list;
811b654882SGreg Clayton }
82e372b98dSGreg Clayton 
83e372b98dSGreg Clayton OptionEnumValueElement
8467cc0636SGreg Clayton g_show_disassembly_enum_values[] =
85e372b98dSGreg Clayton {
8667cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
8767cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
8867cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
89e372b98dSGreg Clayton     { 0, NULL, NULL }
90e372b98dSGreg Clayton };
91e372b98dSGreg Clayton 
9267cc0636SGreg Clayton OptionEnumValueElement
9367cc0636SGreg Clayton g_language_enumerators[] =
9467cc0636SGreg Clayton {
9567cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
9667cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
9767cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
98a12993c9SGreg Clayton     { 0, NULL, NULL }
9967cc0636SGreg Clayton };
100e372b98dSGreg Clayton 
10167cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10267cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10367cc0636SGreg Clayton 
1040769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
10567cc0636SGreg Clayton     "{, ${frame.pc}}"\
10667cc0636SGreg Clayton     MODULE_WITH_FUNC\
10767cc0636SGreg Clayton     FILE_AND_LINE\
1080769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
1090769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
110705b1809SJason Molenda     "{, activity = '${thread.info.activity.name}'}" \
111705b1809SJason Molenda     "{, ${thread.info.trace_messages} messages}" \
11267cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
11367cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
11430fadafeSJim Ingham     "{\\nCompleted expression: ${thread.completed-expression}}"\
11567cc0636SGreg Clayton     "\\n"
11667cc0636SGreg Clayton 
11767cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
11867cc0636SGreg Clayton     MODULE_WITH_FUNC\
11967cc0636SGreg Clayton     FILE_AND_LINE\
12067cc0636SGreg Clayton     "\\n"
12167cc0636SGreg Clayton 
12267cc0636SGreg Clayton 
12367cc0636SGreg Clayton 
124754a9369SGreg Clayton static PropertyDefinition
125754a9369SGreg Clayton g_properties[] =
12667cc0636SGreg Clayton {
12767cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
12867cc0636SGreg 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." },
12967cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1304c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
13167cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
13267cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
13367cc0636SGreg 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." },
13467cc0636SGreg 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." },
13567cc0636SGreg 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." },
13667cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
13767cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
13867cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
139c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
14090a8db30SEnrico 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)." },
141e8cd0c98SGreg Clayton 
14267cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
14367cc0636SGreg Clayton };
14467cc0636SGreg Clayton 
14567cc0636SGreg Clayton enum
14667cc0636SGreg Clayton {
14767cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
14867cc0636SGreg Clayton     ePropertyFrameFormat,
14967cc0636SGreg Clayton     ePropertyNotiftVoid,
15067cc0636SGreg Clayton     ePropertyPrompt,
15167cc0636SGreg Clayton     ePropertyScriptLanguage,
15267cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
15367cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
15467cc0636SGreg Clayton     ePropertyStopLineCountAfter,
15567cc0636SGreg Clayton     ePropertyStopLineCountBefore,
15667cc0636SGreg Clayton     ePropertyTerminalWidth,
15767cc0636SGreg Clayton     ePropertyThreadFormat,
158c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
159c3ce7f27SMichael Sartain     ePropertyUseColor,
16090a8db30SEnrico Granata     ePropertyAutoOneLineSummaries
16167cc0636SGreg Clayton };
16267cc0636SGreg Clayton 
1635fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1644c05410fSGreg Clayton 
1654c05410fSGreg Clayton Error
1664c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1674c05410fSGreg Clayton                             VarSetOperationType op,
1684c05410fSGreg Clayton                             const char *property_path,
1694c05410fSGreg Clayton                             const char *value)
1704c05410fSGreg Clayton {
17184a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
17284a53dfbSEnrico Granata     TargetSP target_sp;
173397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
17484a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
17584a53dfbSEnrico Granata     {
17684a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
17784a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
17884a53dfbSEnrico Granata     }
1794c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1804c05410fSGreg Clayton     if (error.Success())
1814c05410fSGreg Clayton     {
18284a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
1834c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1844c05410fSGreg Clayton         {
1854c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
186c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
187c3ce7f27SMichael Sartain             if (str.length())
188c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
18944d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
1904c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1914c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
1924c05410fSGreg Clayton         }
193c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
194c3ce7f27SMichael Sartain         {
195c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
196c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
197c3ce7f27SMichael Sartain         }
198397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
19984a53dfbSEnrico Granata         {
200397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
20184a53dfbSEnrico Granata             {
20284a53dfbSEnrico Granata                 std::list<Error> errors;
2039730339bSEnrico Granata                 StreamString feedback_stream;
2049730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
20584a53dfbSEnrico Granata                 {
20644d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
20744d93782SGreg Clayton                     if (stream_sp)
20844d93782SGreg Clayton                     {
20984a53dfbSEnrico Granata                         for (auto error : errors)
21084a53dfbSEnrico Granata                         {
21144d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
21284a53dfbSEnrico Granata                         }
2139730339bSEnrico Granata                         if (feedback_stream.GetSize())
21444d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
21544d93782SGreg Clayton                     }
21684a53dfbSEnrico Granata                 }
21784a53dfbSEnrico Granata             }
21884a53dfbSEnrico Granata         }
2194c05410fSGreg Clayton     }
2204c05410fSGreg Clayton     return error;
2214c05410fSGreg Clayton }
2224c05410fSGreg Clayton 
22367cc0636SGreg Clayton bool
22467cc0636SGreg Clayton Debugger::GetAutoConfirm () const
22567cc0636SGreg Clayton {
22667cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
227754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
22867cc0636SGreg Clayton }
22967cc0636SGreg Clayton 
23067cc0636SGreg Clayton const char *
23167cc0636SGreg Clayton Debugger::GetFrameFormat() const
23267cc0636SGreg Clayton {
23367cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
234754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
23567cc0636SGreg Clayton }
23667cc0636SGreg Clayton 
23767cc0636SGreg Clayton bool
23867cc0636SGreg Clayton Debugger::GetNotifyVoid () const
23967cc0636SGreg Clayton {
24067cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
241754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
24267cc0636SGreg Clayton }
24367cc0636SGreg Clayton 
24467cc0636SGreg Clayton const char *
24567cc0636SGreg Clayton Debugger::GetPrompt() const
24667cc0636SGreg Clayton {
24767cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
248754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
24967cc0636SGreg Clayton }
25067cc0636SGreg Clayton 
25167cc0636SGreg Clayton void
25267cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
25367cc0636SGreg Clayton {
25467cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
25567cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
25667cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
257c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
258c3ce7f27SMichael Sartain     if (str.length())
259c3ce7f27SMichael Sartain         new_prompt = str.c_str();
26044d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
26167cc0636SGreg Clayton }
26267cc0636SGreg Clayton 
26367cc0636SGreg Clayton const char *
26467cc0636SGreg Clayton Debugger::GetThreadFormat() const
26567cc0636SGreg Clayton {
26667cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
267754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
26867cc0636SGreg Clayton }
26967cc0636SGreg Clayton 
27067cc0636SGreg Clayton lldb::ScriptLanguage
27167cc0636SGreg Clayton Debugger::GetScriptLanguage() const
27267cc0636SGreg Clayton {
27367cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
274754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
27567cc0636SGreg Clayton }
27667cc0636SGreg Clayton 
27767cc0636SGreg Clayton bool
27867cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
27967cc0636SGreg Clayton {
28067cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
28167cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
28267cc0636SGreg Clayton }
28367cc0636SGreg Clayton 
28467cc0636SGreg Clayton uint32_t
28567cc0636SGreg Clayton Debugger::GetTerminalWidth () const
28667cc0636SGreg Clayton {
28767cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
288754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
28967cc0636SGreg Clayton }
29067cc0636SGreg Clayton 
29167cc0636SGreg Clayton bool
29267cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
29367cc0636SGreg Clayton {
29467cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
29567cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
29667cc0636SGreg Clayton }
29767cc0636SGreg Clayton 
29867cc0636SGreg Clayton bool
29967cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
30067cc0636SGreg Clayton {
30167cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
302754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
30367cc0636SGreg Clayton }
30467cc0636SGreg Clayton 
30567cc0636SGreg Clayton bool
30667cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
30767cc0636SGreg Clayton {
30867cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
30967cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
31067cc0636SGreg Clayton }
31167cc0636SGreg Clayton 
312c3ce7f27SMichael Sartain bool
313c3ce7f27SMichael Sartain Debugger::GetUseColor () const
314c3ce7f27SMichael Sartain {
315c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
316c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
317c3ce7f27SMichael Sartain }
318c3ce7f27SMichael Sartain 
319c3ce7f27SMichael Sartain bool
320c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
321c3ce7f27SMichael Sartain {
322c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
323c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
324c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
325c3ce7f27SMichael Sartain     return ret;
326c3ce7f27SMichael Sartain }
327c3ce7f27SMichael Sartain 
32867cc0636SGreg Clayton uint32_t
32967cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
33067cc0636SGreg Clayton {
33167cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
332754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
33367cc0636SGreg Clayton }
33467cc0636SGreg Clayton 
33567cc0636SGreg Clayton Debugger::StopDisassemblyType
33667cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
33767cc0636SGreg Clayton {
33867cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
339754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
34067cc0636SGreg Clayton }
34167cc0636SGreg Clayton 
34267cc0636SGreg Clayton uint32_t
34367cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
34467cc0636SGreg Clayton {
34567cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
346754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
34767cc0636SGreg Clayton }
348e372b98dSGreg Clayton 
349553fad5cSEnrico Granata bool
35090a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
351553fad5cSEnrico Granata {
35290a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
353553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
354553fad5cSEnrico Granata 
355553fad5cSEnrico Granata }
356553fad5cSEnrico Granata 
3571b654882SGreg Clayton #pragma mark Debugger
3581b654882SGreg Clayton 
35967cc0636SGreg Clayton //const DebuggerPropertiesSP &
36067cc0636SGreg Clayton //Debugger::GetSettings() const
36167cc0636SGreg Clayton //{
36267cc0636SGreg Clayton //    return m_properties_sp;
36367cc0636SGreg Clayton //}
36467cc0636SGreg Clayton //
36599d0faf2SGreg Clayton 
3662f88aadfSCaroline Tice int
3672f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3682f88aadfSCaroline Tice {
3692f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3702f88aadfSCaroline Tice }
3712f88aadfSCaroline Tice 
37230fdc8d8SChris Lattner void
3735fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
37430fdc8d8SChris Lattner {
3755fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
376c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
377dbe54508SGreg Clayton         lldb_private::Initialize();
37899d0faf2SGreg Clayton }
37930fdc8d8SChris Lattner 
38030fdc8d8SChris Lattner void
38130fdc8d8SChris Lattner Debugger::Terminate ()
38230fdc8d8SChris Lattner {
3836611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3846611103cSGreg Clayton     {
38530fdc8d8SChris Lattner         g_shared_debugger_refcount--;
38630fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
38730fdc8d8SChris Lattner         {
388dbe54508SGreg Clayton             lldb_private::WillTerminate();
389dbe54508SGreg Clayton             lldb_private::Terminate();
3906760a517SCaroline Tice 
39199d0faf2SGreg Clayton             // Clear our master list of debugger objects
39299d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
39399d0faf2SGreg Clayton             GetDebuggerList().clear();
39430fdc8d8SChris Lattner         }
3956760a517SCaroline Tice     }
3966760a517SCaroline Tice }
39730fdc8d8SChris Lattner 
39820bd37f7SCaroline Tice void
39920bd37f7SCaroline Tice Debugger::SettingsInitialize ()
40020bd37f7SCaroline Tice {
4016920b52bSGreg Clayton     Target::SettingsInitialize ();
40220bd37f7SCaroline Tice }
40320bd37f7SCaroline Tice 
40420bd37f7SCaroline Tice void
40520bd37f7SCaroline Tice Debugger::SettingsTerminate ()
40620bd37f7SCaroline Tice {
4076920b52bSGreg Clayton     Target::SettingsTerminate ();
40820bd37f7SCaroline Tice }
40920bd37f7SCaroline Tice 
41021dfcd9dSEnrico Granata bool
411e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
41221dfcd9dSEnrico Granata {
4135fb8f797SGreg Clayton     if (g_load_plugin_callback)
414e743c782SEnrico Granata     {
4155fb8f797SGreg Clayton         lldb::DynamicLibrarySP dynlib_sp = g_load_plugin_callback (shared_from_this(), spec, error);
4165fb8f797SGreg Clayton         if (dynlib_sp)
41721dfcd9dSEnrico Granata         {
41821dfcd9dSEnrico Granata             m_loaded_plugins.push_back(dynlib_sp);
41921dfcd9dSEnrico Granata             return true;
42021dfcd9dSEnrico Granata         }
4215fb8f797SGreg Clayton     }
4225fb8f797SGreg Clayton     else
4235fb8f797SGreg Clayton     {
4245fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4255fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4265fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4275fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4285fb8f797SGreg Clayton     }
42921dfcd9dSEnrico Granata     return false;
43021dfcd9dSEnrico Granata }
43121dfcd9dSEnrico Granata 
43221dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
43321dfcd9dSEnrico Granata LoadPluginCallback
43421dfcd9dSEnrico Granata (
43521dfcd9dSEnrico Granata  void *baton,
43621dfcd9dSEnrico Granata  FileSpec::FileType file_type,
43721dfcd9dSEnrico Granata  const FileSpec &file_spec
43821dfcd9dSEnrico Granata  )
43921dfcd9dSEnrico Granata {
44021dfcd9dSEnrico Granata     Error error;
44121dfcd9dSEnrico Granata 
44221dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4433cf443ddSMichael Sartain     static ConstString g_solibext("so");
44421dfcd9dSEnrico Granata 
44521dfcd9dSEnrico Granata     if (!baton)
44621dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
44721dfcd9dSEnrico Granata 
44821dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
44921dfcd9dSEnrico Granata 
45021dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
45121dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
45221dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
45321dfcd9dSEnrico Granata     // file type information.
45421dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
45521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
45621dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
45721dfcd9dSEnrico Granata     {
45821dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
45921dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
46021dfcd9dSEnrico Granata 
4613cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4623cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4633cf443ddSMichael Sartain         {
46421dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4653cf443ddSMichael Sartain         }
46621dfcd9dSEnrico Granata 
467e743c782SEnrico Granata         Error plugin_load_error;
468e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
46921dfcd9dSEnrico Granata 
47021dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
47121dfcd9dSEnrico Granata     }
47221dfcd9dSEnrico Granata 
47321dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
47421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
47521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
47621dfcd9dSEnrico Granata     {
47721dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
47821dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
4796a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
48021dfcd9dSEnrico Granata         // information.
48121dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
48221dfcd9dSEnrico Granata     }
48321dfcd9dSEnrico Granata 
48421dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
48521dfcd9dSEnrico Granata }
48621dfcd9dSEnrico Granata 
48721dfcd9dSEnrico Granata void
48821dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
48921dfcd9dSEnrico Granata {
49021dfcd9dSEnrico Granata     FileSpec dir_spec;
49121dfcd9dSEnrico Granata     const bool find_directories = true;
49221dfcd9dSEnrico Granata     const bool find_files = true;
49321dfcd9dSEnrico Granata     const bool find_other = true;
49421dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
49521dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
49621dfcd9dSEnrico Granata     {
49721dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
49821dfcd9dSEnrico Granata         {
49921dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
50021dfcd9dSEnrico Granata                                           find_directories,
50121dfcd9dSEnrico Granata                                           find_files,
50221dfcd9dSEnrico Granata                                           find_other,
50321dfcd9dSEnrico Granata                                           LoadPluginCallback,
50421dfcd9dSEnrico Granata                                           this);
50521dfcd9dSEnrico Granata         }
50621dfcd9dSEnrico Granata     }
50721dfcd9dSEnrico Granata 
50821dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
50921dfcd9dSEnrico Granata     {
51021dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
51121dfcd9dSEnrico Granata         {
51221dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
51321dfcd9dSEnrico Granata                                           find_directories,
51421dfcd9dSEnrico Granata                                           find_files,
51521dfcd9dSEnrico Granata                                           find_other,
51621dfcd9dSEnrico Granata                                           LoadPluginCallback,
51721dfcd9dSEnrico Granata                                           this);
51821dfcd9dSEnrico Granata         }
51921dfcd9dSEnrico Granata     }
520e8cd0c98SGreg Clayton 
521e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
52221dfcd9dSEnrico Granata }
52321dfcd9dSEnrico Granata 
5246611103cSGreg Clayton DebuggerSP
525228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5266611103cSGreg Clayton {
527228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
528c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5296611103cSGreg Clayton     {
5306611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5316611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5326611103cSGreg Clayton     }
53321dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5346611103cSGreg Clayton     return debugger_sp;
5356611103cSGreg Clayton }
5366611103cSGreg Clayton 
537e02657b1SCaroline Tice void
5384d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
539e02657b1SCaroline Tice {
540e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
541e02657b1SCaroline Tice         return;
542e02657b1SCaroline Tice 
5438314c525SJim Ingham     debugger_sp->Clear();
5448314c525SJim Ingham 
545c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
546c15f55e2SGreg Clayton     {
547e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
548e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
549e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
550e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
551e02657b1SCaroline Tice         {
552e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
553e02657b1SCaroline Tice             {
554e02657b1SCaroline Tice                 debugger_list.erase (pos);
555e02657b1SCaroline Tice                 return;
556e02657b1SCaroline Tice             }
557e02657b1SCaroline Tice         }
558e02657b1SCaroline Tice     }
559c15f55e2SGreg Clayton }
560e02657b1SCaroline Tice 
5614d122c40SGreg Clayton DebuggerSP
5623df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5633df9a8dfSCaroline Tice {
5644d122c40SGreg Clayton     DebuggerSP debugger_sp;
5656920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5666920b52bSGreg Clayton     {
5676920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5686920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5696920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5706920b52bSGreg Clayton 
5716920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5726920b52bSGreg Clayton         {
5736920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5746920b52bSGreg Clayton             {
5756920b52bSGreg Clayton                 debugger_sp = *pos;
5766920b52bSGreg Clayton                 break;
5776920b52bSGreg Clayton             }
5786920b52bSGreg Clayton         }
5796920b52bSGreg Clayton     }
5803df9a8dfSCaroline Tice     return debugger_sp;
5813df9a8dfSCaroline Tice }
5826611103cSGreg Clayton 
5836611103cSGreg Clayton TargetSP
5846611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
5856611103cSGreg Clayton {
5864d122c40SGreg Clayton     TargetSP target_sp;
587c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
588c15f55e2SGreg Clayton     {
5896611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5906611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5916611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5926611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5936611103cSGreg Clayton         {
5946611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
5956611103cSGreg Clayton             if (target_sp)
5966611103cSGreg Clayton                 break;
5976611103cSGreg Clayton         }
598c15f55e2SGreg Clayton     }
5996611103cSGreg Clayton     return target_sp;
6006611103cSGreg Clayton }
6016611103cSGreg Clayton 
602e4e45924SGreg Clayton TargetSP
603e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
604e4e45924SGreg Clayton {
605e4e45924SGreg Clayton     TargetSP target_sp;
606c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
607c15f55e2SGreg Clayton     {
608e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
609e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
610e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
611e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
612e4e45924SGreg Clayton         {
613e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
614e4e45924SGreg Clayton             if (target_sp)
615e4e45924SGreg Clayton                 break;
616e4e45924SGreg Clayton         }
617c15f55e2SGreg Clayton     }
618e4e45924SGreg Clayton     return target_sp;
619e4e45924SGreg Clayton }
620e4e45924SGreg Clayton 
621228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
622ebc1bb27SCaroline Tice     UserID (g_unique_id++),
62367cc0636SGreg Clayton     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
62444d93782SGreg Clayton     m_input_file_sp (new StreamFile (stdin, false)),
62544d93782SGreg Clayton     m_output_file_sp (new StreamFile (stdout, false)),
62644d93782SGreg Clayton     m_error_file_sp (new StreamFile (stderr, false)),
627c5917d9aSJim Ingham     m_terminal_state (),
6284bddaeb5SJim Ingham     m_target_list (*this),
629ded470d3SGreg Clayton     m_platform_list (),
63030fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
6319585fbfcSGreg Clayton     m_source_manager_ap(),
632e37d605eSJim Ingham     m_source_file_cache(),
6336611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
634d5a0a01bSCaroline Tice     m_input_reader_stack (),
63544d93782SGreg Clayton     m_instance_name (),
63644d93782SGreg Clayton     m_loaded_plugins (),
63744d93782SGreg Clayton     m_event_handler_thread (LLDB_INVALID_HOST_THREAD),
638b4874f1aSGreg Clayton     m_io_handler_thread (LLDB_INVALID_HOST_THREAD)
63930fdc8d8SChris Lattner {
64067cc0636SGreg Clayton     char instance_cstr[256];
64167cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
64267cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
643228063cdSJim Ingham     if (log_callback)
644228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6456611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
646ded470d3SGreg Clayton     // Always add our default platform to the platform list
647ded470d3SGreg Clayton     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
648ded470d3SGreg Clayton     assert (default_platform_sp.get());
649ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
65067cc0636SGreg Clayton 
651754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
65267cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
65367cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
65467cc0636SGreg Clayton                                      true,
65567cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
656754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
657754a9369SGreg Clayton     {
658754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
659754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
660754a9369SGreg Clayton                                          true,
661754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
662754a9369SGreg Clayton     }
66367cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
66467cc0636SGreg Clayton     term_width->SetMinimumValue(10);
66567cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
666c3ce7f27SMichael Sartain 
667c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
668c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
669c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
670c3ce7f27SMichael Sartain         SetUseColor (false);
67130fdc8d8SChris Lattner }
67230fdc8d8SChris Lattner 
67330fdc8d8SChris Lattner Debugger::~Debugger ()
67430fdc8d8SChris Lattner {
6758314c525SJim Ingham     Clear();
6768314c525SJim Ingham }
6778314c525SJim Ingham 
6788314c525SJim Ingham void
6798314c525SJim Ingham Debugger::Clear()
6808314c525SJim Ingham {
68144d93782SGreg Clayton     ClearIOHandlers();
68244d93782SGreg Clayton     StopIOHandlerThread();
68344d93782SGreg Clayton     StopEventHandlerThread();
6841ed54f50SGreg Clayton     m_listener.Clear();
6856611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6866611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
6876611103cSGreg Clayton     {
688ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
689ccbc08e6SGreg Clayton         if (target_sp)
690ccbc08e6SGreg Clayton         {
691ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
6926611103cSGreg Clayton             if (process_sp)
6931fd07059SJim Ingham                 process_sp->Finalize();
694ccbc08e6SGreg Clayton             target_sp->Destroy();
6956611103cSGreg Clayton         }
69630fdc8d8SChris Lattner     }
6974bddaeb5SJim Ingham     BroadcasterManager::Clear ();
69830fdc8d8SChris Lattner 
6990d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7000d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
701c5917d9aSJim Ingham     m_terminal_state.Clear();
70244d93782SGreg Clayton     if (m_input_file_sp)
70344d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7040c4129f2SGreg Clayton 
7050c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7068314c525SJim Ingham }
70730fdc8d8SChris Lattner 
70830fdc8d8SChris Lattner bool
709fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
710fc3f027dSGreg Clayton {
71144d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
71244d93782SGreg Clayton     return false;
713fc3f027dSGreg Clayton }
714fc3f027dSGreg Clayton 
715fc3f027dSGreg Clayton void
716fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
717fc3f027dSGreg Clayton {
71844d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
719fc3f027dSGreg Clayton }
720fc3f027dSGreg Clayton 
721fc3f027dSGreg Clayton bool
72230fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
72330fdc8d8SChris Lattner {
7246611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
72530fdc8d8SChris Lattner }
72630fdc8d8SChris Lattner 
72730fdc8d8SChris Lattner void
72830fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
72930fdc8d8SChris Lattner {
7306611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
73130fdc8d8SChris Lattner }
73230fdc8d8SChris Lattner 
73330fdc8d8SChris Lattner 
73430fdc8d8SChris Lattner void
73530fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
73630fdc8d8SChris Lattner {
73744d93782SGreg Clayton     if (m_input_file_sp)
73844d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
73944d93782SGreg Clayton     else
74044d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
74144d93782SGreg Clayton 
74244d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
74351b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
74451b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
74530fdc8d8SChris Lattner 
746c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
747c5917d9aSJim Ingham     SaveInputTerminalState ();
74830fdc8d8SChris Lattner }
74930fdc8d8SChris Lattner 
75030fdc8d8SChris Lattner void
75130fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
75230fdc8d8SChris Lattner {
75344d93782SGreg Clayton     if (m_output_file_sp)
75444d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
75544d93782SGreg Clayton     else
75644d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
75744d93782SGreg Clayton 
75844d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
75951b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
76051b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7612f88aadfSCaroline Tice 
762b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
763b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
764b588726eSEnrico Granata     const bool can_create = false;
765b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
766b588726eSEnrico Granata     if (script_interpreter)
767b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
76830fdc8d8SChris Lattner }
76930fdc8d8SChris Lattner 
77030fdc8d8SChris Lattner void
77130fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
77230fdc8d8SChris Lattner {
77344d93782SGreg Clayton     if (m_error_file_sp)
77444d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
77544d93782SGreg Clayton     else
77644d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
77744d93782SGreg Clayton 
77844d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
77951b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
78051b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
78130fdc8d8SChris Lattner }
78230fdc8d8SChris Lattner 
783c5917d9aSJim Ingham void
784c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
785c5917d9aSJim Ingham {
78644d93782SGreg Clayton     if (m_input_file_sp)
78744d93782SGreg Clayton     {
78844d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
789c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
790c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
791c5917d9aSJim Ingham     }
79244d93782SGreg Clayton }
793c5917d9aSJim Ingham 
794c5917d9aSJim Ingham void
795c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
796c5917d9aSJim Ingham {
797c5917d9aSJim Ingham     m_terminal_state.Restore();
798c5917d9aSJim Ingham }
799c5917d9aSJim Ingham 
80030fdc8d8SChris Lattner ExecutionContext
8012976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
80230fdc8d8SChris Lattner {
80330fdc8d8SChris Lattner     ExecutionContext exe_ctx;
804c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
805c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
80630fdc8d8SChris Lattner 
80730fdc8d8SChris Lattner     if (target_sp)
80830fdc8d8SChris Lattner     {
809c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
810c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
811c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
81230fdc8d8SChris Lattner         {
813c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
814c14ee32dSGreg Clayton             if (thread_sp)
81530fdc8d8SChris Lattner             {
816c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
817c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
818c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
819c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
82030fdc8d8SChris Lattner             }
82130fdc8d8SChris Lattner         }
82230fdc8d8SChris Lattner     }
82330fdc8d8SChris Lattner     return exe_ctx;
82430fdc8d8SChris Lattner }
82530fdc8d8SChris Lattner 
82630fdc8d8SChris Lattner void
827efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
828efed6131SCaroline Tice {
82944d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
83044d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
831efed6131SCaroline Tice     if (reader_sp)
83244d93782SGreg Clayton         reader_sp->Interrupt();
833efed6131SCaroline Tice }
834efed6131SCaroline Tice 
835efed6131SCaroline Tice void
836efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
837efed6131SCaroline Tice {
83844d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
83944d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
840efed6131SCaroline Tice     if (reader_sp)
84144d93782SGreg Clayton         reader_sp->GotEOF();
842efed6131SCaroline Tice }
843efed6131SCaroline Tice 
844efed6131SCaroline Tice void
84544d93782SGreg Clayton Debugger::ClearIOHandlers ()
8463d6086f6SCaroline Tice {
847b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
84844d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
849d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8503d6086f6SCaroline Tice     {
85144d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8523d6086f6SCaroline Tice         if (reader_sp)
8533d6086f6SCaroline Tice         {
85444d93782SGreg Clayton             m_input_reader_stack.Pop();
8553d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
856e68f5d6bSGreg Clayton             reader_sp->Cancel();
8573d6086f6SCaroline Tice         }
8583d6086f6SCaroline Tice     }
8593d6086f6SCaroline Tice }
8603d6086f6SCaroline Tice 
8613d6086f6SCaroline Tice void
86244d93782SGreg Clayton Debugger::ExecuteIOHanders()
863969ed3d1SCaroline Tice {
86444d93782SGreg Clayton 
86544d93782SGreg Clayton     while (1)
866969ed3d1SCaroline Tice     {
86744d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
86830fdc8d8SChris Lattner         if (!reader_sp)
86930fdc8d8SChris Lattner             break;
87030fdc8d8SChris Lattner 
87144d93782SGreg Clayton         reader_sp->Activate();
87244d93782SGreg Clayton         reader_sp->Run();
87344d93782SGreg Clayton         reader_sp->Deactivate();
87444d93782SGreg Clayton 
87544d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
87644d93782SGreg Clayton         while (1)
87730fdc8d8SChris Lattner         {
87844d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
87944d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
88044d93782SGreg Clayton                 m_input_reader_stack.Pop();
88130fdc8d8SChris Lattner             else
88230fdc8d8SChris Lattner                 break;
88330fdc8d8SChris Lattner         }
88430fdc8d8SChris Lattner     }
88544d93782SGreg Clayton     ClearIOHandlers();
88644d93782SGreg Clayton }
88730fdc8d8SChris Lattner 
88844d93782SGreg Clayton bool
88944d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
89044d93782SGreg Clayton {
89144d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
89244d93782SGreg Clayton }
89330fdc8d8SChris Lattner 
89444d93782SGreg Clayton 
89544d93782SGreg Clayton ConstString
89644d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
89744d93782SGreg Clayton {
89844d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
89930fdc8d8SChris Lattner }
90030fdc8d8SChris Lattner 
90130fdc8d8SChris Lattner void
90244d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
90344d93782SGreg Clayton {
90444d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
90544d93782SGreg Clayton     PushIOHandler (reader_sp);
906577508dfSGreg Clayton 
907577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
908577508dfSGreg Clayton     while (top_reader_sp)
909577508dfSGreg Clayton     {
910577508dfSGreg Clayton         top_reader_sp->Activate();
911577508dfSGreg Clayton         top_reader_sp->Run();
912577508dfSGreg Clayton         top_reader_sp->Deactivate();
913577508dfSGreg Clayton 
914577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
915577508dfSGreg Clayton         {
916577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
917577508dfSGreg Clayton                 break;
918577508dfSGreg Clayton         }
919577508dfSGreg Clayton 
920577508dfSGreg Clayton         while (1)
921577508dfSGreg Clayton         {
922577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
923577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
924577508dfSGreg Clayton                 m_input_reader_stack.Pop();
925577508dfSGreg Clayton             else
926577508dfSGreg Clayton                 break;
927577508dfSGreg Clayton         }
928577508dfSGreg Clayton     }
92944d93782SGreg Clayton }
93044d93782SGreg Clayton 
93144d93782SGreg Clayton void
93244d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
93344d93782SGreg Clayton {
93444d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
93544d93782SGreg Clayton     // This function is called when one ore more of the streams
93644d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
93744d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
93844d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
93944d93782SGreg Clayton 
94044d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
94144d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
94244d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
94344d93782SGreg Clayton     if (!in)
94444d93782SGreg Clayton     {
94544d93782SGreg Clayton         if (top_reader_sp)
94644d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
94744d93782SGreg Clayton         else
94844d93782SGreg Clayton             in = GetInputFile();
94944d93782SGreg Clayton 
95044d93782SGreg Clayton         // If there is nothing, use stdin
95144d93782SGreg Clayton         if (!in)
95244d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
95344d93782SGreg Clayton     }
95444d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
95544d93782SGreg Clayton     if (!out)
95644d93782SGreg Clayton     {
95744d93782SGreg Clayton         if (top_reader_sp)
95844d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
95944d93782SGreg Clayton         else
96044d93782SGreg Clayton             out = GetOutputFile();
96144d93782SGreg Clayton 
96244d93782SGreg Clayton         // If there is nothing, use stdout
96344d93782SGreg Clayton         if (!out)
96444d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
96544d93782SGreg Clayton     }
96644d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
96744d93782SGreg Clayton     if (!err)
96844d93782SGreg Clayton     {
96944d93782SGreg Clayton         if (top_reader_sp)
97044d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
97144d93782SGreg Clayton         else
97244d93782SGreg Clayton             err = GetErrorFile();
97344d93782SGreg Clayton 
97444d93782SGreg Clayton         // If there is nothing, use stderr
97544d93782SGreg Clayton         if (!err)
97644d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
97744d93782SGreg Clayton 
97844d93782SGreg Clayton     }
97944d93782SGreg Clayton }
98044d93782SGreg Clayton 
98144d93782SGreg Clayton void
98244d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
98330fdc8d8SChris Lattner {
98430fdc8d8SChris Lattner     if (!reader_sp)
98530fdc8d8SChris Lattner         return;
986b44880caSCaroline Tice 
98744d93782SGreg Clayton     // Got the current top input reader...
98844d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
989b44880caSCaroline Tice 
990b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
991b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
992b4874f1aSGreg Clayton     {
99344d93782SGreg Clayton         // Push our new input reader
994d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
99544d93782SGreg Clayton 
99644d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
99744d93782SGreg Clayton         // and let this new input reader take over
99844d93782SGreg Clayton         if (top_reader_sp)
99944d93782SGreg Clayton             top_reader_sp->Deactivate();
100030fdc8d8SChris Lattner     }
1001b4874f1aSGreg Clayton }
100230fdc8d8SChris Lattner 
100330fdc8d8SChris Lattner bool
100444d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
100530fdc8d8SChris Lattner {
100630fdc8d8SChris Lattner     bool result = false;
100730fdc8d8SChris Lattner 
100844d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
100944d93782SGreg Clayton 
101030fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10116a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
1012d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
101330fdc8d8SChris Lattner     {
101444d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
101530fdc8d8SChris Lattner 
101630fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
101730fdc8d8SChris Lattner         {
101844d93782SGreg Clayton             reader_sp->Deactivate();
1019b4874f1aSGreg Clayton             reader_sp->Cancel();
1020d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
102130fdc8d8SChris Lattner 
1022d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
102330fdc8d8SChris Lattner             if (reader_sp)
102444d93782SGreg Clayton                 reader_sp->Activate();
102544d93782SGreg Clayton 
102644d93782SGreg Clayton             result = true;
102730fdc8d8SChris Lattner         }
102830fdc8d8SChris Lattner     }
102930fdc8d8SChris Lattner     return result;
103030fdc8d8SChris Lattner }
103130fdc8d8SChris Lattner 
103230fdc8d8SChris Lattner bool
103344d93782SGreg Clayton Debugger::HideTopIOHandler()
103430fdc8d8SChris Lattner {
103544d93782SGreg Clayton     Mutex::Locker locker;
103630fdc8d8SChris Lattner 
103744d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
103830fdc8d8SChris Lattner     {
103944d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
104044d93782SGreg Clayton         if (reader_sp)
104144d93782SGreg Clayton             reader_sp->Hide();
104244d93782SGreg Clayton         return true;
104330fdc8d8SChris Lattner     }
104444d93782SGreg Clayton     return false;
104530fdc8d8SChris Lattner }
104630fdc8d8SChris Lattner 
104730fdc8d8SChris Lattner void
104844d93782SGreg Clayton Debugger::RefreshTopIOHandler()
104930fdc8d8SChris Lattner {
105044d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
105144d93782SGreg Clayton     if (reader_sp)
105244d93782SGreg Clayton         reader_sp->Refresh();
105330fdc8d8SChris Lattner }
105444d93782SGreg Clayton 
10556611103cSGreg Clayton 
10565b52f0c7SJim Ingham StreamSP
10575b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10585b52f0c7SJim Ingham {
10595b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10605b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10615b52f0c7SJim Ingham }
10625b52f0c7SJim Ingham 
10635b52f0c7SJim Ingham StreamSP
10645b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10655b52f0c7SJim Ingham {
10665b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10675b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10685b52f0c7SJim Ingham }
10695b52f0c7SJim Ingham 
1070c7bece56SGreg Clayton size_t
1071061858ceSEnrico Granata Debugger::GetNumDebuggers()
1072061858ceSEnrico Granata {
1073c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1074c15f55e2SGreg Clayton     {
1075061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1076061858ceSEnrico Granata         return GetDebuggerList().size();
1077061858ceSEnrico Granata     }
1078c15f55e2SGreg Clayton     return 0;
1079c15f55e2SGreg Clayton }
1080061858ceSEnrico Granata 
1081061858ceSEnrico Granata lldb::DebuggerSP
1082c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1083061858ceSEnrico Granata {
1084061858ceSEnrico Granata     DebuggerSP debugger_sp;
1085061858ceSEnrico Granata 
1086c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1087c15f55e2SGreg Clayton     {
1088061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1089061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1090061858ceSEnrico Granata 
1091061858ceSEnrico Granata         if (index < debugger_list.size())
1092061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1093c15f55e2SGreg Clayton     }
1094061858ceSEnrico Granata 
1095061858ceSEnrico Granata     return debugger_sp;
1096061858ceSEnrico Granata }
1097061858ceSEnrico Granata 
1098ebc1bb27SCaroline Tice DebuggerSP
1099ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1100ebc1bb27SCaroline Tice {
11014d122c40SGreg Clayton     DebuggerSP debugger_sp;
1102ebc1bb27SCaroline Tice 
1103c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1104c15f55e2SGreg Clayton     {
1105ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1106ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1107ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1108ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1109ebc1bb27SCaroline Tice         {
1110ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1111ebc1bb27SCaroline Tice             {
1112ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1113ebc1bb27SCaroline Tice                 break;
1114ebc1bb27SCaroline Tice             }
1115ebc1bb27SCaroline Tice         }
1116c15f55e2SGreg Clayton     }
1117ebc1bb27SCaroline Tice     return debugger_sp;
1118ebc1bb27SCaroline Tice }
11193df9a8dfSCaroline Tice 
11202643b905SSaleem Abdulrasool #if 0
11211b654882SGreg Clayton static void
1122b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11231b654882SGreg Clayton {
11241b654882SGreg Clayton     if (frame == NULL)
11251b654882SGreg Clayton         return;
11261b654882SGreg Clayton 
11271b654882SGreg Clayton     StreamString s;
11281b654882SGreg Clayton     const char *prompt_format =
11291b654882SGreg Clayton     "{addr = '${addr}'\n}"
11301b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11311b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11321b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11331b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11341b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11351b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11361b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11371b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11381b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11391b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11401b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11411b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11421b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11431b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11441b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11451b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11461b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11471b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11481b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11491b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11501b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11511b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11521b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11531b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11541b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11551b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11561b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
11571b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1158ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11591b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
11601b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11611b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11621b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11631b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11641b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11651b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11661b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11671b654882SGreg Clayton ;
11681b654882SGreg Clayton 
11691b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11701b654882SGreg Clayton     ExecutionContext exe_ctx;
11710603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1172c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
11731b654882SGreg Clayton     {
11741b654882SGreg Clayton         printf("%s\n", s.GetData());
11751b654882SGreg Clayton     }
11761b654882SGreg Clayton     else
11771b654882SGreg Clayton     {
11781b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11791b654882SGreg Clayton     }
11801b654882SGreg Clayton }
11812643b905SSaleem Abdulrasool #endif
11821b654882SGreg Clayton 
11839fc1944eSEnrico Granata static bool
11849fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
11859fc1944eSEnrico Granata                       const char* var_name_end,
11869fc1944eSEnrico Granata                       const char** var_name_final,
11879fc1944eSEnrico Granata                       const char** percent_position,
11884d122c40SGreg Clayton                       Format* custom_format,
11899fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
11909fc1944eSEnrico Granata {
11915160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
11929fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
11939fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1194e992a089SEnrico Granata     {
1195e992a089SEnrico Granata         if (log)
1196d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
11979fc1944eSEnrico Granata         *var_name_final = var_name_end;
1198e992a089SEnrico Granata     }
11999fc1944eSEnrico Granata     else
12009fc1944eSEnrico Granata     {
12019fc1944eSEnrico Granata         *var_name_final = *percent_position;
120236aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1203e992a089SEnrico Granata         if (log)
120468ae4117SEnrico Granata             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
120536aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
12069fc1944eSEnrico Granata                                                   true,
12079fc1944eSEnrico Granata                                                   *custom_format) )
12089fc1944eSEnrico Granata         {
1209e992a089SEnrico Granata             if (log)
121068ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
121136aa5ae6SEnrico Granata 
121236aa5ae6SEnrico Granata             switch (format_name.front())
121336aa5ae6SEnrico Granata             {
121436aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
121586cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
121636aa5ae6SEnrico Granata                     break;
121736aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
121886cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
121936aa5ae6SEnrico Granata                     break;
122036aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
122186cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
122236aa5ae6SEnrico Granata                     break;
122336aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
122486cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
122536aa5ae6SEnrico Granata                     break;
122636aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
122786cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
122836aa5ae6SEnrico Granata                     break;
122936aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
123086cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
123136aa5ae6SEnrico Granata                     break;
12322c75f11eSEnrico Granata                 case 'N': // if this is a 'N', print the name
12332c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
12342c75f11eSEnrico Granata                     break;
12352c75f11eSEnrico Granata                 case '>': // if this is a '>', print the name
12362c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
12372c75f11eSEnrico Granata                     break;
123836aa5ae6SEnrico Granata                 default:
12395c42d8a8SJim Ingham                     if (log)
124036aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
124136aa5ae6SEnrico Granata                     break;
124236aa5ae6SEnrico Granata             }
12439fc1944eSEnrico Granata         }
12449fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
12459fc1944eSEnrico Granata         else
1246e992a089SEnrico Granata         {
1247e992a089SEnrico Granata             if (log)
124868ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
124986cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1250e992a089SEnrico Granata         }
12519fc1944eSEnrico Granata     }
1252e992a089SEnrico Granata     if (log)
125368ae4117SEnrico Granata         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1254e992a089SEnrico Granata                     *custom_format,
1255e992a089SEnrico Granata                     *val_obj_display);
12569fc1944eSEnrico Granata     return true;
12579fc1944eSEnrico Granata }
12589fc1944eSEnrico Granata 
12599fc1944eSEnrico Granata static bool
12609fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
12619fc1944eSEnrico Granata                     const char* var_name_end,
12629fc1944eSEnrico Granata                     const char* var_name_final,
12639fc1944eSEnrico Granata                     const char** open_bracket_position,
12649fc1944eSEnrico Granata                     const char** separator_position,
12659fc1944eSEnrico Granata                     const char** close_bracket_position,
12669fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12679fc1944eSEnrico Granata                     int64_t* index_lower,
12689fc1944eSEnrico Granata                     int64_t* index_higher)
12699fc1944eSEnrico Granata {
12705160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12719fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12729fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12739fc1944eSEnrico Granata     {
12749fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12759fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12769fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12779fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12789fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12799fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12809fc1944eSEnrico Granata         {
1281e992a089SEnrico Granata             if (log)
1282d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
12839fc1944eSEnrico Granata             *index_lower = 0;
12849fc1944eSEnrico Granata         }
12859fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
12869fc1944eSEnrico Granata         {
12879fc1944eSEnrico Granata             char *end = NULL;
12889fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12899fc1944eSEnrico Granata             *index_higher = *index_lower;
1290e992a089SEnrico Granata             if (log)
1291d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
12929fc1944eSEnrico Granata         }
12939fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
12949fc1944eSEnrico Granata         {
12959fc1944eSEnrico Granata             char *end = NULL;
12969fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12979fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1298e992a089SEnrico Granata             if (log)
1299d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
13009fc1944eSEnrico Granata         }
13019fc1944eSEnrico Granata         else
1302e992a089SEnrico Granata         {
1303e992a089SEnrico Granata             if (log)
1304d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
13059fc1944eSEnrico Granata             return false;
1306e992a089SEnrico Granata         }
13079fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
13089fc1944eSEnrico Granata         {
1309e992a089SEnrico Granata             if (log)
1310d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1311c7bece56SGreg Clayton             int64_t temp = *index_lower;
13129fc1944eSEnrico Granata             *index_lower = *index_higher;
13139fc1944eSEnrico Granata             *index_higher = temp;
13149fc1944eSEnrico Granata         }
13159fc1944eSEnrico Granata     }
1316e992a089SEnrico Granata     else if (log)
1317d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
13189fc1944eSEnrico Granata     return true;
13199fc1944eSEnrico Granata }
13209fc1944eSEnrico Granata 
13210769b2b1SMichael Sartain template <typename T>
13220769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
13230769b2b1SMichael Sartain {
13240769b2b1SMichael Sartain     if (script_interpreter)
13250769b2b1SMichael Sartain     {
13260769b2b1SMichael Sartain         Error script_error;
13270769b2b1SMichael Sartain         std::string script_output;
13280769b2b1SMichael Sartain 
13290769b2b1SMichael Sartain         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
13300769b2b1SMichael Sartain         {
13310769b2b1SMichael Sartain             s.Printf("%s", script_output.c_str());
13320769b2b1SMichael Sartain             return true;
13330769b2b1SMichael Sartain         }
13340769b2b1SMichael Sartain         else
13350769b2b1SMichael Sartain         {
13360769b2b1SMichael Sartain             s.Printf("<error: %s>",script_error.AsCString());
13370769b2b1SMichael Sartain         }
13380769b2b1SMichael Sartain     }
13390769b2b1SMichael Sartain     return false;
13400769b2b1SMichael Sartain }
13410769b2b1SMichael Sartain 
13429fc1944eSEnrico Granata static ValueObjectSP
1343c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1344c7bece56SGreg Clayton                          size_t index,
1345b57e4a1bSJason Molenda                          StackFrame* frame,
1346fc7a7f3bSEnrico Granata                          bool deref_pointer)
13479fc1944eSEnrico Granata {
13485160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1349fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1350599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1351599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1352e992a089SEnrico Granata     if (log)
1353599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1354fc7a7f3bSEnrico Granata     const char* first_unparsed;
1355fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1356fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1357fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
135886cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1359599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1360fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1361fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1362fc7a7f3bSEnrico Granata                                                           &final_value_type,
1363fc7a7f3bSEnrico Granata                                                           options,
1364fc7a7f3bSEnrico Granata                                                           &what_next);
1365fc7a7f3bSEnrico Granata     if (!item)
1366fc7a7f3bSEnrico Granata     {
1367e992a089SEnrico Granata         if (log)
1368d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1369e992a089SEnrico Granata                " final_value_type %d",
1370fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1371fc7a7f3bSEnrico Granata     }
13729fc1944eSEnrico Granata     else
13739fc1944eSEnrico Granata     {
1374e992a089SEnrico Granata         if (log)
1375d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1376e992a089SEnrico Granata                " final_value_type %d",
1377fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
13789fc1944eSEnrico Granata     }
13799fc1944eSEnrico Granata     return item;
13809fc1944eSEnrico Granata }
13819fc1944eSEnrico Granata 
13820769b2b1SMichael Sartain static inline bool
13830769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var)
13840769b2b1SMichael Sartain {
13850769b2b1SMichael Sartain     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
13860769b2b1SMichael Sartain }
13870769b2b1SMichael Sartain 
13880769b2b1SMichael Sartain static bool
13890769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
13900769b2b1SMichael Sartain     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
13910769b2b1SMichael Sartain {
13920769b2b1SMichael Sartain     int var_len = strlen(var);
13930769b2b1SMichael Sartain     if (::strncmp (var_name_begin, var, var_len) == 0)
13940769b2b1SMichael Sartain     {
13950769b2b1SMichael Sartain         var_name_begin += var_len;
13960769b2b1SMichael Sartain         if (*var_name_begin == '}')
13970769b2b1SMichael Sartain         {
13980769b2b1SMichael Sartain             format = default_format;
13990769b2b1SMichael Sartain             return true;
14000769b2b1SMichael Sartain         }
14010769b2b1SMichael Sartain         else if (*var_name_begin == '%')
14020769b2b1SMichael Sartain         {
14030769b2b1SMichael Sartain             // Allow format specifiers: x|X|u with optional width specifiers.
14040769b2b1SMichael Sartain             //   ${thread.id%x}    ; hex
14050769b2b1SMichael Sartain             //   ${thread.id%X}    ; uppercase hex
14060769b2b1SMichael Sartain             //   ${thread.id%u}    ; unsigned decimal
14070769b2b1SMichael Sartain             //   ${thread.id%8.8X} ; width.precision + specifier
14080769b2b1SMichael Sartain             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
14090769b2b1SMichael Sartain             int dot_count = 0;
14100769b2b1SMichael Sartain             const char *specifier = NULL;
14110769b2b1SMichael Sartain             int width_precision_length = 0;
14120769b2b1SMichael Sartain             const char *width_precision = ++var_name_begin;
14130769b2b1SMichael Sartain             while (isdigit(*var_name_begin) || *var_name_begin == '.')
14140769b2b1SMichael Sartain             {
14150769b2b1SMichael Sartain                 dot_count += (*var_name_begin == '.');
14160769b2b1SMichael Sartain                 if (dot_count > 1)
14170769b2b1SMichael Sartain                     break;
14180769b2b1SMichael Sartain                 var_name_begin++;
14190769b2b1SMichael Sartain                 width_precision_length++;
14200769b2b1SMichael Sartain             }
14210769b2b1SMichael Sartain 
14220769b2b1SMichael Sartain             if (IsToken (var_name_begin, "tid}"))
14230769b2b1SMichael Sartain             {
14240769b2b1SMichael Sartain                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
14250769b2b1SMichael Sartain                 if (target)
14260769b2b1SMichael Sartain                 {
14270769b2b1SMichael Sartain                     ArchSpec arch (target->GetArchitecture ());
14280769b2b1SMichael Sartain                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
14290769b2b1SMichael Sartain                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
14300769b2b1SMichael Sartain                         specifier = PRIu64;
14310769b2b1SMichael Sartain                 }
14320769b2b1SMichael Sartain                 if (!specifier)
14330769b2b1SMichael Sartain                 {
14340769b2b1SMichael Sartain                     format = default_format;
14350769b2b1SMichael Sartain                     return true;
14360769b2b1SMichael Sartain                 }
14370769b2b1SMichael Sartain             }
14380769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "x}"))
14390769b2b1SMichael Sartain                 specifier = PRIx64;
14400769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "X}"))
14410769b2b1SMichael Sartain                 specifier = PRIX64;
14420769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "u}"))
14430769b2b1SMichael Sartain                 specifier = PRIu64;
14440769b2b1SMichael Sartain 
14450769b2b1SMichael Sartain             if (specifier)
14460769b2b1SMichael Sartain             {
14470769b2b1SMichael Sartain                 format = "%";
14480769b2b1SMichael Sartain                 if (width_precision_length)
14490769b2b1SMichael Sartain                     format += std::string(width_precision, width_precision_length);
14500769b2b1SMichael Sartain                 format += specifier;
14510769b2b1SMichael Sartain                 return true;
14520769b2b1SMichael Sartain             }
14530769b2b1SMichael Sartain         }
14540769b2b1SMichael Sartain     }
14550769b2b1SMichael Sartain     return false;
14560769b2b1SMichael Sartain }
14570769b2b1SMichael Sartain 
1458705b1809SJason Molenda // Find information for the "thread.info.*" specifiers in a format string
1459705b1809SJason Molenda static bool
1460705b1809SJason Molenda FormatThreadExtendedInfoRecurse
1461705b1809SJason Molenda (
1462705b1809SJason Molenda     const char *var_name_begin,
1463705b1809SJason Molenda     StructuredData::ObjectSP thread_info_dictionary,
1464705b1809SJason Molenda     const SymbolContext *sc,
1465705b1809SJason Molenda     const ExecutionContext *exe_ctx,
1466705b1809SJason Molenda     Stream &s
1467705b1809SJason Molenda )
1468705b1809SJason Molenda {
1469705b1809SJason Molenda     bool var_success = false;
1470705b1809SJason Molenda     std::string token_format;
1471705b1809SJason Molenda 
1472705b1809SJason Molenda     llvm::StringRef var_name(var_name_begin);
1473705b1809SJason Molenda     size_t percent_idx = var_name.find('%');
1474705b1809SJason Molenda     size_t close_curly_idx = var_name.find('}');
1475705b1809SJason Molenda     llvm::StringRef path = var_name;
1476705b1809SJason Molenda     llvm::StringRef formatter = var_name;
1477705b1809SJason Molenda 
1478705b1809SJason Molenda     // 'path' will be the dot separated list of objects to transverse up until we hit
1479705b1809SJason Molenda     // a close curly brace, a percent sign, or an end of string.
1480705b1809SJason Molenda     if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
1481705b1809SJason Molenda     {
1482705b1809SJason Molenda         if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
1483705b1809SJason Molenda         {
1484705b1809SJason Molenda             if (percent_idx < close_curly_idx)
1485705b1809SJason Molenda             {
1486705b1809SJason Molenda                 path = var_name.slice(0, percent_idx);
1487705b1809SJason Molenda                 formatter = var_name.substr (percent_idx);
1488705b1809SJason Molenda             }
1489705b1809SJason Molenda             else
1490705b1809SJason Molenda             {
1491705b1809SJason Molenda                 path = var_name.slice(0, close_curly_idx);
1492705b1809SJason Molenda                 formatter = var_name.substr (close_curly_idx);
1493705b1809SJason Molenda             }
1494705b1809SJason Molenda         }
1495705b1809SJason Molenda         else if (percent_idx != llvm::StringRef::npos)
1496705b1809SJason Molenda         {
1497705b1809SJason Molenda             path = var_name.slice(0, percent_idx);
1498705b1809SJason Molenda             formatter = var_name.substr (percent_idx);
1499705b1809SJason Molenda         }
1500705b1809SJason Molenda         else if (close_curly_idx != llvm::StringRef::npos)
1501705b1809SJason Molenda         {
1502705b1809SJason Molenda             path = var_name.slice(0, close_curly_idx);
1503705b1809SJason Molenda             formatter = var_name.substr (close_curly_idx);
1504705b1809SJason Molenda         }
1505705b1809SJason Molenda     }
1506705b1809SJason Molenda 
1507705b1809SJason Molenda     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1508705b1809SJason Molenda 
1509705b1809SJason Molenda     if (value.get())
1510705b1809SJason Molenda     {
1511705b1809SJason Molenda         if (value->GetType() == StructuredData::Type::eTypeInteger)
1512705b1809SJason Molenda         {
1513705b1809SJason Molenda             if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1514705b1809SJason Molenda             {
1515705b1809SJason Molenda                 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
1516705b1809SJason Molenda                 var_success = true;
1517705b1809SJason Molenda             }
1518705b1809SJason Molenda         }
1519705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1520705b1809SJason Molenda         {
1521705b1809SJason Molenda             s.Printf ("%f", value->GetAsFloat()->GetValue());
1522705b1809SJason Molenda             var_success = true;
1523705b1809SJason Molenda         }
1524705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeString)
1525705b1809SJason Molenda         {
1526705b1809SJason Molenda             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1527705b1809SJason Molenda             var_success = true;
1528705b1809SJason Molenda         }
1529705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeArray)
1530705b1809SJason Molenda         {
1531705b1809SJason Molenda             if (value->GetAsArray()->GetSize() > 0)
1532705b1809SJason Molenda             {
1533705b1809SJason Molenda                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1534705b1809SJason Molenda                 var_success = true;
1535705b1809SJason Molenda             }
1536705b1809SJason Molenda         }
1537705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1538705b1809SJason Molenda         {
1539705b1809SJason Molenda             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1540705b1809SJason Molenda             var_success = true;
1541705b1809SJason Molenda         }
1542705b1809SJason Molenda     }
1543705b1809SJason Molenda 
1544705b1809SJason Molenda     return var_success;
1545705b1809SJason Molenda }
1546705b1809SJason Molenda 
1547705b1809SJason Molenda 
1548c3ce7f27SMichael Sartain static bool
1549c3ce7f27SMichael Sartain FormatPromptRecurse
15501b654882SGreg Clayton (
15511b654882SGreg Clayton     const char *format,
15521b654882SGreg Clayton     const SymbolContext *sc,
15531b654882SGreg Clayton     const ExecutionContext *exe_ctx,
15541b654882SGreg Clayton     const Address *addr,
15551b654882SGreg Clayton     Stream &s,
15564becb37eSEnrico Granata     const char **end,
1557c482a192SEnrico Granata     ValueObject* valobj
15581b654882SGreg Clayton )
15591b654882SGreg Clayton {
1560c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
15611b654882SGreg Clayton     bool success = true;
15621b654882SGreg Clayton     const char *p;
15635160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1564c3ce7f27SMichael Sartain 
15651b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
15661b654882SGreg Clayton     {
1567c482a192SEnrico Granata         if (realvalobj)
15684becb37eSEnrico Granata         {
1569c482a192SEnrico Granata             valobj = realvalobj;
1570c482a192SEnrico Granata             realvalobj = NULL;
15714becb37eSEnrico Granata         }
15721b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
15731b654882SGreg Clayton         if (non_special_chars > 0)
15741b654882SGreg Clayton         {
15751b654882SGreg Clayton             if (success)
15761b654882SGreg Clayton                 s.Write (p, non_special_chars);
15771b654882SGreg Clayton             p += non_special_chars;
15781b654882SGreg Clayton         }
15791b654882SGreg Clayton 
15801b654882SGreg Clayton         if (*p == '\0')
15811b654882SGreg Clayton         {
15821b654882SGreg Clayton             break;
15831b654882SGreg Clayton         }
15841b654882SGreg Clayton         else if (*p == '{')
15851b654882SGreg Clayton         {
15861b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
15871b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
15881b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
15891b654882SGreg Clayton             // is one in the symbol context you can use:
15901b654882SGreg Clayton             //      "{function =${function.name}}"
15911b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
15921b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
15931b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
15941b654882SGreg Clayton             // or symbol with a valid name.
15951b654882SGreg Clayton             StreamString sub_strm;
15961b654882SGreg Clayton 
15971b654882SGreg Clayton             ++p;  // Skip the '{'
15981b654882SGreg Clayton 
1599c3ce7f27SMichael Sartain             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
16001b654882SGreg Clayton             {
16011b654882SGreg Clayton                 // The stream had all it needed
16021b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
16031b654882SGreg Clayton             }
16041b654882SGreg Clayton             if (*p != '}')
16051b654882SGreg Clayton             {
16061b654882SGreg Clayton                 success = false;
16071b654882SGreg Clayton                 break;
16081b654882SGreg Clayton             }
16091b654882SGreg Clayton         }
16101b654882SGreg Clayton         else if (*p == '}')
16111b654882SGreg Clayton         {
16121b654882SGreg Clayton             // End of a enclosing scope
16131b654882SGreg Clayton             break;
16141b654882SGreg Clayton         }
16151b654882SGreg Clayton         else if (*p == '$')
16161b654882SGreg Clayton         {
16171b654882SGreg Clayton             // We have a prompt variable to print
16181b654882SGreg Clayton             ++p;
16191b654882SGreg Clayton             if (*p == '{')
16201b654882SGreg Clayton             {
16211b654882SGreg Clayton                 ++p;
16221b654882SGreg Clayton                 const char *var_name_begin = p;
16231b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
16241b654882SGreg Clayton 
16251b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
16261b654882SGreg Clayton                 {
16271b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
16281b654882SGreg Clayton                     if (success)
16291b654882SGreg Clayton                     {
16301b654882SGreg Clayton                         const char *cstr = NULL;
16310769b2b1SMichael Sartain                         std::string token_format;
16321b654882SGreg Clayton                         Address format_addr;
16331b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
16341b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
16351b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
16361b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
16371b654882SGreg Clayton                         FileSpec format_file_spec;
1638e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
16391b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
16409fc1944eSEnrico Granata                         bool do_deref_pointer = false;
164186cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
164286cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
16431b654882SGreg Clayton 
16441b654882SGreg Clayton                         // Each variable must set success to true below...
16451b654882SGreg Clayton                         bool var_success = false;
16461b654882SGreg Clayton                         switch (var_name_begin[0])
16471b654882SGreg Clayton                         {
16484becb37eSEnrico Granata                         case '*':
16496f3533fbSEnrico Granata                         case 'v':
16506f3533fbSEnrico Granata                         case 's':
16514becb37eSEnrico Granata                             {
1652c482a192SEnrico Granata                                 if (!valobj)
165334132754SGreg Clayton                                     break;
16546f3533fbSEnrico Granata 
1655c3e320a7SEnrico Granata                                 if (log)
1656d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1657c3e320a7SEnrico Granata 
16586f3533fbSEnrico Granata                                 // check for *var and *svar
16596f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
16606f3533fbSEnrico Granata                                 {
16619fc1944eSEnrico Granata                                     do_deref_pointer = true;
16629fc1944eSEnrico Granata                                     var_name_begin++;
1663c3e320a7SEnrico Granata                                     if (log)
166468ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
166568ae4117SEnrico Granata                                 }
1666c3e320a7SEnrico Granata 
16676f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
16684becb37eSEnrico Granata                                 {
1669c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
167086cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
167186cc9829SEnrico Granata                                     if (!valobj)
167286cc9829SEnrico Granata                                         break;
16736f3533fbSEnrico Granata                                     var_name_begin++;
1674c3e320a7SEnrico Granata                                     if (log)
167568ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
167668ae4117SEnrico Granata                                 }
1677c3e320a7SEnrico Granata 
16786f3533fbSEnrico Granata                                 // should be a 'v' by now
16796f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
16806f3533fbSEnrico Granata                                     break;
16816f3533fbSEnrico Granata 
1682c3e320a7SEnrico Granata                                 if (log)
168368ae4117SEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1684c3e320a7SEnrico Granata 
1685fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
168686cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1687fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
16888c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
168986cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
169034132754SGreg Clayton                                 ValueObject* target = NULL;
16914d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
169234132754SGreg Clayton                                 const char* var_name_final = NULL;
16939fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
169434132754SGreg Clayton                                 const char* close_bracket_position = NULL;
169534132754SGreg Clayton                                 int64_t index_lower = -1;
169634132754SGreg Clayton                                 int64_t index_higher = -1;
16979fc1944eSEnrico Granata                                 bool is_array_range = false;
1698fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
169985933ed4SEnrico Granata                                 bool was_plain_var = false;
170085933ed4SEnrico Granata                                 bool was_var_format = false;
1701a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1702fc7a7f3bSEnrico Granata 
1703c482a192SEnrico Granata                                 if (!valobj) break;
1704c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
17050769b2b1SMichael Sartain                                 if (IsToken (var_name_begin, "var}"))
17060a3958e0SEnrico Granata                                 {
170785933ed4SEnrico Granata                                     was_plain_var = true;
1708c482a192SEnrico Granata                                     target = valobj;
170986cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17100a3958e0SEnrico Granata                                 }
17110769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin,"var%"))
17129fc1944eSEnrico Granata                                 {
171385933ed4SEnrico Granata                                     was_var_format = true;
17149fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
17159fc1944eSEnrico Granata                                     const char* percent_position;
1716c482a192SEnrico Granata                                     target = valobj;
171786cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17189fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17199fc1944eSEnrico Granata                                                           var_name_end,
17209fc1944eSEnrico Granata                                                           &var_name_final,
17219fc1944eSEnrico Granata                                                           &percent_position,
17229fc1944eSEnrico Granata                                                           &custom_format,
17239fc1944eSEnrico Granata                                                           &val_obj_display);
17240a3958e0SEnrico Granata                                 }
17259fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
17260769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin, "var"))
17279fc1944eSEnrico Granata                                 {
17280769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "var["))
1729a777dc2aSEnrico Granata                                         was_var_indexed = true;
17309fc1944eSEnrico Granata                                     const char* percent_position;
17319fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17329fc1944eSEnrico Granata                                                           var_name_end,
17339fc1944eSEnrico Granata                                                           &var_name_final,
17349fc1944eSEnrico Granata                                                           &percent_position,
17359fc1944eSEnrico Granata                                                           &custom_format,
17369fc1944eSEnrico Granata                                                           &val_obj_display);
17379fc1944eSEnrico Granata 
17389fc1944eSEnrico Granata                                     const char* open_bracket_position;
17399fc1944eSEnrico Granata                                     const char* separator_position;
17409fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
17419fc1944eSEnrico Granata                                                         var_name_end,
17429fc1944eSEnrico Granata                                                         var_name_final,
17439fc1944eSEnrico Granata                                                         &open_bracket_position,
17449fc1944eSEnrico Granata                                                         &separator_position,
17459fc1944eSEnrico Granata                                                         &close_bracket_position,
17469fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
17479fc1944eSEnrico Granata                                                         &index_lower,
17489fc1944eSEnrico Granata                                                         &index_higher);
17499fc1944eSEnrico Granata 
17509fc1944eSEnrico Granata                                     Error error;
17519fc1944eSEnrico Granata 
1752599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1753599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1754fc7a7f3bSEnrico Granata 
1755e992a089SEnrico Granata                                     if (log)
1756599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1757fc7a7f3bSEnrico Granata 
1758599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1759fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1760fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1761fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1762fc7a7f3bSEnrico Granata                                                                              options,
1763fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1764fc7a7f3bSEnrico Granata 
1765fc7a7f3bSEnrico Granata                                     if (!target)
17669fc1944eSEnrico Granata                                     {
1767e992a089SEnrico Granata                                         if (log)
1768d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1769e992a089SEnrico Granata                                                " final_value_type %d",
1770fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1771fc7a7f3bSEnrico Granata                                         break;
17720a3958e0SEnrico Granata                                     }
1773a7187d00SEnrico Granata                                     else
1774fc7a7f3bSEnrico Granata                                     {
1775e992a089SEnrico Granata                                         if (log)
1776d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1777e992a089SEnrico Granata                                                " final_value_type %d",
1778fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1779a7187d00SEnrico Granata                                     }
17800a3958e0SEnrico Granata                                 }
17810a3958e0SEnrico Granata                                 else
17820a3958e0SEnrico Granata                                     break;
17839fc1944eSEnrico Granata 
178486cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
178586cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1786fc7a7f3bSEnrico Granata 
178786cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1788fc7a7f3bSEnrico Granata 
1789a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
17900a3958e0SEnrico Granata                                 {
17919fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
17929fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
17939fc1944eSEnrico Granata                                     // to get to the target ValueObject
17949fc1944eSEnrico Granata                                     Error error;
17959fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1796dc940730SEnrico Granata                                     if (error.Fail())
1797dc940730SEnrico Granata                                     {
1798dc940730SEnrico Granata                                         if (log)
1799d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1800dc940730SEnrico Granata                                         break;
1801dc940730SEnrico Granata                                     }
18029fc1944eSEnrico Granata                                     do_deref_pointer = false;
18030a3958e0SEnrico Granata                                 }
18040a3958e0SEnrico Granata 
1805f164d940SJim Ingham                                 if (!target)
1806f164d940SJim Ingham                                 {
1807f164d940SJim Ingham                                     if (log)
1808f164d940SJim Ingham                                         log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
1809f164d940SJim Ingham                                     break;
1810f164d940SJim Ingham                                 }
1811f164d940SJim Ingham 
1812a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1813a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1814a777dc2aSEnrico Granata                                 // us into an endless recursion
1815a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1816a777dc2aSEnrico Granata                                 {
1817a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1818a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1819a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1820a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1821a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1822a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1823a777dc2aSEnrico Granata                                 }
1824a777dc2aSEnrico Granata 
182585933ed4SEnrico Granata                                 // TODO use flags for these
182657ee3067SGreg Clayton                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
182757ee3067SGreg Clayton                                 bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0;
182857ee3067SGreg Clayton                                 bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0;
182957ee3067SGreg Clayton                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1830f4efecd9SEnrico Granata 
183186cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1832f4efecd9SEnrico Granata                                 {
183385933ed4SEnrico Granata                                     StreamString str_temp;
1834e992a089SEnrico Granata                                     if (log)
1835d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1836d64d0bc0SEnrico Granata 
18375088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1838d64d0bc0SEnrico Granata                                     {
1839f4efecd9SEnrico Granata                                         // try to use the special cases
184085933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
184185933ed4SEnrico Granata                                                                                           val_obj_display,
184285933ed4SEnrico Granata                                                                                           custom_format);
1843e992a089SEnrico Granata                                         if (log)
1844d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1845d64d0bc0SEnrico Granata 
1846d64d0bc0SEnrico Granata                                         // should not happen
18475088c486SGreg Clayton                                         if (var_success)
184885933ed4SEnrico Granata                                             s << str_temp.GetData();
1849d64d0bc0SEnrico Granata                                         var_success = true;
1850d64d0bc0SEnrico Granata                                         break;
1851d64d0bc0SEnrico Granata                                     }
1852d64d0bc0SEnrico Granata                                     else
1853d64d0bc0SEnrico Granata                                     {
185488da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1855d64d0bc0SEnrico Granata                                         {
1856d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1857d64d0bc0SEnrico Granata                                         }
185888da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
185988da35f8SEnrico Granata                                         {
186023f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
186188da35f8SEnrico Granata                                                                                  val_obj_display,
186286cc9829SEnrico Granata                                                                                  custom_format,
186386cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
186488da35f8SEnrico Granata                                         }
1865d64d0bc0SEnrico Granata                                         var_success = true;
1866d64d0bc0SEnrico Granata                                         break;
1867d64d0bc0SEnrico Granata                                     }
1868d64d0bc0SEnrico Granata                                 }
1869d64d0bc0SEnrico Granata 
1870d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1871d64d0bc0SEnrico Granata                                 // type @ location message
1872d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1873d64d0bc0SEnrico Granata                                 {
1874d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1875d64d0bc0SEnrico Granata                                     var_success = true;
187685933ed4SEnrico Granata                                     break;
187785933ed4SEnrico Granata                                 }
187885933ed4SEnrico Granata 
1879d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
188086cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
188185933ed4SEnrico Granata                                 {
188285933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
188385933ed4SEnrico Granata                                     var_success = true;
1884f4efecd9SEnrico Granata                                     break;
1885f4efecd9SEnrico Granata                                 }
1886f4efecd9SEnrico Granata 
18879fc1944eSEnrico Granata                                 if (!is_array_range)
1888e992a089SEnrico Granata                                 {
1889e992a089SEnrico Granata                                     if (log)
1890d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
18919fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1892e992a089SEnrico Granata                                 }
18939fc1944eSEnrico Granata                                 else
18949fc1944eSEnrico Granata                                 {
1895e992a089SEnrico Granata                                     if (log)
1896d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
18979fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
18989fc1944eSEnrico Granata                                         break;
1899e992a089SEnrico Granata                                     if (log)
1900d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1901fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1902fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
19030a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
19040a3958e0SEnrico Granata                                     {
1905fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1906fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1907fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1908fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1909fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1910fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
19110a3958e0SEnrico Granata                                     }
19120a3958e0SEnrico Granata 
19130a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
19140a3958e0SEnrico Granata                                     s.PutChar('[');
19150a3958e0SEnrico Granata                                     var_success = true;
19160a3958e0SEnrico Granata 
19179fc1944eSEnrico Granata                                     if (index_higher < 0)
1918c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
19190a3958e0SEnrico Granata 
1920cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
192122c55d18SEnrico Granata 
19220a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
19230a3958e0SEnrico Granata                                     {
1924fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
19259fc1944eSEnrico Granata                                                                                      index_lower,
1926c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1927fc7a7f3bSEnrico Granata                                                                                      false).get();
19280a3958e0SEnrico Granata 
1929fc7a7f3bSEnrico Granata                                         if (!item)
1930fc7a7f3bSEnrico Granata                                         {
1931e992a089SEnrico Granata                                             if (log)
1932d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1933fc7a7f3bSEnrico Granata                                         }
1934fc7a7f3bSEnrico Granata                                         else
1935fc7a7f3bSEnrico Granata                                         {
1936e992a089SEnrico Granata                                             if (log)
1937d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1938fc7a7f3bSEnrico Granata                                         }
1939fc7a7f3bSEnrico Granata 
19400a3958e0SEnrico Granata                                         if (!special_directions)
19419fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
19420a3958e0SEnrico Granata                                         else
1943c3ce7f27SMichael Sartain                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item);
19440a3958e0SEnrico Granata 
194522c55d18SEnrico Granata                                         if (--max_num_children == 0)
194622c55d18SEnrico Granata                                         {
194722c55d18SEnrico Granata                                             s.PutCString(", ...");
194822c55d18SEnrico Granata                                             break;
194922c55d18SEnrico Granata                                         }
195022c55d18SEnrico Granata 
19510a3958e0SEnrico Granata                                         if (index_lower < index_higher)
19520a3958e0SEnrico Granata                                             s.PutChar(',');
19530a3958e0SEnrico Granata                                     }
19540a3958e0SEnrico Granata                                     s.PutChar(']');
19554becb37eSEnrico Granata                                 }
19564becb37eSEnrico Granata                             }
195734132754SGreg Clayton                             break;
19581b654882SGreg Clayton                         case 'a':
19590769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "addr}"))
19601b654882SGreg Clayton                             {
19611b654882SGreg Clayton                                 if (addr && addr->IsValid())
19621b654882SGreg Clayton                                 {
19631b654882SGreg Clayton                                     var_success = true;
19641b654882SGreg Clayton                                     format_addr = *addr;
19651b654882SGreg Clayton                                 }
19661b654882SGreg Clayton                             }
19671b654882SGreg Clayton                             break;
19681b654882SGreg Clayton 
19691b654882SGreg Clayton                         case 'p':
19700769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "process."))
19711b654882SGreg Clayton                             {
1972c14ee32dSGreg Clayton                                 if (exe_ctx)
1973c14ee32dSGreg Clayton                                 {
1974c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
1975c14ee32dSGreg Clayton                                     if (process)
19761b654882SGreg Clayton                                     {
19771b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
19780769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
19791b654882SGreg Clayton                                         {
19800769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), process->GetID());
19811b654882SGreg Clayton                                             var_success = true;
19821b654882SGreg Clayton                                         }
19830769b2b1SMichael Sartain                                         else if ((IsToken (var_name_begin, "name}")) ||
19840769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.basename}")) ||
19850769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.fullpath}")))
19861b654882SGreg Clayton                                         {
1987c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1988aa149cbdSGreg Clayton                                             if (exe_module)
19891b654882SGreg Clayton                                             {
19901b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
19911b654882SGreg Clayton                                                 {
1992aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
19939076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
19941b654882SGreg Clayton                                                 }
19951b654882SGreg Clayton                                                 else
19961b654882SGreg Clayton                                                 {
1997aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
19989076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
19991b654882SGreg Clayton                                                 }
20001b654882SGreg Clayton                                             }
20011b654882SGreg Clayton                                         }
20020769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2003aad8e480SEnrico Granata                                         {
2004aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2005aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2006aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
20070769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
2008aad8e480SEnrico Granata                                                 var_success = true;
2009aad8e480SEnrico Granata                                         }
20101b654882SGreg Clayton                                     }
20111b654882SGreg Clayton                                 }
2012c14ee32dSGreg Clayton                             }
20131b654882SGreg Clayton                             break;
20141b654882SGreg Clayton 
20151b654882SGreg Clayton                         case 't':
20160769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "thread."))
20171b654882SGreg Clayton                             {
2018c14ee32dSGreg Clayton                                 if (exe_ctx)
2019c14ee32dSGreg Clayton                                 {
2020c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
2021c14ee32dSGreg Clayton                                     if (thread)
20221b654882SGreg Clayton                                     {
20231b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
20240769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
20251b654882SGreg Clayton                                         {
20260769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetID());
20271b654882SGreg Clayton                                             var_success = true;
20281b654882SGreg Clayton                                         }
20290769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2030160c9d81SGreg Clayton                                         {
20310769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
2032160c9d81SGreg Clayton                                             var_success = true;
2033160c9d81SGreg Clayton                                         }
20340769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
20351b654882SGreg Clayton                                         {
20360769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
20371b654882SGreg Clayton                                             var_success = true;
20381b654882SGreg Clayton                                         }
20390769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "name}"))
20401b654882SGreg Clayton                                         {
2041c14ee32dSGreg Clayton                                             cstr = thread->GetName();
20421b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20431b654882SGreg Clayton                                             if (var_success)
20441b654882SGreg Clayton                                                 s.PutCString(cstr);
20451b654882SGreg Clayton                                         }
20460769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "queue}"))
20471b654882SGreg Clayton                                         {
2048c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
20491b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20501b654882SGreg Clayton                                             if (var_success)
20511b654882SGreg Clayton                                                 s.PutCString(cstr);
20521b654882SGreg Clayton                                         }
20530769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "stop-reason}"))
20541b654882SGreg Clayton                                         {
2055c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20565d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
20571b654882SGreg Clayton                                             {
2058b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
20591b654882SGreg Clayton                                                 if (cstr && cstr[0])
20601b654882SGreg Clayton                                                 {
20611b654882SGreg Clayton                                                     s.PutCString(cstr);
20621b654882SGreg Clayton                                                     var_success = true;
20631b654882SGreg Clayton                                                 }
20641b654882SGreg Clayton                                             }
20651b654882SGreg Clayton                                         }
20660769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "return-value}"))
206773ca05a2SJim Ingham                                         {
206873ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20695d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
207073ca05a2SJim Ingham                                             {
207173ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
207273ca05a2SJim Ingham                                                 if (return_valobj_sp)
207373ca05a2SJim Ingham                                                 {
20744d93b8cdSEnrico Granata                                                     return_valobj_sp->Dump(s);
207573ca05a2SJim Ingham                                                     var_success = true;
207673ca05a2SJim Ingham                                                 }
207773ca05a2SJim Ingham                                             }
207873ca05a2SJim Ingham                                         }
207930fadafeSJim Ingham                                         else if (IsToken (var_name_begin, "completed-expression}"))
208030fadafeSJim Ingham                                         {
208130fadafeSJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
208230fadafeSJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
208330fadafeSJim Ingham                                             {
208430fadafeSJim Ingham                                                 ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
208530fadafeSJim Ingham                                                 if (expression_var_sp && expression_var_sp->GetValueObject())
208630fadafeSJim Ingham                                                 {
208730fadafeSJim Ingham                                                     expression_var_sp->GetValueObject()->Dump(s);
208830fadafeSJim Ingham                                                     var_success = true;
208930fadafeSJim Ingham                                                 }
209030fadafeSJim Ingham                                             }
209130fadafeSJim Ingham                                         }
20920769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2093aad8e480SEnrico Granata                                         {
2094aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2095aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2096aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
20970769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2098aad8e480SEnrico Granata                                                 var_success = true;
2099aad8e480SEnrico Granata                                         }
2100705b1809SJason Molenda                                         else if (IsToken (var_name_begin, "info."))
2101705b1809SJason Molenda                                         {
2102705b1809SJason Molenda                                             var_name_begin += ::strlen("info.");
2103705b1809SJason Molenda                                             StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
2104705b1809SJason Molenda                                             if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
2105705b1809SJason Molenda                                             {
2106705b1809SJason Molenda                                                 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
2107705b1809SJason Molenda                                             }
2108705b1809SJason Molenda                                         }
2109aad8e480SEnrico Granata                                     }
2110aad8e480SEnrico Granata                                 }
211173ca05a2SJim Ingham                             }
21120769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "target."))
21131b654882SGreg Clayton                             {
211467cc0636SGreg Clayton                                 // TODO: hookup properties
211567cc0636SGreg Clayton //                                if (!target_properties_sp)
211667cc0636SGreg Clayton //                                {
211767cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
211867cc0636SGreg Clayton //                                    if (target)
211967cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
212067cc0636SGreg Clayton //                                }
212167cc0636SGreg Clayton //
212267cc0636SGreg Clayton //                                if (target_properties_sp)
212367cc0636SGreg Clayton //                                {
212467cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
212567cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
212667cc0636SGreg Clayton //                                    if (end_property)
212767cc0636SGreg Clayton //                                    {
212867cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
212967cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
213067cc0636SGreg Clayton //                                        if (!property_value.empty())
213167cc0636SGreg Clayton //                                        {
213267cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
213367cc0636SGreg Clayton //                                            var_success = true;
213467cc0636SGreg Clayton //                                        }
213567cc0636SGreg Clayton //                                    }
213667cc0636SGreg Clayton //                                }
21370603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
21380603aa9dSGreg Clayton                                 if (target)
21391b654882SGreg Clayton                                 {
21401b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
21410769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "arch}"))
21421b654882SGreg Clayton                                     {
21431b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
21441b654882SGreg Clayton                                         if (arch.IsValid())
21451b654882SGreg Clayton                                         {
214664195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
21471b654882SGreg Clayton                                             var_success = true;
21481b654882SGreg Clayton                                         }
21491b654882SGreg Clayton                                     }
21500769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "script:"))
2151aad8e480SEnrico Granata                                     {
2152aad8e480SEnrico Granata                                         var_name_begin += ::strlen("script:");
2153aad8e480SEnrico Granata                                         std::string script_name(var_name_begin,var_name_end);
2154aad8e480SEnrico Granata                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
21550769b2b1SMichael Sartain                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2156aad8e480SEnrico Granata                                             var_success = true;
2157aad8e480SEnrico Granata                                     }
21581b654882SGreg Clayton                                 }
21591b654882SGreg Clayton                             }
21601b654882SGreg Clayton                             break;
21611b654882SGreg Clayton 
21621b654882SGreg Clayton 
21631b654882SGreg Clayton                         case 'm':
21640769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "module."))
21651b654882SGreg Clayton                             {
21660603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
21671b654882SGreg Clayton                                 {
21680603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
21691b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
21701b654882SGreg Clayton 
21710769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
21721b654882SGreg Clayton                                     {
21731b654882SGreg Clayton                                         if (module->GetFileSpec())
21741b654882SGreg Clayton                                         {
21751b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
21761b654882SGreg Clayton 
21770769b2b1SMichael Sartain                                             if (IsToken (var_name_begin, "basename}"))
21781b654882SGreg Clayton                                             {
21791b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
21809076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
21811b654882SGreg Clayton                                             }
21820769b2b1SMichael Sartain                                             else if (IsToken (var_name_begin, "fullpath}"))
21831b654882SGreg Clayton                                             {
21841b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
21859076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
21861b654882SGreg Clayton                                             }
21871b654882SGreg Clayton                                         }
21881b654882SGreg Clayton                                     }
21891b654882SGreg Clayton                                 }
21901b654882SGreg Clayton                             }
21911b654882SGreg Clayton                             break;
21921b654882SGreg Clayton 
21931b654882SGreg Clayton 
21941b654882SGreg Clayton                         case 'f':
21950769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "file."))
21961b654882SGreg Clayton                             {
21971b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
21981b654882SGreg Clayton                                 {
21991b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
22001b654882SGreg Clayton 
22010769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "basename}"))
22021b654882SGreg Clayton                                     {
22031b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
22049076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22051b654882SGreg Clayton                                     }
22060769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "fullpath}"))
22071b654882SGreg Clayton                                     {
22081b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
22099076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22101b654882SGreg Clayton                                     }
22111b654882SGreg Clayton                                 }
22121b654882SGreg Clayton                             }
22130769b2b1SMichael Sartain                            else if (IsToken (var_name_begin, "frame."))
22141b654882SGreg Clayton                             {
2215c14ee32dSGreg Clayton                                 if (exe_ctx)
2216c14ee32dSGreg Clayton                                 {
2217b57e4a1bSJason Molenda                                     StackFrame *frame = exe_ctx->GetFramePtr();
2218c14ee32dSGreg Clayton                                     if (frame)
22191b654882SGreg Clayton                                     {
22201b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
22210769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "index}"))
22221b654882SGreg Clayton                                         {
2223c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
22241b654882SGreg Clayton                                             var_success = true;
22251b654882SGreg Clayton                                         }
22260769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "pc}"))
22271b654882SGreg Clayton                                         {
22281b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22291b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
22301b654882SGreg Clayton                                             var_success = true;
22311b654882SGreg Clayton                                         }
22320769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "sp}"))
22331b654882SGreg Clayton                                         {
22341b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22351b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
22361b654882SGreg Clayton                                             var_success = true;
22371b654882SGreg Clayton                                         }
22380769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fp}"))
22391b654882SGreg Clayton                                         {
22401b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22411b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
22421b654882SGreg Clayton                                             var_success = true;
22431b654882SGreg Clayton                                         }
22440769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "flags}"))
22451b654882SGreg Clayton                                         {
22461b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22471b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
22481b654882SGreg Clayton                                             var_success = true;
22491b654882SGreg Clayton                                         }
22500769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "reg."))
22511b654882SGreg Clayton                                         {
2252c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
22531b654882SGreg Clayton                                             if (reg_ctx)
22541b654882SGreg Clayton                                             {
22551b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
22561b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
22571b654882SGreg Clayton                                                 {
22581b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
22591b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
22601b654882SGreg Clayton                                                     if (reg_info)
22611b654882SGreg Clayton                                                         var_success = true;
22621b654882SGreg Clayton                                                 }
22631b654882SGreg Clayton                                             }
22641b654882SGreg Clayton                                         }
22650769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2266aad8e480SEnrico Granata                                         {
2267aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2268aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2269aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
22700769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2271aad8e480SEnrico Granata                                                 var_success = true;
2272aad8e480SEnrico Granata                                         }
2273aad8e480SEnrico Granata                                     }
2274aad8e480SEnrico Granata                                 }
22751b654882SGreg Clayton                             }
22760769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "function."))
22771b654882SGreg Clayton                             {
22781b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
22791b654882SGreg Clayton                                 {
22801b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
22810769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "id}"))
22821b654882SGreg Clayton                                     {
22831b654882SGreg Clayton                                         if (sc->function)
2284d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
22851b654882SGreg Clayton                                         else
22861b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
22871b654882SGreg Clayton 
22881b654882SGreg Clayton                                         var_success = true;
22891b654882SGreg Clayton                                     }
22900769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name}"))
22911b654882SGreg Clayton                                     {
22921b654882SGreg Clayton                                         if (sc->function)
22931b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
22941b654882SGreg Clayton                                         else if (sc->symbol)
22951b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
22961b654882SGreg Clayton                                         if (cstr)
22971b654882SGreg Clayton                                         {
22981b654882SGreg Clayton                                             s.PutCString(cstr);
22990d9c9934SGreg Clayton 
23000d9c9934SGreg Clayton                                             if (sc->block)
23010d9c9934SGreg Clayton                                             {
23020d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
23030d9c9934SGreg Clayton                                                 if (inline_block)
23040d9c9934SGreg Clayton                                                 {
23050d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
23060d9c9934SGreg Clayton                                                     if (inline_info)
23070d9c9934SGreg Clayton                                                     {
23080d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
23090d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
23100d9c9934SGreg Clayton                                                     }
23110d9c9934SGreg Clayton                                                 }
23120d9c9934SGreg Clayton                                             }
23131b654882SGreg Clayton                                             var_success = true;
23141b654882SGreg Clayton                                         }
23151b654882SGreg Clayton                                     }
23160769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name-with-args}"))
23176d3dbf51SGreg Clayton                                     {
23186d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
23196d3dbf51SGreg Clayton 
23206d3dbf51SGreg Clayton                                         if (sc->function)
23216d3dbf51SGreg Clayton                                         {
23226d3dbf51SGreg Clayton                                             var_success = true;
23236d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
23246d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
23256d3dbf51SGreg Clayton                                             if (cstr)
23266d3dbf51SGreg Clayton                                             {
23276d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
23286d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
23296d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
23306d3dbf51SGreg Clayton                                                 if (sc->block)
23316d3dbf51SGreg Clayton                                                 {
23326d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
23336d3dbf51SGreg Clayton 
23346d3dbf51SGreg Clayton                                                     if (inline_block)
23356d3dbf51SGreg Clayton                                                     {
23366d3dbf51SGreg Clayton                                                         get_function_vars = false;
23376d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
23386d3dbf51SGreg Clayton                                                         if (inline_info)
23396d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
23406d3dbf51SGreg Clayton                                                     }
23416d3dbf51SGreg Clayton                                                 }
23426d3dbf51SGreg Clayton 
23436d3dbf51SGreg Clayton                                                 if (get_function_vars)
23446d3dbf51SGreg Clayton                                                 {
23456d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
23466d3dbf51SGreg Clayton                                                 }
23476d3dbf51SGreg Clayton 
23486d3dbf51SGreg Clayton                                                 if (inline_info)
23496d3dbf51SGreg Clayton                                                 {
23506d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
23516d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
23526d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
23536d3dbf51SGreg Clayton                                                 }
23546d3dbf51SGreg Clayton 
23556d3dbf51SGreg Clayton                                                 VariableList args;
23566d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2357cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
23586d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
23596d3dbf51SGreg Clayton                                                 {
23606d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
2361*e4a4f5d5SEnrico Granata                                                     const char *close_paren = nullptr;
2362*e4a4f5d5SEnrico Granata                                                     const char *generic = strchr(cstr, '<');
2363*e4a4f5d5SEnrico Granata                                                     // if before the arguments list begins there is a template sign
2364*e4a4f5d5SEnrico Granata                                                     // then scan to the end of the generic args before you try to find
2365*e4a4f5d5SEnrico Granata                                                     // the arguments list
2366*e4a4f5d5SEnrico Granata                                                     if (generic && open_paren && generic < open_paren)
2367*e4a4f5d5SEnrico Granata                                                     {
2368*e4a4f5d5SEnrico Granata                                                         int generic_depth = 1;
2369*e4a4f5d5SEnrico Granata                                                         ++generic;
2370*e4a4f5d5SEnrico Granata                                                         for (;
2371*e4a4f5d5SEnrico Granata                                                              *generic && generic_depth > 0;
2372*e4a4f5d5SEnrico Granata                                                              generic++)
2373*e4a4f5d5SEnrico Granata                                                         {
2374*e4a4f5d5SEnrico Granata                                                             if (*generic == '<')
2375*e4a4f5d5SEnrico Granata                                                                 generic_depth++;
2376*e4a4f5d5SEnrico Granata                                                             if (*generic == '>')
2377*e4a4f5d5SEnrico Granata                                                                 generic_depth--;
2378*e4a4f5d5SEnrico Granata                                                         }
2379*e4a4f5d5SEnrico Granata                                                         if (*generic)
2380*e4a4f5d5SEnrico Granata                                                             open_paren = strchr(generic, '(');
2381*e4a4f5d5SEnrico Granata                                                         else
2382*e4a4f5d5SEnrico Granata                                                             open_paren = nullptr;
2383*e4a4f5d5SEnrico Granata                                                     }
23846d3dbf51SGreg Clayton                                                     if (open_paren)
2385855958caSGreg Clayton                                                     {
23860769b2b1SMichael Sartain                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2387855958caSGreg Clayton                                                         {
2388855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2389855958caSGreg Clayton                                                             if (open_paren)
23906d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2391855958caSGreg Clayton                                                         }
2392855958caSGreg Clayton                                                         else
2393855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2394855958caSGreg Clayton                                                     }
23956d3dbf51SGreg Clayton 
23966d3dbf51SGreg Clayton                                                     if (open_paren)
23976d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
23986d3dbf51SGreg Clayton                                                     else
23996d3dbf51SGreg Clayton                                                     {
24006d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
24016d3dbf51SGreg Clayton                                                         s.PutChar ('(');
24026d3dbf51SGreg Clayton                                                     }
24035b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
24046d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
24056d3dbf51SGreg Clayton                                                     {
2406894f7359SEnrico Granata                                                         std::string buffer;
2407894f7359SEnrico Granata 
24086d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
24096d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2410894f7359SEnrico Granata                                                         const char *var_representation = nullptr;
24116d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
2412894f7359SEnrico Granata                                                         if (var_value_sp->GetClangType().IsAggregateType() &&
2413894f7359SEnrico Granata                                                             DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
2414894f7359SEnrico Granata                                                         {
2415894f7359SEnrico Granata                                                             static StringSummaryFormat format(TypeSummaryImpl::Flags()
2416894f7359SEnrico Granata                                                                                               .SetHideItemNames(false)
2417894f7359SEnrico Granata                                                                                               .SetShowMembersOneLiner(true),
2418894f7359SEnrico Granata                                                                                               "");
2419894f7359SEnrico Granata                                                             format.FormatObject(var_value_sp.get(), buffer);
2420894f7359SEnrico Granata                                                             var_representation = buffer.c_str();
2421894f7359SEnrico Granata                                                         }
2422894f7359SEnrico Granata                                                         else
2423894f7359SEnrico Granata                                                             var_representation = var_value_sp->GetValueAsCString();
24246d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
24256d3dbf51SGreg Clayton                                                             s.PutCString (", ");
24263b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2427cc7f9bf5SEnrico Granata                                                         {
2428894f7359SEnrico Granata                                                             if (var_representation)
2429894f7359SEnrico Granata                                                                 s.Printf ("%s=%s", var_name, var_representation);
24303b188b17SGreg Clayton                                                             else
2431cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2432cc7f9bf5SEnrico Granata                                                         }
2433cc7f9bf5SEnrico Granata                                                         else
24343b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
24356d3dbf51SGreg Clayton                                                     }
24366d3dbf51SGreg Clayton 
24376d3dbf51SGreg Clayton                                                     if (close_paren)
24386d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
24396d3dbf51SGreg Clayton                                                     else
24406d3dbf51SGreg Clayton                                                         s.PutChar(')');
24416d3dbf51SGreg Clayton 
24426d3dbf51SGreg Clayton                                                 }
24436d3dbf51SGreg Clayton                                                 else
24446d3dbf51SGreg Clayton                                                 {
24456d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
24466d3dbf51SGreg Clayton                                                 }
24476d3dbf51SGreg Clayton                                             }
24486d3dbf51SGreg Clayton                                         }
24496d3dbf51SGreg Clayton                                         else if (sc->symbol)
24506d3dbf51SGreg Clayton                                         {
24516d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
24526d3dbf51SGreg Clayton                                             if (cstr)
24536d3dbf51SGreg Clayton                                             {
24546d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
24556d3dbf51SGreg Clayton                                                 var_success = true;
24566d3dbf51SGreg Clayton                                             }
24576d3dbf51SGreg Clayton                                         }
24586d3dbf51SGreg Clayton                                     }
24590769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "addr-offset}"))
24601b654882SGreg Clayton                                     {
24611b654882SGreg Clayton                                         var_success = addr != NULL;
24621b654882SGreg Clayton                                         if (var_success)
24631b654882SGreg Clayton                                         {
24641b654882SGreg Clayton                                             format_addr = *addr;
24651b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
24661b654882SGreg Clayton                                         }
24671b654882SGreg Clayton                                     }
24680769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "line-offset}"))
24691b654882SGreg Clayton                                     {
24701b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
24711b654882SGreg Clayton                                         if (var_success)
24721b654882SGreg Clayton                                         {
24731b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
24741b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
24751b654882SGreg Clayton                                         }
24761b654882SGreg Clayton                                     }
24770769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "pc-offset}"))
24781b654882SGreg Clayton                                     {
2479b57e4a1bSJason Molenda                                         StackFrame *frame = exe_ctx->GetFramePtr();
2480c14ee32dSGreg Clayton                                         var_success = frame != NULL;
24811b654882SGreg Clayton                                         if (var_success)
24821b654882SGreg Clayton                                         {
2483c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
24841b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
24851b654882SGreg Clayton                                         }
24861b654882SGreg Clayton                                     }
24871b654882SGreg Clayton                                 }
24881b654882SGreg Clayton                             }
24891b654882SGreg Clayton                             break;
24901b654882SGreg Clayton 
24911b654882SGreg Clayton                         case 'l':
24920769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "line."))
24931b654882SGreg Clayton                             {
24941b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
24951b654882SGreg Clayton                                 {
24961b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
24970769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
24981b654882SGreg Clayton                                     {
24991b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
25001b654882SGreg Clayton 
25010769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "basename}"))
25021b654882SGreg Clayton                                         {
25031b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
25049076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25051b654882SGreg Clayton                                         }
25060769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fullpath}"))
25071b654882SGreg Clayton                                         {
25081b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
25099076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25101b654882SGreg Clayton                                         }
25111b654882SGreg Clayton                                     }
25120769b2b1SMichael Sartain                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
25131b654882SGreg Clayton                                     {
25141b654882SGreg Clayton                                         var_success = true;
25150769b2b1SMichael Sartain                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
25161b654882SGreg Clayton                                     }
25170769b2b1SMichael Sartain                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
25180769b2b1SMichael Sartain                                              (IsToken (var_name_begin, "end-addr}")))
25191b654882SGreg Clayton                                     {
25201b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
25211b654882SGreg Clayton                                         if (var_success)
25221b654882SGreg Clayton                                         {
25231b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
25241b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
25251b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
25261b654882SGreg Clayton                                         }
25271b654882SGreg Clayton                                     }
25281b654882SGreg Clayton                                 }
25291b654882SGreg Clayton                             }
25301b654882SGreg Clayton                             break;
25311b654882SGreg Clayton                         }
25321b654882SGreg Clayton 
25331b654882SGreg Clayton                         if (var_success)
25341b654882SGreg Clayton                         {
25351b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
25361b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
25371b654882SGreg Clayton                             {
2538b57e4a1bSJason Molenda                                 StackFrame *frame = exe_ctx->GetFramePtr();
25391b654882SGreg Clayton                                 // We have a register value to display...
25401b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
25411b654882SGreg Clayton                                 {
2542c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
25431b654882SGreg Clayton                                 }
25441b654882SGreg Clayton                                 else
25451b654882SGreg Clayton                                 {
25461b654882SGreg Clayton                                     if (reg_ctx == NULL)
2547c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
25481b654882SGreg Clayton 
25491b654882SGreg Clayton                                     if (reg_ctx)
25501b654882SGreg Clayton                                     {
25511b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
25521b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
25531b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
25541b654882SGreg Clayton                                         var_success = reg_info != NULL;
25551b654882SGreg Clayton                                     }
25561b654882SGreg Clayton                                 }
25571b654882SGreg Clayton                             }
25581b654882SGreg Clayton 
25591b654882SGreg Clayton                             if (reg_info != NULL)
25601b654882SGreg Clayton                             {
25617349bd90SGreg Clayton                                 RegisterValue reg_value;
25627349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
25637349bd90SGreg Clayton                                 if (var_success)
25641b654882SGreg Clayton                                 {
25659a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
25661b654882SGreg Clayton                                 }
25671b654882SGreg Clayton                             }
25681b654882SGreg Clayton 
25691b654882SGreg Clayton                             if (format_file_spec)
25701b654882SGreg Clayton                             {
25711b654882SGreg Clayton                                 s << format_file_spec;
25721b654882SGreg Clayton                             }
25731b654882SGreg Clayton 
25741b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
25751b654882SGreg Clayton                             if (format_addr.IsValid())
25761b654882SGreg Clayton                             {
25770603aa9dSGreg Clayton                                 var_success = false;
25780603aa9dSGreg Clayton 
25791b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
25801b654882SGreg Clayton                                 {
25811b654882SGreg Clayton                                     Address func_addr;
25820603aa9dSGreg Clayton 
25830603aa9dSGreg Clayton                                     if (sc)
25840603aa9dSGreg Clayton                                     {
25851b654882SGreg Clayton                                         if (sc->function)
25860d9c9934SGreg Clayton                                         {
25871b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
25880d9c9934SGreg Clayton                                             if (sc->block)
25890d9c9934SGreg Clayton                                             {
25900d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
25910d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
25920d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
25930d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
25940d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
25950d9c9934SGreg Clayton                                                 AddressRange inline_range;
25960d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
25970d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
25980d9c9934SGreg Clayton                                             }
25990d9c9934SGreg Clayton                                         }
2600e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2601e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
26020603aa9dSGreg Clayton                                     }
26031b654882SGreg Clayton 
26040603aa9dSGreg Clayton                                     if (func_addr.IsValid())
26051b654882SGreg Clayton                                     {
26061b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
26071b654882SGreg Clayton                                         {
26081b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
26091b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
26101b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2611d01b2953SDaniel Malea                                                 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
26121b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2613d01b2953SDaniel Malea                                                 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
26140603aa9dSGreg Clayton                                             var_success = true;
26151b654882SGreg Clayton                                         }
26161b654882SGreg Clayton                                         else
26170603aa9dSGreg Clayton                                         {
26180603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
26190603aa9dSGreg Clayton                                             if (target)
26200603aa9dSGreg Clayton                                             {
26210603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
26220603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
26230603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2624d01b2953SDaniel Malea                                                     s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
26250603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2626d01b2953SDaniel Malea                                                     s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
26270603aa9dSGreg Clayton                                                 var_success = true;
26280603aa9dSGreg Clayton                                             }
26290603aa9dSGreg Clayton                                         }
26301b654882SGreg Clayton                                     }
26311b654882SGreg Clayton                                 }
26321b654882SGreg Clayton                                 else
26331b654882SGreg Clayton                                 {
26340603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
26351b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
26360603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
26370603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
26381b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
26391b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
26401b654882SGreg Clayton 
26411b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
26420603aa9dSGreg Clayton                                     {
2643514487e8SGreg Clayton                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
264435f1a0d5SGreg Clayton                                         if (addr_width == 0)
264535f1a0d5SGreg Clayton                                             addr_width = 16;
2646d01b2953SDaniel Malea                                         s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
26470603aa9dSGreg Clayton                                         var_success = true;
26480603aa9dSGreg Clayton                                     }
26491b654882SGreg Clayton                                 }
26501b654882SGreg Clayton                             }
26511b654882SGreg Clayton                         }
26521b654882SGreg Clayton 
26531b654882SGreg Clayton                         if (var_success == false)
26541b654882SGreg Clayton                             success = false;
26551b654882SGreg Clayton                     }
26561b654882SGreg Clayton                     p = var_name_end;
26571b654882SGreg Clayton                 }
26581b654882SGreg Clayton                 else
26591b654882SGreg Clayton                     break;
26601b654882SGreg Clayton             }
26611b654882SGreg Clayton             else
26621b654882SGreg Clayton             {
26631b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
26641b654882SGreg Clayton                 s.PutChar(*p);
26651b654882SGreg Clayton             }
26661b654882SGreg Clayton         }
26671b654882SGreg Clayton         else if (*p == '\\')
26681b654882SGreg Clayton         {
26691b654882SGreg Clayton             ++p; // skip the slash
26701b654882SGreg Clayton             switch (*p)
26711b654882SGreg Clayton             {
26721b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
26731b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
26741b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
26751b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
26761b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
26771b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
26781b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
26791b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
26801b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
26811b654882SGreg Clayton             case '0':
26821b654882SGreg Clayton                 // 1 to 3 octal chars
26831b654882SGreg Clayton                 {
26840603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
26850603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
26860603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
26870603aa9dSGreg Clayton 
26880603aa9dSGreg Clayton                     int i;
26890603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
26900603aa9dSGreg Clayton                         oct_str[i] = p[i];
26910603aa9dSGreg Clayton 
26920603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
26930603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
26940603aa9dSGreg Clayton                     // one less than i (even if i is zero)
26950603aa9dSGreg Clayton                     p += i - 1;
26960603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
26970603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
26981b654882SGreg Clayton                     {
2699c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
27001b654882SGreg Clayton                     }
27011b654882SGreg Clayton                 }
27021b654882SGreg Clayton                 break;
27031b654882SGreg Clayton 
27041b654882SGreg Clayton             case 'x':
27051b654882SGreg Clayton                 // hex number in the format
27060603aa9dSGreg Clayton                 if (isxdigit(p[1]))
27071b654882SGreg Clayton                 {
27080603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
27091b654882SGreg Clayton 
27100603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
27110603aa9dSGreg Clayton                     // NULL terminator
27121b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
27131b654882SGreg Clayton                     hex_str[0] = *p;
27140603aa9dSGreg Clayton                     if (isxdigit(p[1]))
27150603aa9dSGreg Clayton                     {
27160603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
27171b654882SGreg Clayton                         hex_str[1] = *p;
27180603aa9dSGreg Clayton                     }
27190603aa9dSGreg Clayton 
27201b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
27210603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2722c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
27231b654882SGreg Clayton                 }
27241b654882SGreg Clayton                 else
27251b654882SGreg Clayton                 {
27260603aa9dSGreg Clayton                     s.PutChar('x');
27271b654882SGreg Clayton                 }
27281b654882SGreg Clayton                 break;
27291b654882SGreg Clayton 
27301b654882SGreg Clayton             default:
27310603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
27320603aa9dSGreg Clayton                 // came after the '\'
27330603aa9dSGreg Clayton                 s << *p;
27341b654882SGreg Clayton                 break;
27351b654882SGreg Clayton 
27361b654882SGreg Clayton             }
27371b654882SGreg Clayton 
27381b654882SGreg Clayton         }
27391b654882SGreg Clayton     }
27401b654882SGreg Clayton     if (end)
27411b654882SGreg Clayton         *end = p;
27421b654882SGreg Clayton     return success;
27431b654882SGreg Clayton }
27441b654882SGreg Clayton 
2745c3ce7f27SMichael Sartain bool
2746c3ce7f27SMichael Sartain Debugger::FormatPrompt
2747c3ce7f27SMichael Sartain (
2748c3ce7f27SMichael Sartain     const char *format,
2749c3ce7f27SMichael Sartain     const SymbolContext *sc,
2750c3ce7f27SMichael Sartain     const ExecutionContext *exe_ctx,
2751c3ce7f27SMichael Sartain     const Address *addr,
2752c3ce7f27SMichael Sartain     Stream &s,
2753c3ce7f27SMichael Sartain     ValueObject* valobj
2754c3ce7f27SMichael Sartain )
2755c3ce7f27SMichael Sartain {
2756c3ce7f27SMichael Sartain     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2757c3ce7f27SMichael Sartain     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2758c3ce7f27SMichael Sartain     if (format_str.length())
2759c3ce7f27SMichael Sartain         format = format_str.c_str();
2760c3ce7f27SMichael Sartain     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj);
2761c3ce7f27SMichael Sartain }
2762c3ce7f27SMichael Sartain 
2763228063cdSJim Ingham void
2764228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2765228063cdSJim Ingham {
27664f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
27674f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
27684f02b22dSJim Ingham     // callback.
2769228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2770228063cdSJim Ingham }
2771228063cdSJim Ingham 
2772228063cdSJim Ingham bool
2773228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2774228063cdSJim Ingham {
2775228063cdSJim Ingham     Log::Callbacks log_callbacks;
2776228063cdSJim Ingham 
2777228063cdSJim Ingham     StreamSP log_stream_sp;
27789a028519SSean Callanan     if (m_log_callback_stream_sp)
2779228063cdSJim Ingham     {
2780228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2781228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2782228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2783228063cdSJim Ingham     }
2784228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2785228063cdSJim Ingham     {
278644d93782SGreg Clayton         log_stream_sp = GetOutputFile();
2787228063cdSJim Ingham     }
2788228063cdSJim Ingham     else
2789228063cdSJim Ingham     {
2790228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2791c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2792c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2793c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2794228063cdSJim Ingham         {
2795228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2796228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2797228063cdSJim Ingham         }
2798228063cdSJim Ingham     }
2799228063cdSJim Ingham     assert (log_stream_sp.get());
2800228063cdSJim Ingham 
2801228063cdSJim Ingham     if (log_options == 0)
2802228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2803228063cdSJim Ingham 
280457abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2805228063cdSJim Ingham     {
2806228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2807228063cdSJim Ingham         return true;
2808228063cdSJim Ingham     }
2809228063cdSJim Ingham     else
2810228063cdSJim Ingham     {
2811228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2812228063cdSJim Ingham         if (log_channel_sp)
2813228063cdSJim Ingham         {
2814228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2815228063cdSJim Ingham             {
2816228063cdSJim Ingham                 return true;
2817228063cdSJim Ingham             }
2818228063cdSJim Ingham             else
2819228063cdSJim Ingham             {
2820228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2821228063cdSJim Ingham                 return false;
2822228063cdSJim Ingham             }
2823228063cdSJim Ingham         }
2824228063cdSJim Ingham         else
2825228063cdSJim Ingham         {
2826228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2827228063cdSJim Ingham             return false;
2828228063cdSJim Ingham         }
2829228063cdSJim Ingham     }
2830228063cdSJim Ingham     return false;
2831228063cdSJim Ingham }
2832228063cdSJim Ingham 
28339585fbfcSGreg Clayton SourceManager &
28349585fbfcSGreg Clayton Debugger::GetSourceManager ()
28359585fbfcSGreg Clayton {
28369585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
28379585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
28389585fbfcSGreg Clayton     return *m_source_manager_ap;
28399585fbfcSGreg Clayton }
28409585fbfcSGreg Clayton 
28419585fbfcSGreg Clayton 
284244d93782SGreg Clayton 
284344d93782SGreg Clayton // This function handles events that were broadcast by the process.
284444d93782SGreg Clayton void
284544d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
284644d93782SGreg Clayton {
284744d93782SGreg Clayton     using namespace lldb;
284844d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
284944d93782SGreg Clayton 
285044d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
285144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
285244d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
285344d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
285444d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
285544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
285644d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
285744d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
285844d93782SGreg Clayton //    {
285944d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
286044d93782SGreg Clayton //    }
286144d93782SGreg Clayton //
286244d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
286344d93782SGreg Clayton     {
286444d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
286544d93782SGreg Clayton         if (num_new_locations > 0)
286644d93782SGreg Clayton         {
286744d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
286844d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
286944d93782SGreg Clayton             if (output_sp)
287044d93782SGreg Clayton             {
287144d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
287244d93782SGreg Clayton                                   num_new_locations,
287344d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
287444d93782SGreg Clayton                                   breakpoint->GetID());
287544d93782SGreg Clayton                 RefreshTopIOHandler();
287644d93782SGreg Clayton             }
287744d93782SGreg Clayton         }
287844d93782SGreg Clayton     }
287944d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
288044d93782SGreg Clayton //    {
288144d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
288244d93782SGreg Clayton //    }
288344d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
288444d93782SGreg Clayton //    {
288544d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
288644d93782SGreg Clayton //    }
288744d93782SGreg Clayton }
288844d93782SGreg Clayton 
288944d93782SGreg Clayton size_t
289044d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
289144d93782SGreg Clayton {
289244d93782SGreg Clayton     size_t total_bytes = 0;
289344d93782SGreg Clayton     if (stream == NULL)
289444d93782SGreg Clayton         stream = GetOutputFile().get();
289544d93782SGreg Clayton 
289644d93782SGreg Clayton     if (stream)
289744d93782SGreg Clayton     {
289844d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
289944d93782SGreg Clayton         if (process == NULL)
290044d93782SGreg Clayton         {
290144d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
290244d93782SGreg Clayton             if (target_sp)
290344d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
290444d93782SGreg Clayton         }
290544d93782SGreg Clayton         if (process)
290644d93782SGreg Clayton         {
290744d93782SGreg Clayton             Error error;
290844d93782SGreg Clayton             size_t len;
290944d93782SGreg Clayton             char stdio_buffer[1024];
291044d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
291144d93782SGreg Clayton             {
291244d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
291344d93782SGreg Clayton                 total_bytes += len;
291444d93782SGreg Clayton             }
291544d93782SGreg Clayton         }
291644d93782SGreg Clayton         stream->Flush();
291744d93782SGreg Clayton     }
291844d93782SGreg Clayton     return total_bytes;
291944d93782SGreg Clayton }
292044d93782SGreg Clayton 
292144d93782SGreg Clayton size_t
292244d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
292344d93782SGreg Clayton {
292444d93782SGreg Clayton     size_t total_bytes = 0;
292544d93782SGreg Clayton     if (stream == NULL)
292644d93782SGreg Clayton         stream = GetOutputFile().get();
292744d93782SGreg Clayton 
292844d93782SGreg Clayton     if (stream)
292944d93782SGreg Clayton     {
293044d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
293144d93782SGreg Clayton         if (process == NULL)
293244d93782SGreg Clayton         {
293344d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
293444d93782SGreg Clayton             if (target_sp)
293544d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
293644d93782SGreg Clayton         }
293744d93782SGreg Clayton         if (process)
293844d93782SGreg Clayton         {
293944d93782SGreg Clayton             Error error;
294044d93782SGreg Clayton             size_t len;
294144d93782SGreg Clayton             char stdio_buffer[1024];
294244d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
294344d93782SGreg Clayton             {
294444d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
294544d93782SGreg Clayton                 total_bytes += len;
294644d93782SGreg Clayton             }
294744d93782SGreg Clayton         }
294844d93782SGreg Clayton         stream->Flush();
294944d93782SGreg Clayton     }
295044d93782SGreg Clayton     return total_bytes;
295144d93782SGreg Clayton }
295244d93782SGreg Clayton 
295344d93782SGreg Clayton // This function handles events that were broadcast by the process.
295444d93782SGreg Clayton void
295544d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
295644d93782SGreg Clayton {
295744d93782SGreg Clayton     using namespace lldb;
295844d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
295944d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
296044d93782SGreg Clayton 
2961b4874f1aSGreg Clayton     StreamString output_stream;
2962b4874f1aSGreg Clayton     StreamString error_stream;
296344d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
296444d93782SGreg Clayton 
2965b4874f1aSGreg Clayton     if (!gui_enabled)
2966b4874f1aSGreg Clayton     {
2967b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
296844d93782SGreg Clayton         assert (process_sp);
296944d93782SGreg Clayton 
2970b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
297144d93782SGreg Clayton         {
2972b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
297344d93782SGreg Clayton         }
2974b4874f1aSGreg Clayton 
2975b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
297644d93782SGreg Clayton         {
2977b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
297844d93782SGreg Clayton         }
2979b4874f1aSGreg Clayton 
2980b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
298144d93782SGreg Clayton         {
2982b4874f1aSGreg Clayton 
298344d93782SGreg Clayton             // Drain all stout and stderr so we don't see any output come after
298444d93782SGreg Clayton             // we print our prompts
298544d93782SGreg Clayton             // Something changed in the process;  get the event and report the process's current status and location to
298644d93782SGreg Clayton             // the user.
298744d93782SGreg Clayton             StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
298844d93782SGreg Clayton             if (event_state == eStateInvalid)
298944d93782SGreg Clayton                 return;
299044d93782SGreg Clayton 
299144d93782SGreg Clayton             switch (event_state)
299244d93782SGreg Clayton             {
299344d93782SGreg Clayton                 case eStateInvalid:
299444d93782SGreg Clayton                 case eStateUnloaded:
299544d93782SGreg Clayton                 case eStateConnected:
299644d93782SGreg Clayton                 case eStateAttaching:
299744d93782SGreg Clayton                 case eStateLaunching:
299844d93782SGreg Clayton                 case eStateStepping:
299944d93782SGreg Clayton                 case eStateDetached:
300044d93782SGreg Clayton                     {
3001b4874f1aSGreg Clayton                         output_stream.Printf("Process %" PRIu64 " %s\n",
300244d93782SGreg Clayton                                              process_sp->GetID(),
300344d93782SGreg Clayton                                              StateAsCString (event_state));
3004b4874f1aSGreg Clayton 
3005b4874f1aSGreg Clayton                         if (event_state == eStateDetached)
3006b4874f1aSGreg Clayton                             pop_process_io_handler = true;
300744d93782SGreg Clayton                     }
300844d93782SGreg Clayton                     break;
300944d93782SGreg Clayton 
301044d93782SGreg Clayton                 case eStateRunning:
301144d93782SGreg Clayton                     // Don't be chatty when we run...
301244d93782SGreg Clayton                     break;
301344d93782SGreg Clayton 
301444d93782SGreg Clayton                 case eStateExited:
3015b4874f1aSGreg Clayton                     process_sp->GetStatus(output_stream);
3016b4874f1aSGreg Clayton                     pop_process_io_handler = true;
301744d93782SGreg Clayton                     break;
301844d93782SGreg Clayton 
301944d93782SGreg Clayton                 case eStateStopped:
302044d93782SGreg Clayton                 case eStateCrashed:
302144d93782SGreg Clayton                 case eStateSuspended:
302244d93782SGreg Clayton                     // Make sure the program hasn't been auto-restarted:
302344d93782SGreg Clayton                     if (Process::ProcessEventData::GetRestartedFromEvent (event_sp.get()))
302444d93782SGreg Clayton                     {
302544d93782SGreg Clayton                         size_t num_reasons = Process::ProcessEventData::GetNumRestartedReasons(event_sp.get());
302644d93782SGreg Clayton                         if (num_reasons > 0)
302744d93782SGreg Clayton                         {
302844d93782SGreg Clayton                             // FIXME: Do we want to report this, or would that just be annoyingly chatty?
302944d93782SGreg Clayton                             if (num_reasons == 1)
303044d93782SGreg Clayton                             {
303144d93782SGreg Clayton                                 const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), 0);
3032b4874f1aSGreg Clayton                                 output_stream.Printf("Process %" PRIu64 " stopped and restarted: %s\n",
303344d93782SGreg Clayton                                                      process_sp->GetID(),
303444d93782SGreg Clayton                                                      reason ? reason : "<UNKNOWN REASON>");
303544d93782SGreg Clayton                             }
303644d93782SGreg Clayton                             else
303744d93782SGreg Clayton                             {
3038b4874f1aSGreg Clayton                                 output_stream.Printf("Process %" PRIu64 " stopped and restarted, reasons:\n",
303944d93782SGreg Clayton                                                      process_sp->GetID());
304044d93782SGreg Clayton 
304144d93782SGreg Clayton 
304244d93782SGreg Clayton                                 for (size_t i = 0; i < num_reasons; i++)
304344d93782SGreg Clayton                                 {
304444d93782SGreg Clayton                                     const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), i);
3045b4874f1aSGreg Clayton                                     output_stream.Printf("\t%s\n", reason ? reason : "<UNKNOWN REASON>");
304644d93782SGreg Clayton                                 }
304744d93782SGreg Clayton                             }
304844d93782SGreg Clayton                         }
304944d93782SGreg Clayton                     }
305044d93782SGreg Clayton                     else
305144d93782SGreg Clayton                     {
30524a65fb1fSJim Ingham                         // Lock the thread list so it doesn't change on us, this is the scope for the locker:
30534a65fb1fSJim Ingham                         {
305444d93782SGreg Clayton                             ThreadList &thread_list = process_sp->GetThreadList();
305544d93782SGreg Clayton                             Mutex::Locker locker (thread_list.GetMutex());
305644d93782SGreg Clayton 
305744d93782SGreg Clayton                             ThreadSP curr_thread (thread_list.GetSelectedThread());
305844d93782SGreg Clayton                             ThreadSP thread;
305944d93782SGreg Clayton                             StopReason curr_thread_stop_reason = eStopReasonInvalid;
306044d93782SGreg Clayton                             if (curr_thread)
306144d93782SGreg Clayton                                 curr_thread_stop_reason = curr_thread->GetStopReason();
3062c809cbcfSGreg Clayton                             if (!curr_thread ||
3063c809cbcfSGreg Clayton                                 !curr_thread->IsValid() ||
306444d93782SGreg Clayton                                 curr_thread_stop_reason == eStopReasonInvalid ||
306544d93782SGreg Clayton                                 curr_thread_stop_reason == eStopReasonNone)
306644d93782SGreg Clayton                             {
306744d93782SGreg Clayton                                 // Prefer a thread that has just completed its plan over another thread as current thread.
306844d93782SGreg Clayton                                 ThreadSP plan_thread;
306944d93782SGreg Clayton                                 ThreadSP other_thread;
307044d93782SGreg Clayton                                 const size_t num_threads = thread_list.GetSize();
307144d93782SGreg Clayton                                 size_t i;
307244d93782SGreg Clayton                                 for (i = 0; i < num_threads; ++i)
307344d93782SGreg Clayton                                 {
307444d93782SGreg Clayton                                     thread = thread_list.GetThreadAtIndex(i);
307544d93782SGreg Clayton                                     StopReason thread_stop_reason = thread->GetStopReason();
307644d93782SGreg Clayton                                     switch (thread_stop_reason)
307744d93782SGreg Clayton                                     {
307844d93782SGreg Clayton                                         case eStopReasonInvalid:
307944d93782SGreg Clayton                                         case eStopReasonNone:
308044d93782SGreg Clayton                                             break;
308144d93782SGreg Clayton 
308244d93782SGreg Clayton                                         case eStopReasonTrace:
308344d93782SGreg Clayton                                         case eStopReasonBreakpoint:
308444d93782SGreg Clayton                                         case eStopReasonWatchpoint:
308544d93782SGreg Clayton                                         case eStopReasonSignal:
308644d93782SGreg Clayton                                         case eStopReasonException:
308744d93782SGreg Clayton                                         case eStopReasonExec:
308844d93782SGreg Clayton                                         case eStopReasonThreadExiting:
308944d93782SGreg Clayton                                             if (!other_thread)
309044d93782SGreg Clayton                                                 other_thread = thread;
309144d93782SGreg Clayton                                             break;
309244d93782SGreg Clayton                                         case eStopReasonPlanComplete:
309344d93782SGreg Clayton                                             if (!plan_thread)
309444d93782SGreg Clayton                                                 plan_thread = thread;
309544d93782SGreg Clayton                                             break;
309644d93782SGreg Clayton                                     }
309744d93782SGreg Clayton                                 }
309844d93782SGreg Clayton                                 if (plan_thread)
309944d93782SGreg Clayton                                     thread_list.SetSelectedThreadByID (plan_thread->GetID());
310044d93782SGreg Clayton                                 else if (other_thread)
310144d93782SGreg Clayton                                     thread_list.SetSelectedThreadByID (other_thread->GetID());
310244d93782SGreg Clayton                                 else
310344d93782SGreg Clayton                                 {
31044046a30cSJim Ingham                                     if (curr_thread && curr_thread->IsValid())
310544d93782SGreg Clayton                                         thread = curr_thread;
310644d93782SGreg Clayton                                     else
310744d93782SGreg Clayton                                         thread = thread_list.GetThreadAtIndex(0);
310844d93782SGreg Clayton 
310944d93782SGreg Clayton                                     if (thread)
311044d93782SGreg Clayton                                         thread_list.SetSelectedThreadByID (thread->GetID());
311144d93782SGreg Clayton                                 }
311244d93782SGreg Clayton                             }
31134a65fb1fSJim Ingham                         }
31144a65fb1fSJim Ingham                         // Drop the ThreadList mutex by here, since GetThreadStatus below might have to run code,
31154a65fb1fSJim Ingham                         // e.g. for Data formatters, and if we hold the ThreadList mutex, then the process is going to
31164a65fb1fSJim Ingham                         // have a hard time restarting the process.
311744d93782SGreg Clayton 
311844d93782SGreg Clayton                         if (GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget())
311944d93782SGreg Clayton                         {
312044d93782SGreg Clayton                             const bool only_threads_with_stop_reason = true;
312144d93782SGreg Clayton                             const uint32_t start_frame = 0;
312244d93782SGreg Clayton                             const uint32_t num_frames = 1;
312344d93782SGreg Clayton                             const uint32_t num_frames_with_source = 1;
3124b4874f1aSGreg Clayton                             process_sp->GetStatus(output_stream);
3125b4874f1aSGreg Clayton                             process_sp->GetThreadStatus (output_stream,
312644d93782SGreg Clayton                                                          only_threads_with_stop_reason,
312744d93782SGreg Clayton                                                          start_frame,
312844d93782SGreg Clayton                                                          num_frames,
312944d93782SGreg Clayton                                                          num_frames_with_source);
313044d93782SGreg Clayton                         }
313144d93782SGreg Clayton                         else
313244d93782SGreg Clayton                         {
313344d93782SGreg Clayton                             uint32_t target_idx = GetTargetList().GetIndexOfTarget(process_sp->GetTarget().shared_from_this());
313444d93782SGreg Clayton                             if (target_idx != UINT32_MAX)
3135b4874f1aSGreg Clayton                                 output_stream.Printf ("Target %d: (", target_idx);
313644d93782SGreg Clayton                             else
3137b4874f1aSGreg Clayton                                 output_stream.Printf ("Target <unknown index>: (");
3138b4874f1aSGreg Clayton                             process_sp->GetTarget().Dump (&output_stream, eDescriptionLevelBrief);
3139b4874f1aSGreg Clayton                             output_stream.Printf (") stopped.\n");
314044d93782SGreg Clayton                         }
3141b4874f1aSGreg Clayton 
3142b4874f1aSGreg Clayton                         // Pop the process IO handler
3143b4874f1aSGreg Clayton                         pop_process_io_handler = true;
314444d93782SGreg Clayton                     }
314544d93782SGreg Clayton                     break;
314644d93782SGreg Clayton             }
314744d93782SGreg Clayton         }
3148b4874f1aSGreg Clayton 
3149b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
3150b4874f1aSGreg Clayton         {
3151b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
31526fea17e8SGreg Clayton             bool top_io_handler_hid = false;
31536fea17e8SGreg Clayton 
31546fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
31556fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
3156b4874f1aSGreg Clayton 
3157b4874f1aSGreg Clayton             if (output_stream.GetSize())
3158b4874f1aSGreg Clayton             {
3159b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
3160b4874f1aSGreg Clayton                 if (output_stream_sp)
3161b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
3162b4874f1aSGreg Clayton             }
3163b4874f1aSGreg Clayton 
3164b4874f1aSGreg Clayton             if (error_stream.GetSize())
3165b4874f1aSGreg Clayton             {
3166b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
3167b4874f1aSGreg Clayton                 if (error_stream_sp)
3168b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
316944d93782SGreg Clayton             }
317044d93782SGreg Clayton 
317144d93782SGreg Clayton             if (top_io_handler_hid)
317244d93782SGreg Clayton                 RefreshTopIOHandler();
317344d93782SGreg Clayton         }
317444d93782SGreg Clayton 
3175b4874f1aSGreg Clayton         if (pop_process_io_handler)
3176b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
3177b4874f1aSGreg Clayton     }
3178b4874f1aSGreg Clayton }
3179b4874f1aSGreg Clayton 
318044d93782SGreg Clayton void
318144d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
318244d93782SGreg Clayton {
318344d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
318444d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
318544d93782SGreg Clayton     using namespace lldb;
318644d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
318744d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
318844d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
318944d93782SGreg Clayton     {
319044d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
319144d93782SGreg Clayton         if (thread_sp)
319244d93782SGreg Clayton         {
319344d93782SGreg Clayton             HideTopIOHandler();
319444d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
319544d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
319644d93782SGreg Clayton             RefreshTopIOHandler();
319744d93782SGreg Clayton         }
319844d93782SGreg Clayton     }
319944d93782SGreg Clayton }
320044d93782SGreg Clayton 
320144d93782SGreg Clayton bool
320244d93782SGreg Clayton Debugger::IsForwardingEvents ()
320344d93782SGreg Clayton {
320444d93782SGreg Clayton     return (bool)m_forward_listener_sp;
320544d93782SGreg Clayton }
320644d93782SGreg Clayton 
320744d93782SGreg Clayton void
320844d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
320944d93782SGreg Clayton {
321044d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
321144d93782SGreg Clayton }
321244d93782SGreg Clayton 
321344d93782SGreg Clayton void
321444d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
321544d93782SGreg Clayton {
321644d93782SGreg Clayton     m_forward_listener_sp.reset();
321744d93782SGreg Clayton }
321844d93782SGreg Clayton 
321944d93782SGreg Clayton 
322044d93782SGreg Clayton void
322144d93782SGreg Clayton Debugger::DefaultEventHandler()
322244d93782SGreg Clayton {
322344d93782SGreg Clayton     Listener& listener(GetListener());
322444d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
322544d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
322644d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
322744d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
322844d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
322944d93782SGreg Clayton 
323044d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
323144d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
323244d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
323344d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
323444d93782SGreg Clayton 
323544d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
323644d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
323744d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
323844d93782SGreg Clayton 
323944d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
324044d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
324144d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
324244d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
324344d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
324444d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
324544d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
324644d93782SGreg Clayton 
324744d93782SGreg Clayton     bool done = false;
324844d93782SGreg Clayton     while (!done)
324944d93782SGreg Clayton     {
325044d93782SGreg Clayton //        Mutex::Locker locker;
325144d93782SGreg Clayton //        if (locker.TryLock(m_input_reader_stack.GetMutex()))
325244d93782SGreg Clayton //        {
325344d93782SGreg Clayton //            if (m_input_reader_stack.IsEmpty())
325444d93782SGreg Clayton //                break;
325544d93782SGreg Clayton //        }
325644d93782SGreg Clayton //
325744d93782SGreg Clayton         EventSP event_sp;
325844d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
325944d93782SGreg Clayton         {
326044d93782SGreg Clayton             if (event_sp)
326144d93782SGreg Clayton             {
326244d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
326344d93782SGreg Clayton                 if (broadcaster)
326444d93782SGreg Clayton                 {
326544d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
326644d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
326744d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
326844d93782SGreg Clayton                     {
326944d93782SGreg Clayton                         HandleProcessEvent (event_sp);
327044d93782SGreg Clayton                     }
327144d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
327244d93782SGreg Clayton                     {
327344d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
327444d93782SGreg Clayton                         {
327544d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
327644d93782SGreg Clayton                         }
327744d93782SGreg Clayton                     }
327844d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
327944d93782SGreg Clayton                     {
328044d93782SGreg Clayton                         HandleThreadEvent (event_sp);
328144d93782SGreg Clayton                     }
328244d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
328344d93782SGreg Clayton                     {
328444d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
328544d93782SGreg Clayton                         {
328644d93782SGreg Clayton                             done = true;
328744d93782SGreg Clayton                         }
328844d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
328944d93782SGreg Clayton                         {
329044d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
329144d93782SGreg Clayton                             if (data && data[0])
329244d93782SGreg Clayton                             {
329344d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
329444d93782SGreg Clayton                                 if (error_sp)
329544d93782SGreg Clayton                                 {
329644d93782SGreg Clayton                                     HideTopIOHandler();
329744d93782SGreg Clayton                                     error_sp->PutCString(data);
329844d93782SGreg Clayton                                     error_sp->Flush();
329944d93782SGreg Clayton                                     RefreshTopIOHandler();
330044d93782SGreg Clayton                                 }
330144d93782SGreg Clayton                             }
330244d93782SGreg Clayton                         }
330344d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
330444d93782SGreg Clayton                         {
330544d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
330644d93782SGreg Clayton                             if (data && data[0])
330744d93782SGreg Clayton                             {
330844d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
330944d93782SGreg Clayton                                 if (output_sp)
331044d93782SGreg Clayton                                 {
331144d93782SGreg Clayton                                     HideTopIOHandler();
331244d93782SGreg Clayton                                     output_sp->PutCString(data);
331344d93782SGreg Clayton                                     output_sp->Flush();
331444d93782SGreg Clayton                                     RefreshTopIOHandler();
331544d93782SGreg Clayton                                 }
331644d93782SGreg Clayton                             }
331744d93782SGreg Clayton                         }
331844d93782SGreg Clayton                     }
331944d93782SGreg Clayton                 }
332044d93782SGreg Clayton 
332144d93782SGreg Clayton                 if (m_forward_listener_sp)
332244d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
332344d93782SGreg Clayton             }
332444d93782SGreg Clayton         }
332544d93782SGreg Clayton     }
332644d93782SGreg Clayton }
332744d93782SGreg Clayton 
332844d93782SGreg Clayton lldb::thread_result_t
332944d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
333044d93782SGreg Clayton {
333144d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
333244d93782SGreg Clayton     return NULL;
333344d93782SGreg Clayton }
333444d93782SGreg Clayton 
333544d93782SGreg Clayton bool
333644d93782SGreg Clayton Debugger::StartEventHandlerThread()
333744d93782SGreg Clayton {
333844d93782SGreg Clayton     if (!IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread))
333944d93782SGreg Clayton         m_event_handler_thread = Host::ThreadCreate("lldb.debugger.event-handler", EventHandlerThread, this, NULL);
334044d93782SGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread);
334144d93782SGreg Clayton }
334244d93782SGreg Clayton 
334344d93782SGreg Clayton void
334444d93782SGreg Clayton Debugger::StopEventHandlerThread()
334544d93782SGreg Clayton {
334644d93782SGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread))
334744d93782SGreg Clayton     {
334844d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
334944d93782SGreg Clayton         Host::ThreadJoin(m_event_handler_thread, NULL, NULL);
335044d93782SGreg Clayton         m_event_handler_thread = LLDB_INVALID_HOST_THREAD;
335144d93782SGreg Clayton     }
335244d93782SGreg Clayton }
335344d93782SGreg Clayton 
335444d93782SGreg Clayton 
335544d93782SGreg Clayton lldb::thread_result_t
335644d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
335744d93782SGreg Clayton {
335844d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
335944d93782SGreg Clayton     debugger->ExecuteIOHanders();
336044d93782SGreg Clayton     debugger->StopEventHandlerThread();
336144d93782SGreg Clayton     return NULL;
336244d93782SGreg Clayton }
336344d93782SGreg Clayton 
336444d93782SGreg Clayton bool
336544d93782SGreg Clayton Debugger::StartIOHandlerThread()
336644d93782SGreg Clayton {
336744d93782SGreg Clayton     if (!IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread))
336844d93782SGreg Clayton         m_io_handler_thread = Host::ThreadCreate("lldb.debugger.io-handler", IOHandlerThread, this, NULL);
336944d93782SGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread);
337044d93782SGreg Clayton }
337144d93782SGreg Clayton 
337244d93782SGreg Clayton void
337344d93782SGreg Clayton Debugger::StopIOHandlerThread()
337444d93782SGreg Clayton {
337544d93782SGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread))
337644d93782SGreg Clayton     {
337744d93782SGreg Clayton         if (m_input_file_sp)
337844d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
337944d93782SGreg Clayton         Host::ThreadJoin(m_io_handler_thread, NULL, NULL);
338044d93782SGreg Clayton         m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
338144d93782SGreg Clayton     }
338244d93782SGreg Clayton }
338344d93782SGreg Clayton 
338444d93782SGreg Clayton 
3385