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
781b654882SGreg Clayton     // global init contructors
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}}"\
11467cc0636SGreg Clayton     "\\n"
11567cc0636SGreg Clayton 
11667cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
11767cc0636SGreg Clayton     MODULE_WITH_FUNC\
11867cc0636SGreg Clayton     FILE_AND_LINE\
11967cc0636SGreg Clayton     "\\n"
12067cc0636SGreg Clayton 
12167cc0636SGreg Clayton 
12267cc0636SGreg Clayton 
123754a9369SGreg Clayton static PropertyDefinition
124754a9369SGreg Clayton g_properties[] =
12567cc0636SGreg Clayton {
12667cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
12767cc0636SGreg 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." },
12867cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1294c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
13067cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
13167cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
13267cc0636SGreg 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." },
13367cc0636SGreg 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." },
13467cc0636SGreg 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." },
13567cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
13667cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
13767cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
138c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
13990a8db30SEnrico 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)." },
140e8cd0c98SGreg Clayton 
14167cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
14267cc0636SGreg Clayton };
14367cc0636SGreg Clayton 
14467cc0636SGreg Clayton enum
14567cc0636SGreg Clayton {
14667cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
14767cc0636SGreg Clayton     ePropertyFrameFormat,
14867cc0636SGreg Clayton     ePropertyNotiftVoid,
14967cc0636SGreg Clayton     ePropertyPrompt,
15067cc0636SGreg Clayton     ePropertyScriptLanguage,
15167cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
15267cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
15367cc0636SGreg Clayton     ePropertyStopLineCountAfter,
15467cc0636SGreg Clayton     ePropertyStopLineCountBefore,
15567cc0636SGreg Clayton     ePropertyTerminalWidth,
15667cc0636SGreg Clayton     ePropertyThreadFormat,
157c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
158c3ce7f27SMichael Sartain     ePropertyUseColor,
15990a8db30SEnrico Granata     ePropertyAutoOneLineSummaries
16067cc0636SGreg Clayton };
16167cc0636SGreg Clayton 
1625fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1634c05410fSGreg Clayton 
1644c05410fSGreg Clayton Error
1654c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1664c05410fSGreg Clayton                             VarSetOperationType op,
1674c05410fSGreg Clayton                             const char *property_path,
1684c05410fSGreg Clayton                             const char *value)
1694c05410fSGreg Clayton {
17084a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
17184a53dfbSEnrico Granata     TargetSP target_sp;
172397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
17384a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
17484a53dfbSEnrico Granata     {
17584a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
17684a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
17784a53dfbSEnrico Granata     }
1784c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1794c05410fSGreg Clayton     if (error.Success())
1804c05410fSGreg Clayton     {
18184a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
1824c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1834c05410fSGreg Clayton         {
1844c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
185c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
186c3ce7f27SMichael Sartain             if (str.length())
187c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
18844d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
1894c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1904c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
1914c05410fSGreg Clayton         }
192c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
193c3ce7f27SMichael Sartain         {
194c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
195c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
196c3ce7f27SMichael Sartain         }
197397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
19884a53dfbSEnrico Granata         {
199397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
20084a53dfbSEnrico Granata             {
20184a53dfbSEnrico Granata                 std::list<Error> errors;
2029730339bSEnrico Granata                 StreamString feedback_stream;
2039730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
20484a53dfbSEnrico Granata                 {
20544d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
20644d93782SGreg Clayton                     if (stream_sp)
20744d93782SGreg Clayton                     {
20884a53dfbSEnrico Granata                         for (auto error : errors)
20984a53dfbSEnrico Granata                         {
21044d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
21184a53dfbSEnrico Granata                         }
2129730339bSEnrico Granata                         if (feedback_stream.GetSize())
21344d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
21444d93782SGreg Clayton                     }
21584a53dfbSEnrico Granata                 }
21684a53dfbSEnrico Granata             }
21784a53dfbSEnrico Granata         }
2184c05410fSGreg Clayton     }
2194c05410fSGreg Clayton     return error;
2204c05410fSGreg Clayton }
2214c05410fSGreg Clayton 
22267cc0636SGreg Clayton bool
22367cc0636SGreg Clayton Debugger::GetAutoConfirm () const
22467cc0636SGreg Clayton {
22567cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
226754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
22767cc0636SGreg Clayton }
22867cc0636SGreg Clayton 
22967cc0636SGreg Clayton const char *
23067cc0636SGreg Clayton Debugger::GetFrameFormat() const
23167cc0636SGreg Clayton {
23267cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
233754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
23467cc0636SGreg Clayton }
23567cc0636SGreg Clayton 
23667cc0636SGreg Clayton bool
23767cc0636SGreg Clayton Debugger::GetNotifyVoid () const
23867cc0636SGreg Clayton {
23967cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
240754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
24167cc0636SGreg Clayton }
24267cc0636SGreg Clayton 
24367cc0636SGreg Clayton const char *
24467cc0636SGreg Clayton Debugger::GetPrompt() const
24567cc0636SGreg Clayton {
24667cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
247754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
24867cc0636SGreg Clayton }
24967cc0636SGreg Clayton 
25067cc0636SGreg Clayton void
25167cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
25267cc0636SGreg Clayton {
25367cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
25467cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
25567cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
256c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
257c3ce7f27SMichael Sartain     if (str.length())
258c3ce7f27SMichael Sartain         new_prompt = str.c_str();
25944d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
26067cc0636SGreg Clayton }
26167cc0636SGreg Clayton 
26267cc0636SGreg Clayton const char *
26367cc0636SGreg Clayton Debugger::GetThreadFormat() const
26467cc0636SGreg Clayton {
26567cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
266754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
26767cc0636SGreg Clayton }
26867cc0636SGreg Clayton 
26967cc0636SGreg Clayton lldb::ScriptLanguage
27067cc0636SGreg Clayton Debugger::GetScriptLanguage() const
27167cc0636SGreg Clayton {
27267cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
273754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
27467cc0636SGreg Clayton }
27567cc0636SGreg Clayton 
27667cc0636SGreg Clayton bool
27767cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
27867cc0636SGreg Clayton {
27967cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
28067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
28167cc0636SGreg Clayton }
28267cc0636SGreg Clayton 
28367cc0636SGreg Clayton uint32_t
28467cc0636SGreg Clayton Debugger::GetTerminalWidth () const
28567cc0636SGreg Clayton {
28667cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
287754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
28867cc0636SGreg Clayton }
28967cc0636SGreg Clayton 
29067cc0636SGreg Clayton bool
29167cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
29267cc0636SGreg Clayton {
29367cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
29467cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
29567cc0636SGreg Clayton }
29667cc0636SGreg Clayton 
29767cc0636SGreg Clayton bool
29867cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
29967cc0636SGreg Clayton {
30067cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
301754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
30267cc0636SGreg Clayton }
30367cc0636SGreg Clayton 
30467cc0636SGreg Clayton bool
30567cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
30667cc0636SGreg Clayton {
30767cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
30867cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
30967cc0636SGreg Clayton }
31067cc0636SGreg Clayton 
311c3ce7f27SMichael Sartain bool
312c3ce7f27SMichael Sartain Debugger::GetUseColor () const
313c3ce7f27SMichael Sartain {
314c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
315c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
316c3ce7f27SMichael Sartain }
317c3ce7f27SMichael Sartain 
318c3ce7f27SMichael Sartain bool
319c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
320c3ce7f27SMichael Sartain {
321c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
322c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
323c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
324c3ce7f27SMichael Sartain     return ret;
325c3ce7f27SMichael Sartain }
326c3ce7f27SMichael Sartain 
32767cc0636SGreg Clayton uint32_t
32867cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
32967cc0636SGreg Clayton {
33067cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
331754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
33267cc0636SGreg Clayton }
33367cc0636SGreg Clayton 
33467cc0636SGreg Clayton Debugger::StopDisassemblyType
33567cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
33667cc0636SGreg Clayton {
33767cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
338754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
33967cc0636SGreg Clayton }
34067cc0636SGreg Clayton 
34167cc0636SGreg Clayton uint32_t
34267cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
34367cc0636SGreg Clayton {
34467cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
345754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
34667cc0636SGreg Clayton }
347e372b98dSGreg Clayton 
348553fad5cSEnrico Granata bool
34990a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
350553fad5cSEnrico Granata {
35190a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
352553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
353553fad5cSEnrico Granata 
354553fad5cSEnrico Granata }
355553fad5cSEnrico Granata 
3561b654882SGreg Clayton #pragma mark Debugger
3571b654882SGreg Clayton 
35867cc0636SGreg Clayton //const DebuggerPropertiesSP &
35967cc0636SGreg Clayton //Debugger::GetSettings() const
36067cc0636SGreg Clayton //{
36167cc0636SGreg Clayton //    return m_properties_sp;
36267cc0636SGreg Clayton //}
36367cc0636SGreg Clayton //
36499d0faf2SGreg Clayton 
3652f88aadfSCaroline Tice int
3662f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3672f88aadfSCaroline Tice {
3682f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3692f88aadfSCaroline Tice }
3702f88aadfSCaroline Tice 
37130fdc8d8SChris Lattner void
3725fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
37330fdc8d8SChris Lattner {
3745fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
375c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
376dbe54508SGreg Clayton         lldb_private::Initialize();
37799d0faf2SGreg Clayton }
37830fdc8d8SChris Lattner 
37930fdc8d8SChris Lattner void
38030fdc8d8SChris Lattner Debugger::Terminate ()
38130fdc8d8SChris Lattner {
3826611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3836611103cSGreg Clayton     {
38430fdc8d8SChris Lattner         g_shared_debugger_refcount--;
38530fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
38630fdc8d8SChris Lattner         {
387dbe54508SGreg Clayton             lldb_private::WillTerminate();
388dbe54508SGreg Clayton             lldb_private::Terminate();
3896760a517SCaroline Tice 
39099d0faf2SGreg Clayton             // Clear our master list of debugger objects
39199d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
39299d0faf2SGreg Clayton             GetDebuggerList().clear();
39330fdc8d8SChris Lattner         }
3946760a517SCaroline Tice     }
3956760a517SCaroline Tice }
39630fdc8d8SChris Lattner 
39720bd37f7SCaroline Tice void
39820bd37f7SCaroline Tice Debugger::SettingsInitialize ()
39920bd37f7SCaroline Tice {
4006920b52bSGreg Clayton     Target::SettingsInitialize ();
40120bd37f7SCaroline Tice }
40220bd37f7SCaroline Tice 
40320bd37f7SCaroline Tice void
40420bd37f7SCaroline Tice Debugger::SettingsTerminate ()
40520bd37f7SCaroline Tice {
4066920b52bSGreg Clayton     Target::SettingsTerminate ();
40720bd37f7SCaroline Tice }
40820bd37f7SCaroline Tice 
40921dfcd9dSEnrico Granata bool
410e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
41121dfcd9dSEnrico Granata {
4125fb8f797SGreg Clayton     if (g_load_plugin_callback)
413e743c782SEnrico Granata     {
4145fb8f797SGreg Clayton         lldb::DynamicLibrarySP dynlib_sp = g_load_plugin_callback (shared_from_this(), spec, error);
4155fb8f797SGreg Clayton         if (dynlib_sp)
41621dfcd9dSEnrico Granata         {
41721dfcd9dSEnrico Granata             m_loaded_plugins.push_back(dynlib_sp);
41821dfcd9dSEnrico Granata             return true;
41921dfcd9dSEnrico Granata         }
4205fb8f797SGreg Clayton     }
4215fb8f797SGreg Clayton     else
4225fb8f797SGreg Clayton     {
4235fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4245fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4255fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4265fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4275fb8f797SGreg Clayton     }
42821dfcd9dSEnrico Granata     return false;
42921dfcd9dSEnrico Granata }
43021dfcd9dSEnrico Granata 
43121dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
43221dfcd9dSEnrico Granata LoadPluginCallback
43321dfcd9dSEnrico Granata (
43421dfcd9dSEnrico Granata  void *baton,
43521dfcd9dSEnrico Granata  FileSpec::FileType file_type,
43621dfcd9dSEnrico Granata  const FileSpec &file_spec
43721dfcd9dSEnrico Granata  )
43821dfcd9dSEnrico Granata {
43921dfcd9dSEnrico Granata     Error error;
44021dfcd9dSEnrico Granata 
44121dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4423cf443ddSMichael Sartain     static ConstString g_solibext("so");
44321dfcd9dSEnrico Granata 
44421dfcd9dSEnrico Granata     if (!baton)
44521dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
44621dfcd9dSEnrico Granata 
44721dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
44821dfcd9dSEnrico Granata 
44921dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
45021dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
45121dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
45221dfcd9dSEnrico Granata     // file type information.
45321dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
45421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
45521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
45621dfcd9dSEnrico Granata     {
45721dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
45821dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
45921dfcd9dSEnrico Granata 
4603cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4613cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4623cf443ddSMichael Sartain         {
46321dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4643cf443ddSMichael Sartain         }
46521dfcd9dSEnrico Granata 
466e743c782SEnrico Granata         Error plugin_load_error;
467e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
46821dfcd9dSEnrico Granata 
46921dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
47021dfcd9dSEnrico Granata     }
47121dfcd9dSEnrico Granata 
47221dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
47321dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
47421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
47521dfcd9dSEnrico Granata     {
47621dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
47721dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
47821dfcd9dSEnrico Granata         // might be enurating a file system that doesn't have correct file type
47921dfcd9dSEnrico Granata         // information.
48021dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
48121dfcd9dSEnrico Granata     }
48221dfcd9dSEnrico Granata 
48321dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
48421dfcd9dSEnrico Granata }
48521dfcd9dSEnrico Granata 
48621dfcd9dSEnrico Granata void
48721dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
48821dfcd9dSEnrico Granata {
48921dfcd9dSEnrico Granata     FileSpec dir_spec;
49021dfcd9dSEnrico Granata     const bool find_directories = true;
49121dfcd9dSEnrico Granata     const bool find_files = true;
49221dfcd9dSEnrico Granata     const bool find_other = true;
49321dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
49421dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
49521dfcd9dSEnrico Granata     {
49621dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
49721dfcd9dSEnrico Granata         {
49821dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
49921dfcd9dSEnrico Granata                                           find_directories,
50021dfcd9dSEnrico Granata                                           find_files,
50121dfcd9dSEnrico Granata                                           find_other,
50221dfcd9dSEnrico Granata                                           LoadPluginCallback,
50321dfcd9dSEnrico Granata                                           this);
50421dfcd9dSEnrico Granata         }
50521dfcd9dSEnrico Granata     }
50621dfcd9dSEnrico Granata 
50721dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
50821dfcd9dSEnrico Granata     {
50921dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
51021dfcd9dSEnrico Granata         {
51121dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
51221dfcd9dSEnrico Granata                                           find_directories,
51321dfcd9dSEnrico Granata                                           find_files,
51421dfcd9dSEnrico Granata                                           find_other,
51521dfcd9dSEnrico Granata                                           LoadPluginCallback,
51621dfcd9dSEnrico Granata                                           this);
51721dfcd9dSEnrico Granata         }
51821dfcd9dSEnrico Granata     }
519e8cd0c98SGreg Clayton 
520e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
52121dfcd9dSEnrico Granata }
52221dfcd9dSEnrico Granata 
5236611103cSGreg Clayton DebuggerSP
524228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5256611103cSGreg Clayton {
526228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
527c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5286611103cSGreg Clayton     {
5296611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5306611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5316611103cSGreg Clayton     }
53221dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5336611103cSGreg Clayton     return debugger_sp;
5346611103cSGreg Clayton }
5356611103cSGreg Clayton 
536e02657b1SCaroline Tice void
5374d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
538e02657b1SCaroline Tice {
539e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
540e02657b1SCaroline Tice         return;
541e02657b1SCaroline Tice 
5428314c525SJim Ingham     debugger_sp->Clear();
5438314c525SJim Ingham 
544c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
545c15f55e2SGreg Clayton     {
546e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
547e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
548e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
549e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
550e02657b1SCaroline Tice         {
551e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
552e02657b1SCaroline Tice             {
553e02657b1SCaroline Tice                 debugger_list.erase (pos);
554e02657b1SCaroline Tice                 return;
555e02657b1SCaroline Tice             }
556e02657b1SCaroline Tice         }
557e02657b1SCaroline Tice     }
558c15f55e2SGreg Clayton }
559e02657b1SCaroline Tice 
5604d122c40SGreg Clayton DebuggerSP
5613df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5623df9a8dfSCaroline Tice {
5634d122c40SGreg Clayton     DebuggerSP debugger_sp;
5646920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5656920b52bSGreg Clayton     {
5666920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5676920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5686920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5696920b52bSGreg Clayton 
5706920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5716920b52bSGreg Clayton         {
5726920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5736920b52bSGreg Clayton             {
5746920b52bSGreg Clayton                 debugger_sp = *pos;
5756920b52bSGreg Clayton                 break;
5766920b52bSGreg Clayton             }
5776920b52bSGreg Clayton         }
5786920b52bSGreg Clayton     }
5793df9a8dfSCaroline Tice     return debugger_sp;
5803df9a8dfSCaroline Tice }
5816611103cSGreg Clayton 
5826611103cSGreg Clayton TargetSP
5836611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
5846611103cSGreg Clayton {
5854d122c40SGreg Clayton     TargetSP target_sp;
586c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
587c15f55e2SGreg Clayton     {
5886611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5896611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5906611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5916611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5926611103cSGreg Clayton         {
5936611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
5946611103cSGreg Clayton             if (target_sp)
5956611103cSGreg Clayton                 break;
5966611103cSGreg Clayton         }
597c15f55e2SGreg Clayton     }
5986611103cSGreg Clayton     return target_sp;
5996611103cSGreg Clayton }
6006611103cSGreg Clayton 
601e4e45924SGreg Clayton TargetSP
602e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
603e4e45924SGreg Clayton {
604e4e45924SGreg Clayton     TargetSP target_sp;
605c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
606c15f55e2SGreg Clayton     {
607e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
608e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
609e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
610e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
611e4e45924SGreg Clayton         {
612e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
613e4e45924SGreg Clayton             if (target_sp)
614e4e45924SGreg Clayton                 break;
615e4e45924SGreg Clayton         }
616c15f55e2SGreg Clayton     }
617e4e45924SGreg Clayton     return target_sp;
618e4e45924SGreg Clayton }
619e4e45924SGreg Clayton 
620228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
621ebc1bb27SCaroline Tice     UserID (g_unique_id++),
62267cc0636SGreg Clayton     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
62344d93782SGreg Clayton     m_input_file_sp (new StreamFile (stdin, false)),
62444d93782SGreg Clayton     m_output_file_sp (new StreamFile (stdout, false)),
62544d93782SGreg Clayton     m_error_file_sp (new StreamFile (stderr, false)),
626c5917d9aSJim Ingham     m_terminal_state (),
6274bddaeb5SJim Ingham     m_target_list (*this),
628ded470d3SGreg Clayton     m_platform_list (),
62930fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
6309585fbfcSGreg Clayton     m_source_manager_ap(),
631e37d605eSJim Ingham     m_source_file_cache(),
6326611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
633d5a0a01bSCaroline Tice     m_input_reader_stack (),
63444d93782SGreg Clayton     m_instance_name (),
63544d93782SGreg Clayton     m_loaded_plugins (),
63644d93782SGreg Clayton     m_event_handler_thread (LLDB_INVALID_HOST_THREAD),
637b4874f1aSGreg Clayton     m_io_handler_thread (LLDB_INVALID_HOST_THREAD)
63830fdc8d8SChris Lattner {
63967cc0636SGreg Clayton     char instance_cstr[256];
64067cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
64167cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
642228063cdSJim Ingham     if (log_callback)
643228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6446611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
645ded470d3SGreg Clayton     // Always add our default platform to the platform list
646ded470d3SGreg Clayton     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
647ded470d3SGreg Clayton     assert (default_platform_sp.get());
648ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
64967cc0636SGreg Clayton 
650754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
65167cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
65267cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
65367cc0636SGreg Clayton                                      true,
65467cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
655754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
656754a9369SGreg Clayton     {
657754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
658754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
659754a9369SGreg Clayton                                          true,
660754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
661754a9369SGreg Clayton     }
66267cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
66367cc0636SGreg Clayton     term_width->SetMinimumValue(10);
66467cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
665c3ce7f27SMichael Sartain 
666c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
667c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
668c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
669c3ce7f27SMichael Sartain         SetUseColor (false);
67030fdc8d8SChris Lattner }
67130fdc8d8SChris Lattner 
67230fdc8d8SChris Lattner Debugger::~Debugger ()
67330fdc8d8SChris Lattner {
6748314c525SJim Ingham     Clear();
6758314c525SJim Ingham }
6768314c525SJim Ingham 
6778314c525SJim Ingham void
6788314c525SJim Ingham Debugger::Clear()
6798314c525SJim Ingham {
68044d93782SGreg Clayton     ClearIOHandlers();
68144d93782SGreg Clayton     StopIOHandlerThread();
68244d93782SGreg Clayton     StopEventHandlerThread();
6831ed54f50SGreg Clayton     m_listener.Clear();
6846611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6856611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
6866611103cSGreg Clayton     {
687ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
688ccbc08e6SGreg Clayton         if (target_sp)
689ccbc08e6SGreg Clayton         {
690ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
6916611103cSGreg Clayton             if (process_sp)
6921fd07059SJim Ingham                 process_sp->Finalize();
693ccbc08e6SGreg Clayton             target_sp->Destroy();
6946611103cSGreg Clayton         }
69530fdc8d8SChris Lattner     }
6964bddaeb5SJim Ingham     BroadcasterManager::Clear ();
69730fdc8d8SChris Lattner 
6980d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
6990d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
700c5917d9aSJim Ingham     m_terminal_state.Clear();
70144d93782SGreg Clayton     if (m_input_file_sp)
70244d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7030c4129f2SGreg Clayton 
7040c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7058314c525SJim Ingham }
70630fdc8d8SChris Lattner 
70730fdc8d8SChris Lattner bool
708fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
709fc3f027dSGreg Clayton {
71044d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
71144d93782SGreg Clayton     return false;
712fc3f027dSGreg Clayton }
713fc3f027dSGreg Clayton 
714fc3f027dSGreg Clayton void
715fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
716fc3f027dSGreg Clayton {
71744d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
718fc3f027dSGreg Clayton }
719fc3f027dSGreg Clayton 
720fc3f027dSGreg Clayton bool
72130fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
72230fdc8d8SChris Lattner {
7236611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
72430fdc8d8SChris Lattner }
72530fdc8d8SChris Lattner 
72630fdc8d8SChris Lattner void
72730fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
72830fdc8d8SChris Lattner {
7296611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
73030fdc8d8SChris Lattner }
73130fdc8d8SChris Lattner 
73230fdc8d8SChris Lattner 
73330fdc8d8SChris Lattner void
73430fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
73530fdc8d8SChris Lattner {
73644d93782SGreg Clayton     if (m_input_file_sp)
73744d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
73844d93782SGreg Clayton     else
73944d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
74044d93782SGreg Clayton 
74144d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
74251b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
74351b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
74430fdc8d8SChris Lattner 
745c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
746c5917d9aSJim Ingham     SaveInputTerminalState ();
74730fdc8d8SChris Lattner }
74830fdc8d8SChris Lattner 
74930fdc8d8SChris Lattner void
75030fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
75130fdc8d8SChris Lattner {
75244d93782SGreg Clayton     if (m_output_file_sp)
75344d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
75444d93782SGreg Clayton     else
75544d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
75644d93782SGreg Clayton 
75744d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
75851b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
75951b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7602f88aadfSCaroline Tice 
761b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
762b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
763b588726eSEnrico Granata     const bool can_create = false;
764b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
765b588726eSEnrico Granata     if (script_interpreter)
766b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
76730fdc8d8SChris Lattner }
76830fdc8d8SChris Lattner 
76930fdc8d8SChris Lattner void
77030fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
77130fdc8d8SChris Lattner {
77244d93782SGreg Clayton     if (m_error_file_sp)
77344d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
77444d93782SGreg Clayton     else
77544d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
77644d93782SGreg Clayton 
77744d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
77851b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
77951b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
78030fdc8d8SChris Lattner }
78130fdc8d8SChris Lattner 
782c5917d9aSJim Ingham void
783c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
784c5917d9aSJim Ingham {
78544d93782SGreg Clayton     if (m_input_file_sp)
78644d93782SGreg Clayton     {
78744d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
788c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
789c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
790c5917d9aSJim Ingham     }
79144d93782SGreg Clayton }
792c5917d9aSJim Ingham 
793c5917d9aSJim Ingham void
794c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
795c5917d9aSJim Ingham {
796c5917d9aSJim Ingham     m_terminal_state.Restore();
797c5917d9aSJim Ingham }
798c5917d9aSJim Ingham 
79930fdc8d8SChris Lattner ExecutionContext
8002976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
80130fdc8d8SChris Lattner {
80230fdc8d8SChris Lattner     ExecutionContext exe_ctx;
803c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
804c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
80530fdc8d8SChris Lattner 
80630fdc8d8SChris Lattner     if (target_sp)
80730fdc8d8SChris Lattner     {
808c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
809c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
810c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
81130fdc8d8SChris Lattner         {
812c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
813c14ee32dSGreg Clayton             if (thread_sp)
81430fdc8d8SChris Lattner             {
815c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
816c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
817c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
818c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
81930fdc8d8SChris Lattner             }
82030fdc8d8SChris Lattner         }
82130fdc8d8SChris Lattner     }
82230fdc8d8SChris Lattner     return exe_ctx;
82330fdc8d8SChris Lattner }
82430fdc8d8SChris Lattner 
82530fdc8d8SChris Lattner void
826efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
827efed6131SCaroline Tice {
82844d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
82944d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
830efed6131SCaroline Tice     if (reader_sp)
83144d93782SGreg Clayton         reader_sp->Interrupt();
832efed6131SCaroline Tice }
833efed6131SCaroline Tice 
834efed6131SCaroline Tice void
835efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
836efed6131SCaroline Tice {
83744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
83844d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
839efed6131SCaroline Tice     if (reader_sp)
84044d93782SGreg Clayton         reader_sp->GotEOF();
841efed6131SCaroline Tice }
842efed6131SCaroline Tice 
843efed6131SCaroline Tice void
84444d93782SGreg Clayton Debugger::ClearIOHandlers ()
8453d6086f6SCaroline Tice {
846b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
84744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
848d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8493d6086f6SCaroline Tice     {
85044d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8513d6086f6SCaroline Tice         if (reader_sp)
8523d6086f6SCaroline Tice         {
85344d93782SGreg Clayton             m_input_reader_stack.Pop();
8543d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
855e68f5d6bSGreg Clayton             reader_sp->Cancel();
8563d6086f6SCaroline Tice         }
8573d6086f6SCaroline Tice     }
8583d6086f6SCaroline Tice }
8593d6086f6SCaroline Tice 
8603d6086f6SCaroline Tice void
86144d93782SGreg Clayton Debugger::ExecuteIOHanders()
862969ed3d1SCaroline Tice {
86344d93782SGreg Clayton 
86444d93782SGreg Clayton     while (1)
865969ed3d1SCaroline Tice     {
86644d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
86730fdc8d8SChris Lattner         if (!reader_sp)
86830fdc8d8SChris Lattner             break;
86930fdc8d8SChris Lattner 
87044d93782SGreg Clayton         reader_sp->Activate();
87144d93782SGreg Clayton         reader_sp->Run();
87244d93782SGreg Clayton         reader_sp->Deactivate();
87344d93782SGreg Clayton 
87444d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
87544d93782SGreg Clayton         while (1)
87630fdc8d8SChris Lattner         {
87744d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
87844d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
87944d93782SGreg Clayton                 m_input_reader_stack.Pop();
88030fdc8d8SChris Lattner             else
88130fdc8d8SChris Lattner                 break;
88230fdc8d8SChris Lattner         }
88330fdc8d8SChris Lattner     }
88444d93782SGreg Clayton     ClearIOHandlers();
88544d93782SGreg Clayton }
88630fdc8d8SChris Lattner 
88744d93782SGreg Clayton bool
88844d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
88944d93782SGreg Clayton {
89044d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
89144d93782SGreg Clayton }
89230fdc8d8SChris Lattner 
89344d93782SGreg Clayton 
89444d93782SGreg Clayton ConstString
89544d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
89644d93782SGreg Clayton {
89744d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
89830fdc8d8SChris Lattner }
89930fdc8d8SChris Lattner 
90030fdc8d8SChris Lattner void
90144d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
90244d93782SGreg Clayton {
90344d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
90444d93782SGreg Clayton     PushIOHandler (reader_sp);
905*577508dfSGreg Clayton 
906*577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
907*577508dfSGreg Clayton     while (top_reader_sp)
908*577508dfSGreg Clayton     {
909*577508dfSGreg Clayton         top_reader_sp->Activate();
910*577508dfSGreg Clayton         top_reader_sp->Run();
911*577508dfSGreg Clayton         top_reader_sp->Deactivate();
912*577508dfSGreg Clayton 
913*577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
914*577508dfSGreg Clayton         {
915*577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
916*577508dfSGreg Clayton                 break;
917*577508dfSGreg Clayton         }
918*577508dfSGreg Clayton 
919*577508dfSGreg Clayton         while (1)
920*577508dfSGreg Clayton         {
921*577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
922*577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
923*577508dfSGreg Clayton                 m_input_reader_stack.Pop();
924*577508dfSGreg Clayton             else
925*577508dfSGreg Clayton                 break;
926*577508dfSGreg Clayton         }
927*577508dfSGreg Clayton     }
92844d93782SGreg Clayton }
92944d93782SGreg Clayton 
93044d93782SGreg Clayton void
93144d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
93244d93782SGreg Clayton {
93344d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
93444d93782SGreg Clayton     // This function is called when one ore more of the streams
93544d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
93644d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
93744d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
93844d93782SGreg Clayton 
93944d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
94044d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
94144d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
94244d93782SGreg Clayton     if (!in)
94344d93782SGreg Clayton     {
94444d93782SGreg Clayton         if (top_reader_sp)
94544d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
94644d93782SGreg Clayton         else
94744d93782SGreg Clayton             in = GetInputFile();
94844d93782SGreg Clayton 
94944d93782SGreg Clayton         // If there is nothing, use stdin
95044d93782SGreg Clayton         if (!in)
95144d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
95244d93782SGreg Clayton     }
95344d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
95444d93782SGreg Clayton     if (!out)
95544d93782SGreg Clayton     {
95644d93782SGreg Clayton         if (top_reader_sp)
95744d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
95844d93782SGreg Clayton         else
95944d93782SGreg Clayton             out = GetOutputFile();
96044d93782SGreg Clayton 
96144d93782SGreg Clayton         // If there is nothing, use stdout
96244d93782SGreg Clayton         if (!out)
96344d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
96444d93782SGreg Clayton     }
96544d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
96644d93782SGreg Clayton     if (!err)
96744d93782SGreg Clayton     {
96844d93782SGreg Clayton         if (top_reader_sp)
96944d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
97044d93782SGreg Clayton         else
97144d93782SGreg Clayton             err = GetErrorFile();
97244d93782SGreg Clayton 
97344d93782SGreg Clayton         // If there is nothing, use stderr
97444d93782SGreg Clayton         if (!err)
97544d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
97644d93782SGreg Clayton 
97744d93782SGreg Clayton     }
97844d93782SGreg Clayton }
97944d93782SGreg Clayton 
98044d93782SGreg Clayton void
98144d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
98230fdc8d8SChris Lattner {
98330fdc8d8SChris Lattner     if (!reader_sp)
98430fdc8d8SChris Lattner         return;
985b44880caSCaroline Tice 
98644d93782SGreg Clayton     // Got the current top input reader...
98744d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
988b44880caSCaroline Tice 
989b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
990b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
991b4874f1aSGreg Clayton     {
99244d93782SGreg Clayton         // Push our new input reader
993d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
99444d93782SGreg Clayton 
99544d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
99644d93782SGreg Clayton         // and let this new input reader take over
99744d93782SGreg Clayton         if (top_reader_sp)
99844d93782SGreg Clayton             top_reader_sp->Deactivate();
99930fdc8d8SChris Lattner     }
1000b4874f1aSGreg Clayton }
100130fdc8d8SChris Lattner 
100230fdc8d8SChris Lattner bool
100344d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
100430fdc8d8SChris Lattner {
100530fdc8d8SChris Lattner     bool result = false;
100630fdc8d8SChris Lattner 
100744d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
100844d93782SGreg Clayton 
100930fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
101030fdc8d8SChris Lattner     // read on the stack referesh its prompt and if there is one...
1011d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
101230fdc8d8SChris Lattner     {
101344d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
101430fdc8d8SChris Lattner 
101530fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
101630fdc8d8SChris Lattner         {
101744d93782SGreg Clayton             reader_sp->Deactivate();
1018b4874f1aSGreg Clayton             reader_sp->Cancel();
1019d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
102030fdc8d8SChris Lattner 
1021d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
102230fdc8d8SChris Lattner             if (reader_sp)
102344d93782SGreg Clayton                 reader_sp->Activate();
102444d93782SGreg Clayton 
102544d93782SGreg Clayton             result = true;
102630fdc8d8SChris Lattner         }
102730fdc8d8SChris Lattner     }
102830fdc8d8SChris Lattner     return result;
102930fdc8d8SChris Lattner }
103030fdc8d8SChris Lattner 
103130fdc8d8SChris Lattner bool
103244d93782SGreg Clayton Debugger::HideTopIOHandler()
103330fdc8d8SChris Lattner {
103444d93782SGreg Clayton     Mutex::Locker locker;
103530fdc8d8SChris Lattner 
103644d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
103730fdc8d8SChris Lattner     {
103844d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
103944d93782SGreg Clayton         if (reader_sp)
104044d93782SGreg Clayton             reader_sp->Hide();
104144d93782SGreg Clayton         return true;
104230fdc8d8SChris Lattner     }
104344d93782SGreg Clayton     return false;
104430fdc8d8SChris Lattner }
104530fdc8d8SChris Lattner 
104630fdc8d8SChris Lattner void
104744d93782SGreg Clayton Debugger::RefreshTopIOHandler()
104830fdc8d8SChris Lattner {
104944d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
105044d93782SGreg Clayton     if (reader_sp)
105144d93782SGreg Clayton         reader_sp->Refresh();
105230fdc8d8SChris Lattner }
105344d93782SGreg Clayton 
10546611103cSGreg Clayton 
10555b52f0c7SJim Ingham StreamSP
10565b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10575b52f0c7SJim Ingham {
10585b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10595b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10605b52f0c7SJim Ingham }
10615b52f0c7SJim Ingham 
10625b52f0c7SJim Ingham StreamSP
10635b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10645b52f0c7SJim Ingham {
10655b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10665b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10675b52f0c7SJim Ingham }
10685b52f0c7SJim Ingham 
1069c7bece56SGreg Clayton size_t
1070061858ceSEnrico Granata Debugger::GetNumDebuggers()
1071061858ceSEnrico Granata {
1072c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1073c15f55e2SGreg Clayton     {
1074061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1075061858ceSEnrico Granata         return GetDebuggerList().size();
1076061858ceSEnrico Granata     }
1077c15f55e2SGreg Clayton     return 0;
1078c15f55e2SGreg Clayton }
1079061858ceSEnrico Granata 
1080061858ceSEnrico Granata lldb::DebuggerSP
1081c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1082061858ceSEnrico Granata {
1083061858ceSEnrico Granata     DebuggerSP debugger_sp;
1084061858ceSEnrico Granata 
1085c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1086c15f55e2SGreg Clayton     {
1087061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1088061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1089061858ceSEnrico Granata 
1090061858ceSEnrico Granata         if (index < debugger_list.size())
1091061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1092c15f55e2SGreg Clayton     }
1093061858ceSEnrico Granata 
1094061858ceSEnrico Granata     return debugger_sp;
1095061858ceSEnrico Granata }
1096061858ceSEnrico Granata 
1097ebc1bb27SCaroline Tice DebuggerSP
1098ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1099ebc1bb27SCaroline Tice {
11004d122c40SGreg Clayton     DebuggerSP debugger_sp;
1101ebc1bb27SCaroline Tice 
1102c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1103c15f55e2SGreg Clayton     {
1104ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1105ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1106ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1107ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1108ebc1bb27SCaroline Tice         {
1109ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1110ebc1bb27SCaroline Tice             {
1111ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1112ebc1bb27SCaroline Tice                 break;
1113ebc1bb27SCaroline Tice             }
1114ebc1bb27SCaroline Tice         }
1115c15f55e2SGreg Clayton     }
1116ebc1bb27SCaroline Tice     return debugger_sp;
1117ebc1bb27SCaroline Tice }
11183df9a8dfSCaroline Tice 
11192643b905SSaleem Abdulrasool #if 0
11201b654882SGreg Clayton static void
1121b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11221b654882SGreg Clayton {
11231b654882SGreg Clayton     if (frame == NULL)
11241b654882SGreg Clayton         return;
11251b654882SGreg Clayton 
11261b654882SGreg Clayton     StreamString s;
11271b654882SGreg Clayton     const char *prompt_format =
11281b654882SGreg Clayton     "{addr = '${addr}'\n}"
11291b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11301b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11311b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11321b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11331b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11341b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11351b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11361b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11371b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11381b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11391b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11401b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11411b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11421b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11431b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11441b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11451b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11461b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11471b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11481b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11491b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11501b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11511b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11521b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11531b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11541b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11551b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
11561b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1157ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11581b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
11591b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11601b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11611b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11621b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11631b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11641b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11651b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11661b654882SGreg Clayton ;
11671b654882SGreg Clayton 
11681b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11691b654882SGreg Clayton     ExecutionContext exe_ctx;
11700603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1171c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
11721b654882SGreg Clayton     {
11731b654882SGreg Clayton         printf("%s\n", s.GetData());
11741b654882SGreg Clayton     }
11751b654882SGreg Clayton     else
11761b654882SGreg Clayton     {
11771b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11781b654882SGreg Clayton     }
11791b654882SGreg Clayton }
11802643b905SSaleem Abdulrasool #endif
11811b654882SGreg Clayton 
11829fc1944eSEnrico Granata static bool
11839fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
11849fc1944eSEnrico Granata                       const char* var_name_end,
11859fc1944eSEnrico Granata                       const char** var_name_final,
11869fc1944eSEnrico Granata                       const char** percent_position,
11874d122c40SGreg Clayton                       Format* custom_format,
11889fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
11899fc1944eSEnrico Granata {
11905160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
11919fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
11929fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1193e992a089SEnrico Granata     {
1194e992a089SEnrico Granata         if (log)
1195d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
11969fc1944eSEnrico Granata         *var_name_final = var_name_end;
1197e992a089SEnrico Granata     }
11989fc1944eSEnrico Granata     else
11999fc1944eSEnrico Granata     {
12009fc1944eSEnrico Granata         *var_name_final = *percent_position;
120136aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1202e992a089SEnrico Granata         if (log)
120368ae4117SEnrico Granata             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
120436aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
12059fc1944eSEnrico Granata                                                   true,
12069fc1944eSEnrico Granata                                                   *custom_format) )
12079fc1944eSEnrico Granata         {
1208e992a089SEnrico Granata             if (log)
120968ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
121036aa5ae6SEnrico Granata 
121136aa5ae6SEnrico Granata             switch (format_name.front())
121236aa5ae6SEnrico Granata             {
121336aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
121486cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
121536aa5ae6SEnrico Granata                     break;
121636aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
121786cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
121836aa5ae6SEnrico Granata                     break;
121936aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
122086cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
122136aa5ae6SEnrico Granata                     break;
122236aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
122386cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
122436aa5ae6SEnrico Granata                     break;
122536aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
122686cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
122736aa5ae6SEnrico Granata                     break;
122836aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
122986cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
123036aa5ae6SEnrico Granata                     break;
12312c75f11eSEnrico Granata                 case 'N': // if this is a 'N', print the name
12322c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
12332c75f11eSEnrico Granata                     break;
12342c75f11eSEnrico Granata                 case '>': // if this is a '>', print the name
12352c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
12362c75f11eSEnrico Granata                     break;
123736aa5ae6SEnrico Granata                 default:
12385c42d8a8SJim Ingham                     if (log)
123936aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
124036aa5ae6SEnrico Granata                     break;
124136aa5ae6SEnrico Granata             }
12429fc1944eSEnrico Granata         }
12439fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
12449fc1944eSEnrico Granata         else
1245e992a089SEnrico Granata         {
1246e992a089SEnrico Granata             if (log)
124768ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
124886cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1249e992a089SEnrico Granata         }
12509fc1944eSEnrico Granata     }
1251e992a089SEnrico Granata     if (log)
125268ae4117SEnrico Granata         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1253e992a089SEnrico Granata                     *custom_format,
1254e992a089SEnrico Granata                     *val_obj_display);
12559fc1944eSEnrico Granata     return true;
12569fc1944eSEnrico Granata }
12579fc1944eSEnrico Granata 
12589fc1944eSEnrico Granata static bool
12599fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
12609fc1944eSEnrico Granata                     const char* var_name_end,
12619fc1944eSEnrico Granata                     const char* var_name_final,
12629fc1944eSEnrico Granata                     const char** open_bracket_position,
12639fc1944eSEnrico Granata                     const char** separator_position,
12649fc1944eSEnrico Granata                     const char** close_bracket_position,
12659fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12669fc1944eSEnrico Granata                     int64_t* index_lower,
12679fc1944eSEnrico Granata                     int64_t* index_higher)
12689fc1944eSEnrico Granata {
12695160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12709fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12719fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12729fc1944eSEnrico Granata     {
12739fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12749fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12759fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12769fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12779fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12789fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12799fc1944eSEnrico Granata         {
1280e992a089SEnrico Granata             if (log)
1281d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
12829fc1944eSEnrico Granata             *index_lower = 0;
12839fc1944eSEnrico Granata         }
12849fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
12859fc1944eSEnrico Granata         {
12869fc1944eSEnrico Granata             char *end = NULL;
12879fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12889fc1944eSEnrico Granata             *index_higher = *index_lower;
1289e992a089SEnrico Granata             if (log)
1290d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
12919fc1944eSEnrico Granata         }
12929fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
12939fc1944eSEnrico Granata         {
12949fc1944eSEnrico Granata             char *end = NULL;
12959fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12969fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1297e992a089SEnrico Granata             if (log)
1298d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
12999fc1944eSEnrico Granata         }
13009fc1944eSEnrico Granata         else
1301e992a089SEnrico Granata         {
1302e992a089SEnrico Granata             if (log)
1303d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
13049fc1944eSEnrico Granata             return false;
1305e992a089SEnrico Granata         }
13069fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
13079fc1944eSEnrico Granata         {
1308e992a089SEnrico Granata             if (log)
1309d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1310c7bece56SGreg Clayton             int64_t temp = *index_lower;
13119fc1944eSEnrico Granata             *index_lower = *index_higher;
13129fc1944eSEnrico Granata             *index_higher = temp;
13139fc1944eSEnrico Granata         }
13149fc1944eSEnrico Granata     }
1315e992a089SEnrico Granata     else if (log)
1316d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
13179fc1944eSEnrico Granata     return true;
13189fc1944eSEnrico Granata }
13199fc1944eSEnrico Granata 
13200769b2b1SMichael Sartain template <typename T>
13210769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
13220769b2b1SMichael Sartain {
13230769b2b1SMichael Sartain     if (script_interpreter)
13240769b2b1SMichael Sartain     {
13250769b2b1SMichael Sartain         Error script_error;
13260769b2b1SMichael Sartain         std::string script_output;
13270769b2b1SMichael Sartain 
13280769b2b1SMichael Sartain         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
13290769b2b1SMichael Sartain         {
13300769b2b1SMichael Sartain             s.Printf("%s", script_output.c_str());
13310769b2b1SMichael Sartain             return true;
13320769b2b1SMichael Sartain         }
13330769b2b1SMichael Sartain         else
13340769b2b1SMichael Sartain         {
13350769b2b1SMichael Sartain             s.Printf("<error: %s>",script_error.AsCString());
13360769b2b1SMichael Sartain         }
13370769b2b1SMichael Sartain     }
13380769b2b1SMichael Sartain     return false;
13390769b2b1SMichael Sartain }
13400769b2b1SMichael Sartain 
13419fc1944eSEnrico Granata static ValueObjectSP
1342c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1343c7bece56SGreg Clayton                          size_t index,
1344b57e4a1bSJason Molenda                          StackFrame* frame,
1345fc7a7f3bSEnrico Granata                          bool deref_pointer)
13469fc1944eSEnrico Granata {
13475160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1348fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1349599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1350599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1351e992a089SEnrico Granata     if (log)
1352599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1353fc7a7f3bSEnrico Granata     const char* first_unparsed;
1354fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1355fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1356fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
135786cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1358599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1359fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1360fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1361fc7a7f3bSEnrico Granata                                                           &final_value_type,
1362fc7a7f3bSEnrico Granata                                                           options,
1363fc7a7f3bSEnrico Granata                                                           &what_next);
1364fc7a7f3bSEnrico Granata     if (!item)
1365fc7a7f3bSEnrico Granata     {
1366e992a089SEnrico Granata         if (log)
1367d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1368e992a089SEnrico Granata                " final_value_type %d",
1369fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1370fc7a7f3bSEnrico Granata     }
13719fc1944eSEnrico Granata     else
13729fc1944eSEnrico Granata     {
1373e992a089SEnrico Granata         if (log)
1374d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1375e992a089SEnrico Granata                " final_value_type %d",
1376fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
13779fc1944eSEnrico Granata     }
13789fc1944eSEnrico Granata     return item;
13799fc1944eSEnrico Granata }
13809fc1944eSEnrico Granata 
13810769b2b1SMichael Sartain static inline bool
13820769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var)
13830769b2b1SMichael Sartain {
13840769b2b1SMichael Sartain     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
13850769b2b1SMichael Sartain }
13860769b2b1SMichael Sartain 
13870769b2b1SMichael Sartain static bool
13880769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
13890769b2b1SMichael Sartain     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
13900769b2b1SMichael Sartain {
13910769b2b1SMichael Sartain     int var_len = strlen(var);
13920769b2b1SMichael Sartain     if (::strncmp (var_name_begin, var, var_len) == 0)
13930769b2b1SMichael Sartain     {
13940769b2b1SMichael Sartain         var_name_begin += var_len;
13950769b2b1SMichael Sartain         if (*var_name_begin == '}')
13960769b2b1SMichael Sartain         {
13970769b2b1SMichael Sartain             format = default_format;
13980769b2b1SMichael Sartain             return true;
13990769b2b1SMichael Sartain         }
14000769b2b1SMichael Sartain         else if (*var_name_begin == '%')
14010769b2b1SMichael Sartain         {
14020769b2b1SMichael Sartain             // Allow format specifiers: x|X|u with optional width specifiers.
14030769b2b1SMichael Sartain             //   ${thread.id%x}    ; hex
14040769b2b1SMichael Sartain             //   ${thread.id%X}    ; uppercase hex
14050769b2b1SMichael Sartain             //   ${thread.id%u}    ; unsigned decimal
14060769b2b1SMichael Sartain             //   ${thread.id%8.8X} ; width.precision + specifier
14070769b2b1SMichael Sartain             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
14080769b2b1SMichael Sartain             int dot_count = 0;
14090769b2b1SMichael Sartain             const char *specifier = NULL;
14100769b2b1SMichael Sartain             int width_precision_length = 0;
14110769b2b1SMichael Sartain             const char *width_precision = ++var_name_begin;
14120769b2b1SMichael Sartain             while (isdigit(*var_name_begin) || *var_name_begin == '.')
14130769b2b1SMichael Sartain             {
14140769b2b1SMichael Sartain                 dot_count += (*var_name_begin == '.');
14150769b2b1SMichael Sartain                 if (dot_count > 1)
14160769b2b1SMichael Sartain                     break;
14170769b2b1SMichael Sartain                 var_name_begin++;
14180769b2b1SMichael Sartain                 width_precision_length++;
14190769b2b1SMichael Sartain             }
14200769b2b1SMichael Sartain 
14210769b2b1SMichael Sartain             if (IsToken (var_name_begin, "tid}"))
14220769b2b1SMichael Sartain             {
14230769b2b1SMichael Sartain                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
14240769b2b1SMichael Sartain                 if (target)
14250769b2b1SMichael Sartain                 {
14260769b2b1SMichael Sartain                     ArchSpec arch (target->GetArchitecture ());
14270769b2b1SMichael Sartain                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
14280769b2b1SMichael Sartain                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
14290769b2b1SMichael Sartain                         specifier = PRIu64;
14300769b2b1SMichael Sartain                 }
14310769b2b1SMichael Sartain                 if (!specifier)
14320769b2b1SMichael Sartain                 {
14330769b2b1SMichael Sartain                     format = default_format;
14340769b2b1SMichael Sartain                     return true;
14350769b2b1SMichael Sartain                 }
14360769b2b1SMichael Sartain             }
14370769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "x}"))
14380769b2b1SMichael Sartain                 specifier = PRIx64;
14390769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "X}"))
14400769b2b1SMichael Sartain                 specifier = PRIX64;
14410769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "u}"))
14420769b2b1SMichael Sartain                 specifier = PRIu64;
14430769b2b1SMichael Sartain 
14440769b2b1SMichael Sartain             if (specifier)
14450769b2b1SMichael Sartain             {
14460769b2b1SMichael Sartain                 format = "%";
14470769b2b1SMichael Sartain                 if (width_precision_length)
14480769b2b1SMichael Sartain                     format += std::string(width_precision, width_precision_length);
14490769b2b1SMichael Sartain                 format += specifier;
14500769b2b1SMichael Sartain                 return true;
14510769b2b1SMichael Sartain             }
14520769b2b1SMichael Sartain         }
14530769b2b1SMichael Sartain     }
14540769b2b1SMichael Sartain     return false;
14550769b2b1SMichael Sartain }
14560769b2b1SMichael Sartain 
1457705b1809SJason Molenda // Find information for the "thread.info.*" specifiers in a format string
1458705b1809SJason Molenda static bool
1459705b1809SJason Molenda FormatThreadExtendedInfoRecurse
1460705b1809SJason Molenda (
1461705b1809SJason Molenda     const char *var_name_begin,
1462705b1809SJason Molenda     StructuredData::ObjectSP thread_info_dictionary,
1463705b1809SJason Molenda     const SymbolContext *sc,
1464705b1809SJason Molenda     const ExecutionContext *exe_ctx,
1465705b1809SJason Molenda     Stream &s
1466705b1809SJason Molenda )
1467705b1809SJason Molenda {
1468705b1809SJason Molenda     bool var_success = false;
1469705b1809SJason Molenda     std::string token_format;
1470705b1809SJason Molenda 
1471705b1809SJason Molenda     llvm::StringRef var_name(var_name_begin);
1472705b1809SJason Molenda     size_t percent_idx = var_name.find('%');
1473705b1809SJason Molenda     size_t close_curly_idx = var_name.find('}');
1474705b1809SJason Molenda     llvm::StringRef path = var_name;
1475705b1809SJason Molenda     llvm::StringRef formatter = var_name;
1476705b1809SJason Molenda 
1477705b1809SJason Molenda     // 'path' will be the dot separated list of objects to transverse up until we hit
1478705b1809SJason Molenda     // a close curly brace, a percent sign, or an end of string.
1479705b1809SJason Molenda     if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
1480705b1809SJason Molenda     {
1481705b1809SJason Molenda         if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
1482705b1809SJason Molenda         {
1483705b1809SJason Molenda             if (percent_idx < close_curly_idx)
1484705b1809SJason Molenda             {
1485705b1809SJason Molenda                 path = var_name.slice(0, percent_idx);
1486705b1809SJason Molenda                 formatter = var_name.substr (percent_idx);
1487705b1809SJason Molenda             }
1488705b1809SJason Molenda             else
1489705b1809SJason Molenda             {
1490705b1809SJason Molenda                 path = var_name.slice(0, close_curly_idx);
1491705b1809SJason Molenda                 formatter = var_name.substr (close_curly_idx);
1492705b1809SJason Molenda             }
1493705b1809SJason Molenda         }
1494705b1809SJason Molenda         else if (percent_idx != llvm::StringRef::npos)
1495705b1809SJason Molenda         {
1496705b1809SJason Molenda             path = var_name.slice(0, percent_idx);
1497705b1809SJason Molenda             formatter = var_name.substr (percent_idx);
1498705b1809SJason Molenda         }
1499705b1809SJason Molenda         else if (close_curly_idx != llvm::StringRef::npos)
1500705b1809SJason Molenda         {
1501705b1809SJason Molenda             path = var_name.slice(0, close_curly_idx);
1502705b1809SJason Molenda             formatter = var_name.substr (close_curly_idx);
1503705b1809SJason Molenda         }
1504705b1809SJason Molenda     }
1505705b1809SJason Molenda 
1506705b1809SJason Molenda     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1507705b1809SJason Molenda 
1508705b1809SJason Molenda     if (value.get())
1509705b1809SJason Molenda     {
1510705b1809SJason Molenda         if (value->GetType() == StructuredData::Type::eTypeInteger)
1511705b1809SJason Molenda         {
1512705b1809SJason Molenda             if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1513705b1809SJason Molenda             {
1514705b1809SJason Molenda                 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
1515705b1809SJason Molenda                 var_success = true;
1516705b1809SJason Molenda             }
1517705b1809SJason Molenda         }
1518705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1519705b1809SJason Molenda         {
1520705b1809SJason Molenda             s.Printf ("%f", value->GetAsFloat()->GetValue());
1521705b1809SJason Molenda             var_success = true;
1522705b1809SJason Molenda         }
1523705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeString)
1524705b1809SJason Molenda         {
1525705b1809SJason Molenda             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1526705b1809SJason Molenda             var_success = true;
1527705b1809SJason Molenda         }
1528705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeArray)
1529705b1809SJason Molenda         {
1530705b1809SJason Molenda             if (value->GetAsArray()->GetSize() > 0)
1531705b1809SJason Molenda             {
1532705b1809SJason Molenda                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1533705b1809SJason Molenda                 var_success = true;
1534705b1809SJason Molenda             }
1535705b1809SJason Molenda         }
1536705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1537705b1809SJason Molenda         {
1538705b1809SJason Molenda             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1539705b1809SJason Molenda             var_success = true;
1540705b1809SJason Molenda         }
1541705b1809SJason Molenda     }
1542705b1809SJason Molenda 
1543705b1809SJason Molenda     return var_success;
1544705b1809SJason Molenda }
1545705b1809SJason Molenda 
1546705b1809SJason Molenda 
1547c3ce7f27SMichael Sartain static bool
1548c3ce7f27SMichael Sartain FormatPromptRecurse
15491b654882SGreg Clayton (
15501b654882SGreg Clayton     const char *format,
15511b654882SGreg Clayton     const SymbolContext *sc,
15521b654882SGreg Clayton     const ExecutionContext *exe_ctx,
15531b654882SGreg Clayton     const Address *addr,
15541b654882SGreg Clayton     Stream &s,
15554becb37eSEnrico Granata     const char **end,
1556c482a192SEnrico Granata     ValueObject* valobj
15571b654882SGreg Clayton )
15581b654882SGreg Clayton {
1559c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
15601b654882SGreg Clayton     bool success = true;
15611b654882SGreg Clayton     const char *p;
15625160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1563c3ce7f27SMichael Sartain 
15641b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
15651b654882SGreg Clayton     {
1566c482a192SEnrico Granata         if (realvalobj)
15674becb37eSEnrico Granata         {
1568c482a192SEnrico Granata             valobj = realvalobj;
1569c482a192SEnrico Granata             realvalobj = NULL;
15704becb37eSEnrico Granata         }
15711b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
15721b654882SGreg Clayton         if (non_special_chars > 0)
15731b654882SGreg Clayton         {
15741b654882SGreg Clayton             if (success)
15751b654882SGreg Clayton                 s.Write (p, non_special_chars);
15761b654882SGreg Clayton             p += non_special_chars;
15771b654882SGreg Clayton         }
15781b654882SGreg Clayton 
15791b654882SGreg Clayton         if (*p == '\0')
15801b654882SGreg Clayton         {
15811b654882SGreg Clayton             break;
15821b654882SGreg Clayton         }
15831b654882SGreg Clayton         else if (*p == '{')
15841b654882SGreg Clayton         {
15851b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
15861b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
15871b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
15881b654882SGreg Clayton             // is one in the symbol context you can use:
15891b654882SGreg Clayton             //      "{function =${function.name}}"
15901b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
15911b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
15921b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
15931b654882SGreg Clayton             // or symbol with a valid name.
15941b654882SGreg Clayton             StreamString sub_strm;
15951b654882SGreg Clayton 
15961b654882SGreg Clayton             ++p;  // Skip the '{'
15971b654882SGreg Clayton 
1598c3ce7f27SMichael Sartain             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
15991b654882SGreg Clayton             {
16001b654882SGreg Clayton                 // The stream had all it needed
16011b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
16021b654882SGreg Clayton             }
16031b654882SGreg Clayton             if (*p != '}')
16041b654882SGreg Clayton             {
16051b654882SGreg Clayton                 success = false;
16061b654882SGreg Clayton                 break;
16071b654882SGreg Clayton             }
16081b654882SGreg Clayton         }
16091b654882SGreg Clayton         else if (*p == '}')
16101b654882SGreg Clayton         {
16111b654882SGreg Clayton             // End of a enclosing scope
16121b654882SGreg Clayton             break;
16131b654882SGreg Clayton         }
16141b654882SGreg Clayton         else if (*p == '$')
16151b654882SGreg Clayton         {
16161b654882SGreg Clayton             // We have a prompt variable to print
16171b654882SGreg Clayton             ++p;
16181b654882SGreg Clayton             if (*p == '{')
16191b654882SGreg Clayton             {
16201b654882SGreg Clayton                 ++p;
16211b654882SGreg Clayton                 const char *var_name_begin = p;
16221b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
16231b654882SGreg Clayton 
16241b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
16251b654882SGreg Clayton                 {
16261b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
16271b654882SGreg Clayton                     if (success)
16281b654882SGreg Clayton                     {
16291b654882SGreg Clayton                         const char *cstr = NULL;
16300769b2b1SMichael Sartain                         std::string token_format;
16311b654882SGreg Clayton                         Address format_addr;
16321b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
16331b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
16341b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
16351b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
16361b654882SGreg Clayton                         FileSpec format_file_spec;
1637e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
16381b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
16399fc1944eSEnrico Granata                         bool do_deref_pointer = false;
164086cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
164186cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
16421b654882SGreg Clayton 
16431b654882SGreg Clayton                         // Each variable must set success to true below...
16441b654882SGreg Clayton                         bool var_success = false;
16451b654882SGreg Clayton                         switch (var_name_begin[0])
16461b654882SGreg Clayton                         {
16474becb37eSEnrico Granata                         case '*':
16486f3533fbSEnrico Granata                         case 'v':
16496f3533fbSEnrico Granata                         case 's':
16504becb37eSEnrico Granata                             {
1651c482a192SEnrico Granata                                 if (!valobj)
165234132754SGreg Clayton                                     break;
16536f3533fbSEnrico Granata 
1654c3e320a7SEnrico Granata                                 if (log)
1655d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1656c3e320a7SEnrico Granata 
16576f3533fbSEnrico Granata                                 // check for *var and *svar
16586f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
16596f3533fbSEnrico Granata                                 {
16609fc1944eSEnrico Granata                                     do_deref_pointer = true;
16619fc1944eSEnrico Granata                                     var_name_begin++;
1662c3e320a7SEnrico Granata                                     if (log)
166368ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
166468ae4117SEnrico Granata                                 }
1665c3e320a7SEnrico Granata 
16666f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
16674becb37eSEnrico Granata                                 {
1668c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
166986cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
167086cc9829SEnrico Granata                                     if (!valobj)
167186cc9829SEnrico Granata                                         break;
16726f3533fbSEnrico Granata                                     var_name_begin++;
1673c3e320a7SEnrico Granata                                     if (log)
167468ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
167568ae4117SEnrico Granata                                 }
1676c3e320a7SEnrico Granata 
16776f3533fbSEnrico Granata                                 // should be a 'v' by now
16786f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
16796f3533fbSEnrico Granata                                     break;
16806f3533fbSEnrico Granata 
1681c3e320a7SEnrico Granata                                 if (log)
168268ae4117SEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1683c3e320a7SEnrico Granata 
1684fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
168586cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1686fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
16878c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
168886cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
168934132754SGreg Clayton                                 ValueObject* target = NULL;
16904d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
169134132754SGreg Clayton                                 const char* var_name_final = NULL;
16929fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
169334132754SGreg Clayton                                 const char* close_bracket_position = NULL;
169434132754SGreg Clayton                                 int64_t index_lower = -1;
169534132754SGreg Clayton                                 int64_t index_higher = -1;
16969fc1944eSEnrico Granata                                 bool is_array_range = false;
1697fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
169885933ed4SEnrico Granata                                 bool was_plain_var = false;
169985933ed4SEnrico Granata                                 bool was_var_format = false;
1700a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1701fc7a7f3bSEnrico Granata 
1702c482a192SEnrico Granata                                 if (!valobj) break;
1703c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
17040769b2b1SMichael Sartain                                 if (IsToken (var_name_begin, "var}"))
17050a3958e0SEnrico Granata                                 {
170685933ed4SEnrico Granata                                     was_plain_var = true;
1707c482a192SEnrico Granata                                     target = valobj;
170886cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17090a3958e0SEnrico Granata                                 }
17100769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin,"var%"))
17119fc1944eSEnrico Granata                                 {
171285933ed4SEnrico Granata                                     was_var_format = true;
17139fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
17149fc1944eSEnrico Granata                                     const char* percent_position;
1715c482a192SEnrico Granata                                     target = valobj;
171686cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17179fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17189fc1944eSEnrico Granata                                                           var_name_end,
17199fc1944eSEnrico Granata                                                           &var_name_final,
17209fc1944eSEnrico Granata                                                           &percent_position,
17219fc1944eSEnrico Granata                                                           &custom_format,
17229fc1944eSEnrico Granata                                                           &val_obj_display);
17230a3958e0SEnrico Granata                                 }
17249fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
17250769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin, "var"))
17269fc1944eSEnrico Granata                                 {
17270769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "var["))
1728a777dc2aSEnrico Granata                                         was_var_indexed = true;
17299fc1944eSEnrico Granata                                     const char* percent_position;
17309fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17319fc1944eSEnrico Granata                                                           var_name_end,
17329fc1944eSEnrico Granata                                                           &var_name_final,
17339fc1944eSEnrico Granata                                                           &percent_position,
17349fc1944eSEnrico Granata                                                           &custom_format,
17359fc1944eSEnrico Granata                                                           &val_obj_display);
17369fc1944eSEnrico Granata 
17379fc1944eSEnrico Granata                                     const char* open_bracket_position;
17389fc1944eSEnrico Granata                                     const char* separator_position;
17399fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
17409fc1944eSEnrico Granata                                                         var_name_end,
17419fc1944eSEnrico Granata                                                         var_name_final,
17429fc1944eSEnrico Granata                                                         &open_bracket_position,
17439fc1944eSEnrico Granata                                                         &separator_position,
17449fc1944eSEnrico Granata                                                         &close_bracket_position,
17459fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
17469fc1944eSEnrico Granata                                                         &index_lower,
17479fc1944eSEnrico Granata                                                         &index_higher);
17489fc1944eSEnrico Granata 
17499fc1944eSEnrico Granata                                     Error error;
17509fc1944eSEnrico Granata 
1751599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1752599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1753fc7a7f3bSEnrico Granata 
1754e992a089SEnrico Granata                                     if (log)
1755599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1756fc7a7f3bSEnrico Granata 
1757599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1758fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1759fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1760fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1761fc7a7f3bSEnrico Granata                                                                              options,
1762fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1763fc7a7f3bSEnrico Granata 
1764fc7a7f3bSEnrico Granata                                     if (!target)
17659fc1944eSEnrico Granata                                     {
1766e992a089SEnrico Granata                                         if (log)
1767d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1768e992a089SEnrico Granata                                                " final_value_type %d",
1769fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1770fc7a7f3bSEnrico Granata                                         break;
17710a3958e0SEnrico Granata                                     }
1772a7187d00SEnrico Granata                                     else
1773fc7a7f3bSEnrico Granata                                     {
1774e992a089SEnrico Granata                                         if (log)
1775d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1776e992a089SEnrico Granata                                                " final_value_type %d",
1777fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1778a7187d00SEnrico Granata                                     }
17790a3958e0SEnrico Granata                                 }
17800a3958e0SEnrico Granata                                 else
17810a3958e0SEnrico Granata                                     break;
17829fc1944eSEnrico Granata 
178386cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
178486cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1785fc7a7f3bSEnrico Granata 
178686cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1787fc7a7f3bSEnrico Granata 
1788a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
17890a3958e0SEnrico Granata                                 {
17909fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
17919fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
17929fc1944eSEnrico Granata                                     // to get to the target ValueObject
17939fc1944eSEnrico Granata                                     Error error;
17949fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1795dc940730SEnrico Granata                                     if (error.Fail())
1796dc940730SEnrico Granata                                     {
1797dc940730SEnrico Granata                                         if (log)
1798d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1799dc940730SEnrico Granata                                         break;
1800dc940730SEnrico Granata                                     }
18019fc1944eSEnrico Granata                                     do_deref_pointer = false;
18020a3958e0SEnrico Granata                                 }
18030a3958e0SEnrico Granata 
1804f164d940SJim Ingham                                 if (!target)
1805f164d940SJim Ingham                                 {
1806f164d940SJim Ingham                                     if (log)
1807f164d940SJim Ingham                                         log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
1808f164d940SJim Ingham                                     break;
1809f164d940SJim Ingham                                 }
1810f164d940SJim Ingham 
1811a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1812a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1813a777dc2aSEnrico Granata                                 // us into an endless recursion
1814a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1815a777dc2aSEnrico Granata                                 {
1816a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1817a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1818a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1819a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1820a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1821a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1822a777dc2aSEnrico Granata                                 }
1823a777dc2aSEnrico Granata 
182485933ed4SEnrico Granata                                 // TODO use flags for these
182557ee3067SGreg Clayton                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
182657ee3067SGreg Clayton                                 bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0;
182757ee3067SGreg Clayton                                 bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0;
182857ee3067SGreg Clayton                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1829f4efecd9SEnrico Granata 
183086cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1831f4efecd9SEnrico Granata                                 {
183285933ed4SEnrico Granata                                     StreamString str_temp;
1833e992a089SEnrico Granata                                     if (log)
1834d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1835d64d0bc0SEnrico Granata 
18365088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1837d64d0bc0SEnrico Granata                                     {
1838f4efecd9SEnrico Granata                                         // try to use the special cases
183985933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
184085933ed4SEnrico Granata                                                                                           val_obj_display,
184185933ed4SEnrico Granata                                                                                           custom_format);
1842e992a089SEnrico Granata                                         if (log)
1843d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1844d64d0bc0SEnrico Granata 
1845d64d0bc0SEnrico Granata                                         // should not happen
18465088c486SGreg Clayton                                         if (var_success)
184785933ed4SEnrico Granata                                             s << str_temp.GetData();
1848d64d0bc0SEnrico Granata                                         var_success = true;
1849d64d0bc0SEnrico Granata                                         break;
1850d64d0bc0SEnrico Granata                                     }
1851d64d0bc0SEnrico Granata                                     else
1852d64d0bc0SEnrico Granata                                     {
185388da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1854d64d0bc0SEnrico Granata                                         {
1855d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1856d64d0bc0SEnrico Granata                                         }
185788da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
185888da35f8SEnrico Granata                                         {
185923f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
186088da35f8SEnrico Granata                                                                                  val_obj_display,
186186cc9829SEnrico Granata                                                                                  custom_format,
186286cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
186388da35f8SEnrico Granata                                         }
1864d64d0bc0SEnrico Granata                                         var_success = true;
1865d64d0bc0SEnrico Granata                                         break;
1866d64d0bc0SEnrico Granata                                     }
1867d64d0bc0SEnrico Granata                                 }
1868d64d0bc0SEnrico Granata 
1869d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1870d64d0bc0SEnrico Granata                                 // type @ location message
1871d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1872d64d0bc0SEnrico Granata                                 {
1873d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1874d64d0bc0SEnrico Granata                                     var_success = true;
187585933ed4SEnrico Granata                                     break;
187685933ed4SEnrico Granata                                 }
187785933ed4SEnrico Granata 
1878d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
187986cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
188085933ed4SEnrico Granata                                 {
188185933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
188285933ed4SEnrico Granata                                     var_success = true;
1883f4efecd9SEnrico Granata                                     break;
1884f4efecd9SEnrico Granata                                 }
1885f4efecd9SEnrico Granata 
18869fc1944eSEnrico Granata                                 if (!is_array_range)
1887e992a089SEnrico Granata                                 {
1888e992a089SEnrico Granata                                     if (log)
1889d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
18909fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1891e992a089SEnrico Granata                                 }
18929fc1944eSEnrico Granata                                 else
18939fc1944eSEnrico Granata                                 {
1894e992a089SEnrico Granata                                     if (log)
1895d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
18969fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
18979fc1944eSEnrico Granata                                         break;
1898e992a089SEnrico Granata                                     if (log)
1899d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1900fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1901fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
19020a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
19030a3958e0SEnrico Granata                                     {
1904fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1905fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1906fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1907fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1908fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1909fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
19100a3958e0SEnrico Granata                                     }
19110a3958e0SEnrico Granata 
19120a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
19130a3958e0SEnrico Granata                                     s.PutChar('[');
19140a3958e0SEnrico Granata                                     var_success = true;
19150a3958e0SEnrico Granata 
19169fc1944eSEnrico Granata                                     if (index_higher < 0)
1917c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
19180a3958e0SEnrico Granata 
1919cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
192022c55d18SEnrico Granata 
19210a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
19220a3958e0SEnrico Granata                                     {
1923fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
19249fc1944eSEnrico Granata                                                                                      index_lower,
1925c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1926fc7a7f3bSEnrico Granata                                                                                      false).get();
19270a3958e0SEnrico Granata 
1928fc7a7f3bSEnrico Granata                                         if (!item)
1929fc7a7f3bSEnrico Granata                                         {
1930e992a089SEnrico Granata                                             if (log)
1931d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1932fc7a7f3bSEnrico Granata                                         }
1933fc7a7f3bSEnrico Granata                                         else
1934fc7a7f3bSEnrico Granata                                         {
1935e992a089SEnrico Granata                                             if (log)
1936d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1937fc7a7f3bSEnrico Granata                                         }
1938fc7a7f3bSEnrico Granata 
19390a3958e0SEnrico Granata                                         if (!special_directions)
19409fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
19410a3958e0SEnrico Granata                                         else
1942c3ce7f27SMichael Sartain                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item);
19430a3958e0SEnrico Granata 
194422c55d18SEnrico Granata                                         if (--max_num_children == 0)
194522c55d18SEnrico Granata                                         {
194622c55d18SEnrico Granata                                             s.PutCString(", ...");
194722c55d18SEnrico Granata                                             break;
194822c55d18SEnrico Granata                                         }
194922c55d18SEnrico Granata 
19500a3958e0SEnrico Granata                                         if (index_lower < index_higher)
19510a3958e0SEnrico Granata                                             s.PutChar(',');
19520a3958e0SEnrico Granata                                     }
19530a3958e0SEnrico Granata                                     s.PutChar(']');
19544becb37eSEnrico Granata                                 }
19554becb37eSEnrico Granata                             }
195634132754SGreg Clayton                             break;
19571b654882SGreg Clayton                         case 'a':
19580769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "addr}"))
19591b654882SGreg Clayton                             {
19601b654882SGreg Clayton                                 if (addr && addr->IsValid())
19611b654882SGreg Clayton                                 {
19621b654882SGreg Clayton                                     var_success = true;
19631b654882SGreg Clayton                                     format_addr = *addr;
19641b654882SGreg Clayton                                 }
19651b654882SGreg Clayton                             }
19661b654882SGreg Clayton                             break;
19671b654882SGreg Clayton 
19681b654882SGreg Clayton                         case 'p':
19690769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "process."))
19701b654882SGreg Clayton                             {
1971c14ee32dSGreg Clayton                                 if (exe_ctx)
1972c14ee32dSGreg Clayton                                 {
1973c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
1974c14ee32dSGreg Clayton                                     if (process)
19751b654882SGreg Clayton                                     {
19761b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
19770769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
19781b654882SGreg Clayton                                         {
19790769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), process->GetID());
19801b654882SGreg Clayton                                             var_success = true;
19811b654882SGreg Clayton                                         }
19820769b2b1SMichael Sartain                                         else if ((IsToken (var_name_begin, "name}")) ||
19830769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.basename}")) ||
19840769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.fullpath}")))
19851b654882SGreg Clayton                                         {
1986c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1987aa149cbdSGreg Clayton                                             if (exe_module)
19881b654882SGreg Clayton                                             {
19891b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
19901b654882SGreg Clayton                                                 {
1991aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
19929076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
19931b654882SGreg Clayton                                                 }
19941b654882SGreg Clayton                                                 else
19951b654882SGreg Clayton                                                 {
1996aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
19979076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
19981b654882SGreg Clayton                                                 }
19991b654882SGreg Clayton                                             }
20001b654882SGreg Clayton                                         }
20010769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2002aad8e480SEnrico Granata                                         {
2003aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2004aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2005aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
20060769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
2007aad8e480SEnrico Granata                                                 var_success = true;
2008aad8e480SEnrico Granata                                         }
20091b654882SGreg Clayton                                     }
20101b654882SGreg Clayton                                 }
2011c14ee32dSGreg Clayton                             }
20121b654882SGreg Clayton                             break;
20131b654882SGreg Clayton 
20141b654882SGreg Clayton                         case 't':
20150769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "thread."))
20161b654882SGreg Clayton                             {
2017c14ee32dSGreg Clayton                                 if (exe_ctx)
2018c14ee32dSGreg Clayton                                 {
2019c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
2020c14ee32dSGreg Clayton                                     if (thread)
20211b654882SGreg Clayton                                     {
20221b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
20230769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
20241b654882SGreg Clayton                                         {
20250769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetID());
20261b654882SGreg Clayton                                             var_success = true;
20271b654882SGreg Clayton                                         }
20280769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2029160c9d81SGreg Clayton                                         {
20300769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
2031160c9d81SGreg Clayton                                             var_success = true;
2032160c9d81SGreg Clayton                                         }
20330769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
20341b654882SGreg Clayton                                         {
20350769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
20361b654882SGreg Clayton                                             var_success = true;
20371b654882SGreg Clayton                                         }
20380769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "name}"))
20391b654882SGreg Clayton                                         {
2040c14ee32dSGreg Clayton                                             cstr = thread->GetName();
20411b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20421b654882SGreg Clayton                                             if (var_success)
20431b654882SGreg Clayton                                                 s.PutCString(cstr);
20441b654882SGreg Clayton                                         }
20450769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "queue}"))
20461b654882SGreg Clayton                                         {
2047c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
20481b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20491b654882SGreg Clayton                                             if (var_success)
20501b654882SGreg Clayton                                                 s.PutCString(cstr);
20511b654882SGreg Clayton                                         }
20520769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "stop-reason}"))
20531b654882SGreg Clayton                                         {
2054c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20555d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
20561b654882SGreg Clayton                                             {
2057b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
20581b654882SGreg Clayton                                                 if (cstr && cstr[0])
20591b654882SGreg Clayton                                                 {
20601b654882SGreg Clayton                                                     s.PutCString(cstr);
20611b654882SGreg Clayton                                                     var_success = true;
20621b654882SGreg Clayton                                                 }
20631b654882SGreg Clayton                                             }
20641b654882SGreg Clayton                                         }
20650769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "return-value}"))
206673ca05a2SJim Ingham                                         {
206773ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20685d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
206973ca05a2SJim Ingham                                             {
207073ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
207173ca05a2SJim Ingham                                                 if (return_valobj_sp)
207273ca05a2SJim Ingham                                                 {
20734d93b8cdSEnrico Granata                                                     return_valobj_sp->Dump(s);
207473ca05a2SJim Ingham                                                     var_success = true;
207573ca05a2SJim Ingham                                                 }
207673ca05a2SJim Ingham                                             }
207773ca05a2SJim Ingham                                         }
20780769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2079aad8e480SEnrico Granata                                         {
2080aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2081aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2082aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
20830769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2084aad8e480SEnrico Granata                                                 var_success = true;
2085aad8e480SEnrico Granata                                         }
2086705b1809SJason Molenda                                         else if (IsToken (var_name_begin, "info."))
2087705b1809SJason Molenda                                         {
2088705b1809SJason Molenda                                             var_name_begin += ::strlen("info.");
2089705b1809SJason Molenda                                             StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
2090705b1809SJason Molenda                                             if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
2091705b1809SJason Molenda                                             {
2092705b1809SJason Molenda                                                 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
2093705b1809SJason Molenda                                             }
2094705b1809SJason Molenda                                         }
2095aad8e480SEnrico Granata                                     }
2096aad8e480SEnrico Granata                                 }
209773ca05a2SJim Ingham                             }
20980769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "target."))
20991b654882SGreg Clayton                             {
210067cc0636SGreg Clayton                                 // TODO: hookup properties
210167cc0636SGreg Clayton //                                if (!target_properties_sp)
210267cc0636SGreg Clayton //                                {
210367cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
210467cc0636SGreg Clayton //                                    if (target)
210567cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
210667cc0636SGreg Clayton //                                }
210767cc0636SGreg Clayton //
210867cc0636SGreg Clayton //                                if (target_properties_sp)
210967cc0636SGreg Clayton //                                {
211067cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
211167cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
211267cc0636SGreg Clayton //                                    if (end_property)
211367cc0636SGreg Clayton //                                    {
211467cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
211567cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
211667cc0636SGreg Clayton //                                        if (!property_value.empty())
211767cc0636SGreg Clayton //                                        {
211867cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
211967cc0636SGreg Clayton //                                            var_success = true;
212067cc0636SGreg Clayton //                                        }
212167cc0636SGreg Clayton //                                    }
212267cc0636SGreg Clayton //                                }
21230603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
21240603aa9dSGreg Clayton                                 if (target)
21251b654882SGreg Clayton                                 {
21261b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
21270769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "arch}"))
21281b654882SGreg Clayton                                     {
21291b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
21301b654882SGreg Clayton                                         if (arch.IsValid())
21311b654882SGreg Clayton                                         {
213264195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
21331b654882SGreg Clayton                                             var_success = true;
21341b654882SGreg Clayton                                         }
21351b654882SGreg Clayton                                     }
21360769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "script:"))
2137aad8e480SEnrico Granata                                     {
2138aad8e480SEnrico Granata                                         var_name_begin += ::strlen("script:");
2139aad8e480SEnrico Granata                                         std::string script_name(var_name_begin,var_name_end);
2140aad8e480SEnrico Granata                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
21410769b2b1SMichael Sartain                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2142aad8e480SEnrico Granata                                             var_success = true;
2143aad8e480SEnrico Granata                                     }
21441b654882SGreg Clayton                                 }
21451b654882SGreg Clayton                             }
21461b654882SGreg Clayton                             break;
21471b654882SGreg Clayton 
21481b654882SGreg Clayton 
21491b654882SGreg Clayton                         case 'm':
21500769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "module."))
21511b654882SGreg Clayton                             {
21520603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
21531b654882SGreg Clayton                                 {
21540603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
21551b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
21561b654882SGreg Clayton 
21570769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
21581b654882SGreg Clayton                                     {
21591b654882SGreg Clayton                                         if (module->GetFileSpec())
21601b654882SGreg Clayton                                         {
21611b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
21621b654882SGreg Clayton 
21630769b2b1SMichael Sartain                                             if (IsToken (var_name_begin, "basename}"))
21641b654882SGreg Clayton                                             {
21651b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
21669076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
21671b654882SGreg Clayton                                             }
21680769b2b1SMichael Sartain                                             else if (IsToken (var_name_begin, "fullpath}"))
21691b654882SGreg Clayton                                             {
21701b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
21719076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
21721b654882SGreg Clayton                                             }
21731b654882SGreg Clayton                                         }
21741b654882SGreg Clayton                                     }
21751b654882SGreg Clayton                                 }
21761b654882SGreg Clayton                             }
21771b654882SGreg Clayton                             break;
21781b654882SGreg Clayton 
21791b654882SGreg Clayton 
21801b654882SGreg Clayton                         case 'f':
21810769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "file."))
21821b654882SGreg Clayton                             {
21831b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
21841b654882SGreg Clayton                                 {
21851b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
21861b654882SGreg Clayton 
21870769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "basename}"))
21881b654882SGreg Clayton                                     {
21891b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
21909076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
21911b654882SGreg Clayton                                     }
21920769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "fullpath}"))
21931b654882SGreg Clayton                                     {
21941b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
21959076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
21961b654882SGreg Clayton                                     }
21971b654882SGreg Clayton                                 }
21981b654882SGreg Clayton                             }
21990769b2b1SMichael Sartain                            else if (IsToken (var_name_begin, "frame."))
22001b654882SGreg Clayton                             {
2201c14ee32dSGreg Clayton                                 if (exe_ctx)
2202c14ee32dSGreg Clayton                                 {
2203b57e4a1bSJason Molenda                                     StackFrame *frame = exe_ctx->GetFramePtr();
2204c14ee32dSGreg Clayton                                     if (frame)
22051b654882SGreg Clayton                                     {
22061b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
22070769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "index}"))
22081b654882SGreg Clayton                                         {
2209c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
22101b654882SGreg Clayton                                             var_success = true;
22111b654882SGreg Clayton                                         }
22120769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "pc}"))
22131b654882SGreg Clayton                                         {
22141b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22151b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
22161b654882SGreg Clayton                                             var_success = true;
22171b654882SGreg Clayton                                         }
22180769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "sp}"))
22191b654882SGreg Clayton                                         {
22201b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22211b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
22221b654882SGreg Clayton                                             var_success = true;
22231b654882SGreg Clayton                                         }
22240769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fp}"))
22251b654882SGreg Clayton                                         {
22261b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22271b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
22281b654882SGreg Clayton                                             var_success = true;
22291b654882SGreg Clayton                                         }
22300769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "flags}"))
22311b654882SGreg Clayton                                         {
22321b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22331b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
22341b654882SGreg Clayton                                             var_success = true;
22351b654882SGreg Clayton                                         }
22360769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "reg."))
22371b654882SGreg Clayton                                         {
2238c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
22391b654882SGreg Clayton                                             if (reg_ctx)
22401b654882SGreg Clayton                                             {
22411b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
22421b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
22431b654882SGreg Clayton                                                 {
22441b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
22451b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
22461b654882SGreg Clayton                                                     if (reg_info)
22471b654882SGreg Clayton                                                         var_success = true;
22481b654882SGreg Clayton                                                 }
22491b654882SGreg Clayton                                             }
22501b654882SGreg Clayton                                         }
22510769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2252aad8e480SEnrico Granata                                         {
2253aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2254aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2255aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
22560769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2257aad8e480SEnrico Granata                                                 var_success = true;
2258aad8e480SEnrico Granata                                         }
2259aad8e480SEnrico Granata                                     }
2260aad8e480SEnrico Granata                                 }
22611b654882SGreg Clayton                             }
22620769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "function."))
22631b654882SGreg Clayton                             {
22641b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
22651b654882SGreg Clayton                                 {
22661b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
22670769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "id}"))
22681b654882SGreg Clayton                                     {
22691b654882SGreg Clayton                                         if (sc->function)
2270d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
22711b654882SGreg Clayton                                         else
22721b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
22731b654882SGreg Clayton 
22741b654882SGreg Clayton                                         var_success = true;
22751b654882SGreg Clayton                                     }
22760769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name}"))
22771b654882SGreg Clayton                                     {
22781b654882SGreg Clayton                                         if (sc->function)
22791b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
22801b654882SGreg Clayton                                         else if (sc->symbol)
22811b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
22821b654882SGreg Clayton                                         if (cstr)
22831b654882SGreg Clayton                                         {
22841b654882SGreg Clayton                                             s.PutCString(cstr);
22850d9c9934SGreg Clayton 
22860d9c9934SGreg Clayton                                             if (sc->block)
22870d9c9934SGreg Clayton                                             {
22880d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
22890d9c9934SGreg Clayton                                                 if (inline_block)
22900d9c9934SGreg Clayton                                                 {
22910d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
22920d9c9934SGreg Clayton                                                     if (inline_info)
22930d9c9934SGreg Clayton                                                     {
22940d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
22950d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
22960d9c9934SGreg Clayton                                                     }
22970d9c9934SGreg Clayton                                                 }
22980d9c9934SGreg Clayton                                             }
22991b654882SGreg Clayton                                             var_success = true;
23001b654882SGreg Clayton                                         }
23011b654882SGreg Clayton                                     }
23020769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name-with-args}"))
23036d3dbf51SGreg Clayton                                     {
23046d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
23056d3dbf51SGreg Clayton 
23066d3dbf51SGreg Clayton                                         if (sc->function)
23076d3dbf51SGreg Clayton                                         {
23086d3dbf51SGreg Clayton                                             var_success = true;
23096d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
23106d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
23116d3dbf51SGreg Clayton                                             if (cstr)
23126d3dbf51SGreg Clayton                                             {
23136d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
23146d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
23156d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
23166d3dbf51SGreg Clayton                                                 if (sc->block)
23176d3dbf51SGreg Clayton                                                 {
23186d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
23196d3dbf51SGreg Clayton 
23206d3dbf51SGreg Clayton                                                     if (inline_block)
23216d3dbf51SGreg Clayton                                                     {
23226d3dbf51SGreg Clayton                                                         get_function_vars = false;
23236d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
23246d3dbf51SGreg Clayton                                                         if (inline_info)
23256d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
23266d3dbf51SGreg Clayton                                                     }
23276d3dbf51SGreg Clayton                                                 }
23286d3dbf51SGreg Clayton 
23296d3dbf51SGreg Clayton                                                 if (get_function_vars)
23306d3dbf51SGreg Clayton                                                 {
23316d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
23326d3dbf51SGreg Clayton                                                 }
23336d3dbf51SGreg Clayton 
23346d3dbf51SGreg Clayton                                                 if (inline_info)
23356d3dbf51SGreg Clayton                                                 {
23366d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
23376d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
23386d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
23396d3dbf51SGreg Clayton                                                 }
23406d3dbf51SGreg Clayton 
23416d3dbf51SGreg Clayton                                                 VariableList args;
23426d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2343cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
23446d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
23456d3dbf51SGreg Clayton                                                 {
23466d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
23476d3dbf51SGreg Clayton                                                     const char *close_paren = NULL;
23486d3dbf51SGreg Clayton                                                     if (open_paren)
2349855958caSGreg Clayton                                                     {
23500769b2b1SMichael Sartain                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2351855958caSGreg Clayton                                                         {
2352855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2353855958caSGreg Clayton                                                             if (open_paren)
23546d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2355855958caSGreg Clayton                                                         }
2356855958caSGreg Clayton                                                         else
2357855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2358855958caSGreg Clayton                                                     }
23596d3dbf51SGreg Clayton 
23606d3dbf51SGreg Clayton                                                     if (open_paren)
23616d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
23626d3dbf51SGreg Clayton                                                     else
23636d3dbf51SGreg Clayton                                                     {
23646d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
23656d3dbf51SGreg Clayton                                                         s.PutChar ('(');
23666d3dbf51SGreg Clayton                                                     }
23675b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
23686d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
23696d3dbf51SGreg Clayton                                                     {
2370894f7359SEnrico Granata                                                         std::string buffer;
2371894f7359SEnrico Granata 
23726d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
23736d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2374894f7359SEnrico Granata                                                         const char *var_representation = nullptr;
23756d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
2376894f7359SEnrico Granata                                                         if (var_value_sp->GetClangType().IsAggregateType() &&
2377894f7359SEnrico Granata                                                             DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
2378894f7359SEnrico Granata                                                         {
2379894f7359SEnrico Granata                                                             static StringSummaryFormat format(TypeSummaryImpl::Flags()
2380894f7359SEnrico Granata                                                                                               .SetHideItemNames(false)
2381894f7359SEnrico Granata                                                                                               .SetShowMembersOneLiner(true),
2382894f7359SEnrico Granata                                                                                               "");
2383894f7359SEnrico Granata                                                             format.FormatObject(var_value_sp.get(), buffer);
2384894f7359SEnrico Granata                                                             var_representation = buffer.c_str();
2385894f7359SEnrico Granata                                                         }
2386894f7359SEnrico Granata                                                         else
2387894f7359SEnrico Granata                                                             var_representation = var_value_sp->GetValueAsCString();
23886d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
23896d3dbf51SGreg Clayton                                                             s.PutCString (", ");
23903b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2391cc7f9bf5SEnrico Granata                                                         {
2392894f7359SEnrico Granata                                                             if (var_representation)
2393894f7359SEnrico Granata                                                                 s.Printf ("%s=%s", var_name, var_representation);
23943b188b17SGreg Clayton                                                             else
2395cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2396cc7f9bf5SEnrico Granata                                                         }
2397cc7f9bf5SEnrico Granata                                                         else
23983b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
23996d3dbf51SGreg Clayton                                                     }
24006d3dbf51SGreg Clayton 
24016d3dbf51SGreg Clayton                                                     if (close_paren)
24026d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
24036d3dbf51SGreg Clayton                                                     else
24046d3dbf51SGreg Clayton                                                         s.PutChar(')');
24056d3dbf51SGreg Clayton 
24066d3dbf51SGreg Clayton                                                 }
24076d3dbf51SGreg Clayton                                                 else
24086d3dbf51SGreg Clayton                                                 {
24096d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
24106d3dbf51SGreg Clayton                                                 }
24116d3dbf51SGreg Clayton                                             }
24126d3dbf51SGreg Clayton                                         }
24136d3dbf51SGreg Clayton                                         else if (sc->symbol)
24146d3dbf51SGreg Clayton                                         {
24156d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
24166d3dbf51SGreg Clayton                                             if (cstr)
24176d3dbf51SGreg Clayton                                             {
24186d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
24196d3dbf51SGreg Clayton                                                 var_success = true;
24206d3dbf51SGreg Clayton                                             }
24216d3dbf51SGreg Clayton                                         }
24226d3dbf51SGreg Clayton                                     }
24230769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "addr-offset}"))
24241b654882SGreg Clayton                                     {
24251b654882SGreg Clayton                                         var_success = addr != NULL;
24261b654882SGreg Clayton                                         if (var_success)
24271b654882SGreg Clayton                                         {
24281b654882SGreg Clayton                                             format_addr = *addr;
24291b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
24301b654882SGreg Clayton                                         }
24311b654882SGreg Clayton                                     }
24320769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "line-offset}"))
24331b654882SGreg Clayton                                     {
24341b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
24351b654882SGreg Clayton                                         if (var_success)
24361b654882SGreg Clayton                                         {
24371b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
24381b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
24391b654882SGreg Clayton                                         }
24401b654882SGreg Clayton                                     }
24410769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "pc-offset}"))
24421b654882SGreg Clayton                                     {
2443b57e4a1bSJason Molenda                                         StackFrame *frame = exe_ctx->GetFramePtr();
2444c14ee32dSGreg Clayton                                         var_success = frame != NULL;
24451b654882SGreg Clayton                                         if (var_success)
24461b654882SGreg Clayton                                         {
2447c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
24481b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
24491b654882SGreg Clayton                                         }
24501b654882SGreg Clayton                                     }
24511b654882SGreg Clayton                                 }
24521b654882SGreg Clayton                             }
24531b654882SGreg Clayton                             break;
24541b654882SGreg Clayton 
24551b654882SGreg Clayton                         case 'l':
24560769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "line."))
24571b654882SGreg Clayton                             {
24581b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
24591b654882SGreg Clayton                                 {
24601b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
24610769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
24621b654882SGreg Clayton                                     {
24631b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
24641b654882SGreg Clayton 
24650769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "basename}"))
24661b654882SGreg Clayton                                         {
24671b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
24689076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
24691b654882SGreg Clayton                                         }
24700769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fullpath}"))
24711b654882SGreg Clayton                                         {
24721b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
24739076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
24741b654882SGreg Clayton                                         }
24751b654882SGreg Clayton                                     }
24760769b2b1SMichael Sartain                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
24771b654882SGreg Clayton                                     {
24781b654882SGreg Clayton                                         var_success = true;
24790769b2b1SMichael Sartain                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
24801b654882SGreg Clayton                                     }
24810769b2b1SMichael Sartain                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
24820769b2b1SMichael Sartain                                              (IsToken (var_name_begin, "end-addr}")))
24831b654882SGreg Clayton                                     {
24841b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
24851b654882SGreg Clayton                                         if (var_success)
24861b654882SGreg Clayton                                         {
24871b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
24881b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
24891b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
24901b654882SGreg Clayton                                         }
24911b654882SGreg Clayton                                     }
24921b654882SGreg Clayton                                 }
24931b654882SGreg Clayton                             }
24941b654882SGreg Clayton                             break;
24951b654882SGreg Clayton                         }
24961b654882SGreg Clayton 
24971b654882SGreg Clayton                         if (var_success)
24981b654882SGreg Clayton                         {
24991b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
25001b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
25011b654882SGreg Clayton                             {
2502b57e4a1bSJason Molenda                                 StackFrame *frame = exe_ctx->GetFramePtr();
25031b654882SGreg Clayton                                 // We have a register value to display...
25041b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
25051b654882SGreg Clayton                                 {
2506c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
25071b654882SGreg Clayton                                 }
25081b654882SGreg Clayton                                 else
25091b654882SGreg Clayton                                 {
25101b654882SGreg Clayton                                     if (reg_ctx == NULL)
2511c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
25121b654882SGreg Clayton 
25131b654882SGreg Clayton                                     if (reg_ctx)
25141b654882SGreg Clayton                                     {
25151b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
25161b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
25171b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
25181b654882SGreg Clayton                                         var_success = reg_info != NULL;
25191b654882SGreg Clayton                                     }
25201b654882SGreg Clayton                                 }
25211b654882SGreg Clayton                             }
25221b654882SGreg Clayton 
25231b654882SGreg Clayton                             if (reg_info != NULL)
25241b654882SGreg Clayton                             {
25257349bd90SGreg Clayton                                 RegisterValue reg_value;
25267349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
25277349bd90SGreg Clayton                                 if (var_success)
25281b654882SGreg Clayton                                 {
25299a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
25301b654882SGreg Clayton                                 }
25311b654882SGreg Clayton                             }
25321b654882SGreg Clayton 
25331b654882SGreg Clayton                             if (format_file_spec)
25341b654882SGreg Clayton                             {
25351b654882SGreg Clayton                                 s << format_file_spec;
25361b654882SGreg Clayton                             }
25371b654882SGreg Clayton 
25381b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
25391b654882SGreg Clayton                             if (format_addr.IsValid())
25401b654882SGreg Clayton                             {
25410603aa9dSGreg Clayton                                 var_success = false;
25420603aa9dSGreg Clayton 
25431b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
25441b654882SGreg Clayton                                 {
25451b654882SGreg Clayton                                     Address func_addr;
25460603aa9dSGreg Clayton 
25470603aa9dSGreg Clayton                                     if (sc)
25480603aa9dSGreg Clayton                                     {
25491b654882SGreg Clayton                                         if (sc->function)
25500d9c9934SGreg Clayton                                         {
25511b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
25520d9c9934SGreg Clayton                                             if (sc->block)
25530d9c9934SGreg Clayton                                             {
25540d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
25550d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
25560d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
25570d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
25580d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
25590d9c9934SGreg Clayton                                                 AddressRange inline_range;
25600d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
25610d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
25620d9c9934SGreg Clayton                                             }
25630d9c9934SGreg Clayton                                         }
2564e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2565e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
25660603aa9dSGreg Clayton                                     }
25671b654882SGreg Clayton 
25680603aa9dSGreg Clayton                                     if (func_addr.IsValid())
25691b654882SGreg Clayton                                     {
25701b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
25711b654882SGreg Clayton                                         {
25721b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
25731b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
25741b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2575d01b2953SDaniel Malea                                                 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
25761b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2577d01b2953SDaniel Malea                                                 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
25780603aa9dSGreg Clayton                                             var_success = true;
25791b654882SGreg Clayton                                         }
25801b654882SGreg Clayton                                         else
25810603aa9dSGreg Clayton                                         {
25820603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
25830603aa9dSGreg Clayton                                             if (target)
25840603aa9dSGreg Clayton                                             {
25850603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
25860603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
25870603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2588d01b2953SDaniel Malea                                                     s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
25890603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2590d01b2953SDaniel Malea                                                     s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
25910603aa9dSGreg Clayton                                                 var_success = true;
25920603aa9dSGreg Clayton                                             }
25930603aa9dSGreg Clayton                                         }
25941b654882SGreg Clayton                                     }
25951b654882SGreg Clayton                                 }
25961b654882SGreg Clayton                                 else
25971b654882SGreg Clayton                                 {
25980603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
25991b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
26000603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
26010603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
26021b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
26031b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
26041b654882SGreg Clayton 
26051b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
26060603aa9dSGreg Clayton                                     {
2607514487e8SGreg Clayton                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
260835f1a0d5SGreg Clayton                                         if (addr_width == 0)
260935f1a0d5SGreg Clayton                                             addr_width = 16;
2610d01b2953SDaniel Malea                                         s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
26110603aa9dSGreg Clayton                                         var_success = true;
26120603aa9dSGreg Clayton                                     }
26131b654882SGreg Clayton                                 }
26141b654882SGreg Clayton                             }
26151b654882SGreg Clayton                         }
26161b654882SGreg Clayton 
26171b654882SGreg Clayton                         if (var_success == false)
26181b654882SGreg Clayton                             success = false;
26191b654882SGreg Clayton                     }
26201b654882SGreg Clayton                     p = var_name_end;
26211b654882SGreg Clayton                 }
26221b654882SGreg Clayton                 else
26231b654882SGreg Clayton                     break;
26241b654882SGreg Clayton             }
26251b654882SGreg Clayton             else
26261b654882SGreg Clayton             {
26271b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
26281b654882SGreg Clayton                 s.PutChar(*p);
26291b654882SGreg Clayton             }
26301b654882SGreg Clayton         }
26311b654882SGreg Clayton         else if (*p == '\\')
26321b654882SGreg Clayton         {
26331b654882SGreg Clayton             ++p; // skip the slash
26341b654882SGreg Clayton             switch (*p)
26351b654882SGreg Clayton             {
26361b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
26371b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
26381b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
26391b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
26401b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
26411b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
26421b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
26431b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
26441b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
26451b654882SGreg Clayton             case '0':
26461b654882SGreg Clayton                 // 1 to 3 octal chars
26471b654882SGreg Clayton                 {
26480603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
26490603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
26500603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
26510603aa9dSGreg Clayton 
26520603aa9dSGreg Clayton                     int i;
26530603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
26540603aa9dSGreg Clayton                         oct_str[i] = p[i];
26550603aa9dSGreg Clayton 
26560603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
26570603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
26580603aa9dSGreg Clayton                     // one less than i (even if i is zero)
26590603aa9dSGreg Clayton                     p += i - 1;
26600603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
26610603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
26621b654882SGreg Clayton                     {
2663c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
26641b654882SGreg Clayton                     }
26651b654882SGreg Clayton                 }
26661b654882SGreg Clayton                 break;
26671b654882SGreg Clayton 
26681b654882SGreg Clayton             case 'x':
26691b654882SGreg Clayton                 // hex number in the format
26700603aa9dSGreg Clayton                 if (isxdigit(p[1]))
26711b654882SGreg Clayton                 {
26720603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
26731b654882SGreg Clayton 
26740603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
26750603aa9dSGreg Clayton                     // NULL terminator
26761b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
26771b654882SGreg Clayton                     hex_str[0] = *p;
26780603aa9dSGreg Clayton                     if (isxdigit(p[1]))
26790603aa9dSGreg Clayton                     {
26800603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
26811b654882SGreg Clayton                         hex_str[1] = *p;
26820603aa9dSGreg Clayton                     }
26830603aa9dSGreg Clayton 
26841b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
26850603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2686c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
26871b654882SGreg Clayton                 }
26881b654882SGreg Clayton                 else
26891b654882SGreg Clayton                 {
26900603aa9dSGreg Clayton                     s.PutChar('x');
26911b654882SGreg Clayton                 }
26921b654882SGreg Clayton                 break;
26931b654882SGreg Clayton 
26941b654882SGreg Clayton             default:
26950603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
26960603aa9dSGreg Clayton                 // came after the '\'
26970603aa9dSGreg Clayton                 s << *p;
26981b654882SGreg Clayton                 break;
26991b654882SGreg Clayton 
27001b654882SGreg Clayton             }
27011b654882SGreg Clayton 
27021b654882SGreg Clayton         }
27031b654882SGreg Clayton     }
27041b654882SGreg Clayton     if (end)
27051b654882SGreg Clayton         *end = p;
27061b654882SGreg Clayton     return success;
27071b654882SGreg Clayton }
27081b654882SGreg Clayton 
2709c3ce7f27SMichael Sartain bool
2710c3ce7f27SMichael Sartain Debugger::FormatPrompt
2711c3ce7f27SMichael Sartain (
2712c3ce7f27SMichael Sartain     const char *format,
2713c3ce7f27SMichael Sartain     const SymbolContext *sc,
2714c3ce7f27SMichael Sartain     const ExecutionContext *exe_ctx,
2715c3ce7f27SMichael Sartain     const Address *addr,
2716c3ce7f27SMichael Sartain     Stream &s,
2717c3ce7f27SMichael Sartain     ValueObject* valobj
2718c3ce7f27SMichael Sartain )
2719c3ce7f27SMichael Sartain {
2720c3ce7f27SMichael Sartain     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2721c3ce7f27SMichael Sartain     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2722c3ce7f27SMichael Sartain     if (format_str.length())
2723c3ce7f27SMichael Sartain         format = format_str.c_str();
2724c3ce7f27SMichael Sartain     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj);
2725c3ce7f27SMichael Sartain }
2726c3ce7f27SMichael Sartain 
2727228063cdSJim Ingham void
2728228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2729228063cdSJim Ingham {
27304f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
27314f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
27324f02b22dSJim Ingham     // callback.
2733228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2734228063cdSJim Ingham }
2735228063cdSJim Ingham 
2736228063cdSJim Ingham bool
2737228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2738228063cdSJim Ingham {
2739228063cdSJim Ingham     Log::Callbacks log_callbacks;
2740228063cdSJim Ingham 
2741228063cdSJim Ingham     StreamSP log_stream_sp;
27429a028519SSean Callanan     if (m_log_callback_stream_sp)
2743228063cdSJim Ingham     {
2744228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2745228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2746228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2747228063cdSJim Ingham     }
2748228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2749228063cdSJim Ingham     {
275044d93782SGreg Clayton         log_stream_sp = GetOutputFile();
2751228063cdSJim Ingham     }
2752228063cdSJim Ingham     else
2753228063cdSJim Ingham     {
2754228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2755c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2756c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2757c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2758228063cdSJim Ingham         {
2759228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2760228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2761228063cdSJim Ingham         }
2762228063cdSJim Ingham     }
2763228063cdSJim Ingham     assert (log_stream_sp.get());
2764228063cdSJim Ingham 
2765228063cdSJim Ingham     if (log_options == 0)
2766228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2767228063cdSJim Ingham 
276857abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2769228063cdSJim Ingham     {
2770228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2771228063cdSJim Ingham         return true;
2772228063cdSJim Ingham     }
2773228063cdSJim Ingham     else
2774228063cdSJim Ingham     {
2775228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2776228063cdSJim Ingham         if (log_channel_sp)
2777228063cdSJim Ingham         {
2778228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2779228063cdSJim Ingham             {
2780228063cdSJim Ingham                 return true;
2781228063cdSJim Ingham             }
2782228063cdSJim Ingham             else
2783228063cdSJim Ingham             {
2784228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2785228063cdSJim Ingham                 return false;
2786228063cdSJim Ingham             }
2787228063cdSJim Ingham         }
2788228063cdSJim Ingham         else
2789228063cdSJim Ingham         {
2790228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2791228063cdSJim Ingham             return false;
2792228063cdSJim Ingham         }
2793228063cdSJim Ingham     }
2794228063cdSJim Ingham     return false;
2795228063cdSJim Ingham }
2796228063cdSJim Ingham 
27979585fbfcSGreg Clayton SourceManager &
27989585fbfcSGreg Clayton Debugger::GetSourceManager ()
27999585fbfcSGreg Clayton {
28009585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
28019585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
28029585fbfcSGreg Clayton     return *m_source_manager_ap;
28039585fbfcSGreg Clayton }
28049585fbfcSGreg Clayton 
28059585fbfcSGreg Clayton 
280644d93782SGreg Clayton 
280744d93782SGreg Clayton // This function handles events that were broadcast by the process.
280844d93782SGreg Clayton void
280944d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
281044d93782SGreg Clayton {
281144d93782SGreg Clayton     using namespace lldb;
281244d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
281344d93782SGreg Clayton 
281444d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
281544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
281644d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
281744d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
281844d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
281944d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
282044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
282144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
282244d93782SGreg Clayton //    {
282344d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
282444d93782SGreg Clayton //    }
282544d93782SGreg Clayton //
282644d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
282744d93782SGreg Clayton     {
282844d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
282944d93782SGreg Clayton         if (num_new_locations > 0)
283044d93782SGreg Clayton         {
283144d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
283244d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
283344d93782SGreg Clayton             if (output_sp)
283444d93782SGreg Clayton             {
283544d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
283644d93782SGreg Clayton                                   num_new_locations,
283744d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
283844d93782SGreg Clayton                                   breakpoint->GetID());
283944d93782SGreg Clayton                 RefreshTopIOHandler();
284044d93782SGreg Clayton             }
284144d93782SGreg Clayton         }
284244d93782SGreg Clayton     }
284344d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
284444d93782SGreg Clayton //    {
284544d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
284644d93782SGreg Clayton //    }
284744d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
284844d93782SGreg Clayton //    {
284944d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
285044d93782SGreg Clayton //    }
285144d93782SGreg Clayton }
285244d93782SGreg Clayton 
285344d93782SGreg Clayton size_t
285444d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
285544d93782SGreg Clayton {
285644d93782SGreg Clayton     size_t total_bytes = 0;
285744d93782SGreg Clayton     if (stream == NULL)
285844d93782SGreg Clayton         stream = GetOutputFile().get();
285944d93782SGreg Clayton 
286044d93782SGreg Clayton     if (stream)
286144d93782SGreg Clayton     {
286244d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
286344d93782SGreg Clayton         if (process == NULL)
286444d93782SGreg Clayton         {
286544d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
286644d93782SGreg Clayton             if (target_sp)
286744d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
286844d93782SGreg Clayton         }
286944d93782SGreg Clayton         if (process)
287044d93782SGreg Clayton         {
287144d93782SGreg Clayton             Error error;
287244d93782SGreg Clayton             size_t len;
287344d93782SGreg Clayton             char stdio_buffer[1024];
287444d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
287544d93782SGreg Clayton             {
287644d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
287744d93782SGreg Clayton                 total_bytes += len;
287844d93782SGreg Clayton             }
287944d93782SGreg Clayton         }
288044d93782SGreg Clayton         stream->Flush();
288144d93782SGreg Clayton     }
288244d93782SGreg Clayton     return total_bytes;
288344d93782SGreg Clayton }
288444d93782SGreg Clayton 
288544d93782SGreg Clayton size_t
288644d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
288744d93782SGreg Clayton {
288844d93782SGreg Clayton     size_t total_bytes = 0;
288944d93782SGreg Clayton     if (stream == NULL)
289044d93782SGreg Clayton         stream = GetOutputFile().get();
289144d93782SGreg Clayton 
289244d93782SGreg Clayton     if (stream)
289344d93782SGreg Clayton     {
289444d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
289544d93782SGreg Clayton         if (process == NULL)
289644d93782SGreg Clayton         {
289744d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
289844d93782SGreg Clayton             if (target_sp)
289944d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
290044d93782SGreg Clayton         }
290144d93782SGreg Clayton         if (process)
290244d93782SGreg Clayton         {
290344d93782SGreg Clayton             Error error;
290444d93782SGreg Clayton             size_t len;
290544d93782SGreg Clayton             char stdio_buffer[1024];
290644d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
290744d93782SGreg Clayton             {
290844d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
290944d93782SGreg Clayton                 total_bytes += len;
291044d93782SGreg Clayton             }
291144d93782SGreg Clayton         }
291244d93782SGreg Clayton         stream->Flush();
291344d93782SGreg Clayton     }
291444d93782SGreg Clayton     return total_bytes;
291544d93782SGreg Clayton }
291644d93782SGreg Clayton 
291744d93782SGreg Clayton // This function handles events that were broadcast by the process.
291844d93782SGreg Clayton void
291944d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
292044d93782SGreg Clayton {
292144d93782SGreg Clayton     using namespace lldb;
292244d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
292344d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
292444d93782SGreg Clayton 
2925b4874f1aSGreg Clayton     StreamString output_stream;
2926b4874f1aSGreg Clayton     StreamString error_stream;
292744d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
292844d93782SGreg Clayton 
2929b4874f1aSGreg Clayton     if (!gui_enabled)
2930b4874f1aSGreg Clayton     {
2931b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
293244d93782SGreg Clayton         assert (process_sp);
293344d93782SGreg Clayton 
2934b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
293544d93782SGreg Clayton         {
2936b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
293744d93782SGreg Clayton         }
2938b4874f1aSGreg Clayton 
2939b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
294044d93782SGreg Clayton         {
2941b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
294244d93782SGreg Clayton         }
2943b4874f1aSGreg Clayton 
2944b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
294544d93782SGreg Clayton         {
2946b4874f1aSGreg Clayton 
294744d93782SGreg Clayton             // Drain all stout and stderr so we don't see any output come after
294844d93782SGreg Clayton             // we print our prompts
294944d93782SGreg Clayton             // Something changed in the process;  get the event and report the process's current status and location to
295044d93782SGreg Clayton             // the user.
295144d93782SGreg Clayton             StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
295244d93782SGreg Clayton             if (event_state == eStateInvalid)
295344d93782SGreg Clayton                 return;
295444d93782SGreg Clayton 
295544d93782SGreg Clayton             switch (event_state)
295644d93782SGreg Clayton             {
295744d93782SGreg Clayton                 case eStateInvalid:
295844d93782SGreg Clayton                 case eStateUnloaded:
295944d93782SGreg Clayton                 case eStateConnected:
296044d93782SGreg Clayton                 case eStateAttaching:
296144d93782SGreg Clayton                 case eStateLaunching:
296244d93782SGreg Clayton                 case eStateStepping:
296344d93782SGreg Clayton                 case eStateDetached:
296444d93782SGreg Clayton                     {
2965b4874f1aSGreg Clayton                         output_stream.Printf("Process %" PRIu64 " %s\n",
296644d93782SGreg Clayton                                              process_sp->GetID(),
296744d93782SGreg Clayton                                              StateAsCString (event_state));
2968b4874f1aSGreg Clayton 
2969b4874f1aSGreg Clayton                         if (event_state == eStateDetached)
2970b4874f1aSGreg Clayton                             pop_process_io_handler = true;
297144d93782SGreg Clayton                     }
297244d93782SGreg Clayton                     break;
297344d93782SGreg Clayton 
297444d93782SGreg Clayton                 case eStateRunning:
297544d93782SGreg Clayton                     // Don't be chatty when we run...
297644d93782SGreg Clayton                     break;
297744d93782SGreg Clayton 
297844d93782SGreg Clayton                 case eStateExited:
2979b4874f1aSGreg Clayton                     process_sp->GetStatus(output_stream);
2980b4874f1aSGreg Clayton                     pop_process_io_handler = true;
298144d93782SGreg Clayton                     break;
298244d93782SGreg Clayton 
298344d93782SGreg Clayton                 case eStateStopped:
298444d93782SGreg Clayton                 case eStateCrashed:
298544d93782SGreg Clayton                 case eStateSuspended:
298644d93782SGreg Clayton                     // Make sure the program hasn't been auto-restarted:
298744d93782SGreg Clayton                     if (Process::ProcessEventData::GetRestartedFromEvent (event_sp.get()))
298844d93782SGreg Clayton                     {
298944d93782SGreg Clayton                         size_t num_reasons = Process::ProcessEventData::GetNumRestartedReasons(event_sp.get());
299044d93782SGreg Clayton                         if (num_reasons > 0)
299144d93782SGreg Clayton                         {
299244d93782SGreg Clayton                             // FIXME: Do we want to report this, or would that just be annoyingly chatty?
299344d93782SGreg Clayton                             if (num_reasons == 1)
299444d93782SGreg Clayton                             {
299544d93782SGreg Clayton                                 const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), 0);
2996b4874f1aSGreg Clayton                                 output_stream.Printf("Process %" PRIu64 " stopped and restarted: %s\n",
299744d93782SGreg Clayton                                                      process_sp->GetID(),
299844d93782SGreg Clayton                                                      reason ? reason : "<UNKNOWN REASON>");
299944d93782SGreg Clayton                             }
300044d93782SGreg Clayton                             else
300144d93782SGreg Clayton                             {
3002b4874f1aSGreg Clayton                                 output_stream.Printf("Process %" PRIu64 " stopped and restarted, reasons:\n",
300344d93782SGreg Clayton                                                      process_sp->GetID());
300444d93782SGreg Clayton 
300544d93782SGreg Clayton 
300644d93782SGreg Clayton                                 for (size_t i = 0; i < num_reasons; i++)
300744d93782SGreg Clayton                                 {
300844d93782SGreg Clayton                                     const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), i);
3009b4874f1aSGreg Clayton                                     output_stream.Printf("\t%s\n", reason ? reason : "<UNKNOWN REASON>");
301044d93782SGreg Clayton                                 }
301144d93782SGreg Clayton                             }
301244d93782SGreg Clayton                         }
301344d93782SGreg Clayton                     }
301444d93782SGreg Clayton                     else
301544d93782SGreg Clayton                     {
30164a65fb1fSJim Ingham                         // Lock the thread list so it doesn't change on us, this is the scope for the locker:
30174a65fb1fSJim Ingham                         {
301844d93782SGreg Clayton                             ThreadList &thread_list = process_sp->GetThreadList();
301944d93782SGreg Clayton                             Mutex::Locker locker (thread_list.GetMutex());
302044d93782SGreg Clayton 
302144d93782SGreg Clayton                             ThreadSP curr_thread (thread_list.GetSelectedThread());
302244d93782SGreg Clayton                             ThreadSP thread;
302344d93782SGreg Clayton                             StopReason curr_thread_stop_reason = eStopReasonInvalid;
302444d93782SGreg Clayton                             if (curr_thread)
302544d93782SGreg Clayton                                 curr_thread_stop_reason = curr_thread->GetStopReason();
3026c809cbcfSGreg Clayton                             if (!curr_thread ||
3027c809cbcfSGreg Clayton                                 !curr_thread->IsValid() ||
302844d93782SGreg Clayton                                 curr_thread_stop_reason == eStopReasonInvalid ||
302944d93782SGreg Clayton                                 curr_thread_stop_reason == eStopReasonNone)
303044d93782SGreg Clayton                             {
303144d93782SGreg Clayton                                 // Prefer a thread that has just completed its plan over another thread as current thread.
303244d93782SGreg Clayton                                 ThreadSP plan_thread;
303344d93782SGreg Clayton                                 ThreadSP other_thread;
303444d93782SGreg Clayton                                 const size_t num_threads = thread_list.GetSize();
303544d93782SGreg Clayton                                 size_t i;
303644d93782SGreg Clayton                                 for (i = 0; i < num_threads; ++i)
303744d93782SGreg Clayton                                 {
303844d93782SGreg Clayton                                     thread = thread_list.GetThreadAtIndex(i);
303944d93782SGreg Clayton                                     StopReason thread_stop_reason = thread->GetStopReason();
304044d93782SGreg Clayton                                     switch (thread_stop_reason)
304144d93782SGreg Clayton                                     {
304244d93782SGreg Clayton                                         case eStopReasonInvalid:
304344d93782SGreg Clayton                                         case eStopReasonNone:
304444d93782SGreg Clayton                                             break;
304544d93782SGreg Clayton 
304644d93782SGreg Clayton                                         case eStopReasonTrace:
304744d93782SGreg Clayton                                         case eStopReasonBreakpoint:
304844d93782SGreg Clayton                                         case eStopReasonWatchpoint:
304944d93782SGreg Clayton                                         case eStopReasonSignal:
305044d93782SGreg Clayton                                         case eStopReasonException:
305144d93782SGreg Clayton                                         case eStopReasonExec:
305244d93782SGreg Clayton                                         case eStopReasonThreadExiting:
305344d93782SGreg Clayton                                             if (!other_thread)
305444d93782SGreg Clayton                                                 other_thread = thread;
305544d93782SGreg Clayton                                             break;
305644d93782SGreg Clayton                                         case eStopReasonPlanComplete:
305744d93782SGreg Clayton                                             if (!plan_thread)
305844d93782SGreg Clayton                                                 plan_thread = thread;
305944d93782SGreg Clayton                                             break;
306044d93782SGreg Clayton                                     }
306144d93782SGreg Clayton                                 }
306244d93782SGreg Clayton                                 if (plan_thread)
306344d93782SGreg Clayton                                     thread_list.SetSelectedThreadByID (plan_thread->GetID());
306444d93782SGreg Clayton                                 else if (other_thread)
306544d93782SGreg Clayton                                     thread_list.SetSelectedThreadByID (other_thread->GetID());
306644d93782SGreg Clayton                                 else
306744d93782SGreg Clayton                                 {
30684046a30cSJim Ingham                                     if (curr_thread && curr_thread->IsValid())
306944d93782SGreg Clayton                                         thread = curr_thread;
307044d93782SGreg Clayton                                     else
307144d93782SGreg Clayton                                         thread = thread_list.GetThreadAtIndex(0);
307244d93782SGreg Clayton 
307344d93782SGreg Clayton                                     if (thread)
307444d93782SGreg Clayton                                         thread_list.SetSelectedThreadByID (thread->GetID());
307544d93782SGreg Clayton                                 }
307644d93782SGreg Clayton                             }
30774a65fb1fSJim Ingham                         }
30784a65fb1fSJim Ingham                         // Drop the ThreadList mutex by here, since GetThreadStatus below might have to run code,
30794a65fb1fSJim Ingham                         // e.g. for Data formatters, and if we hold the ThreadList mutex, then the process is going to
30804a65fb1fSJim Ingham                         // have a hard time restarting the process.
308144d93782SGreg Clayton 
308244d93782SGreg Clayton                         if (GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget())
308344d93782SGreg Clayton                         {
308444d93782SGreg Clayton                             const bool only_threads_with_stop_reason = true;
308544d93782SGreg Clayton                             const uint32_t start_frame = 0;
308644d93782SGreg Clayton                             const uint32_t num_frames = 1;
308744d93782SGreg Clayton                             const uint32_t num_frames_with_source = 1;
3088b4874f1aSGreg Clayton                             process_sp->GetStatus(output_stream);
3089b4874f1aSGreg Clayton                             process_sp->GetThreadStatus (output_stream,
309044d93782SGreg Clayton                                                          only_threads_with_stop_reason,
309144d93782SGreg Clayton                                                          start_frame,
309244d93782SGreg Clayton                                                          num_frames,
309344d93782SGreg Clayton                                                          num_frames_with_source);
309444d93782SGreg Clayton                         }
309544d93782SGreg Clayton                         else
309644d93782SGreg Clayton                         {
309744d93782SGreg Clayton                             uint32_t target_idx = GetTargetList().GetIndexOfTarget(process_sp->GetTarget().shared_from_this());
309844d93782SGreg Clayton                             if (target_idx != UINT32_MAX)
3099b4874f1aSGreg Clayton                                 output_stream.Printf ("Target %d: (", target_idx);
310044d93782SGreg Clayton                             else
3101b4874f1aSGreg Clayton                                 output_stream.Printf ("Target <unknown index>: (");
3102b4874f1aSGreg Clayton                             process_sp->GetTarget().Dump (&output_stream, eDescriptionLevelBrief);
3103b4874f1aSGreg Clayton                             output_stream.Printf (") stopped.\n");
310444d93782SGreg Clayton                         }
3105b4874f1aSGreg Clayton 
3106b4874f1aSGreg Clayton                         // Pop the process IO handler
3107b4874f1aSGreg Clayton                         pop_process_io_handler = true;
310844d93782SGreg Clayton                     }
310944d93782SGreg Clayton                     break;
311044d93782SGreg Clayton             }
311144d93782SGreg Clayton         }
3112b4874f1aSGreg Clayton 
3113b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
3114b4874f1aSGreg Clayton         {
3115b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
31166fea17e8SGreg Clayton             bool top_io_handler_hid = false;
31176fea17e8SGreg Clayton 
31186fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
31196fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
3120b4874f1aSGreg Clayton 
3121b4874f1aSGreg Clayton             if (output_stream.GetSize())
3122b4874f1aSGreg Clayton             {
3123b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
3124b4874f1aSGreg Clayton                 if (output_stream_sp)
3125b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
3126b4874f1aSGreg Clayton             }
3127b4874f1aSGreg Clayton 
3128b4874f1aSGreg Clayton             if (error_stream.GetSize())
3129b4874f1aSGreg Clayton             {
3130b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
3131b4874f1aSGreg Clayton                 if (error_stream_sp)
3132b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
313344d93782SGreg Clayton             }
313444d93782SGreg Clayton 
313544d93782SGreg Clayton             if (top_io_handler_hid)
313644d93782SGreg Clayton                 RefreshTopIOHandler();
313744d93782SGreg Clayton         }
313844d93782SGreg Clayton 
3139b4874f1aSGreg Clayton         if (pop_process_io_handler)
3140b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
3141b4874f1aSGreg Clayton     }
3142b4874f1aSGreg Clayton }
3143b4874f1aSGreg Clayton 
314444d93782SGreg Clayton void
314544d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
314644d93782SGreg Clayton {
314744d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
314844d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
314944d93782SGreg Clayton     using namespace lldb;
315044d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
315144d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
315244d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
315344d93782SGreg Clayton     {
315444d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
315544d93782SGreg Clayton         if (thread_sp)
315644d93782SGreg Clayton         {
315744d93782SGreg Clayton             HideTopIOHandler();
315844d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
315944d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
316044d93782SGreg Clayton             RefreshTopIOHandler();
316144d93782SGreg Clayton         }
316244d93782SGreg Clayton     }
316344d93782SGreg Clayton }
316444d93782SGreg Clayton 
316544d93782SGreg Clayton bool
316644d93782SGreg Clayton Debugger::IsForwardingEvents ()
316744d93782SGreg Clayton {
316844d93782SGreg Clayton     return (bool)m_forward_listener_sp;
316944d93782SGreg Clayton }
317044d93782SGreg Clayton 
317144d93782SGreg Clayton void
317244d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
317344d93782SGreg Clayton {
317444d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
317544d93782SGreg Clayton }
317644d93782SGreg Clayton 
317744d93782SGreg Clayton void
317844d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
317944d93782SGreg Clayton {
318044d93782SGreg Clayton     m_forward_listener_sp.reset();
318144d93782SGreg Clayton }
318244d93782SGreg Clayton 
318344d93782SGreg Clayton 
318444d93782SGreg Clayton void
318544d93782SGreg Clayton Debugger::DefaultEventHandler()
318644d93782SGreg Clayton {
318744d93782SGreg Clayton     Listener& listener(GetListener());
318844d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
318944d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
319044d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
319144d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
319244d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
319344d93782SGreg Clayton 
319444d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
319544d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
319644d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
319744d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
319844d93782SGreg Clayton 
319944d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
320044d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
320144d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
320244d93782SGreg Clayton 
320344d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
320444d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
320544d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
320644d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
320744d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
320844d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
320944d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
321044d93782SGreg Clayton 
321144d93782SGreg Clayton     bool done = false;
321244d93782SGreg Clayton     while (!done)
321344d93782SGreg Clayton     {
321444d93782SGreg Clayton //        Mutex::Locker locker;
321544d93782SGreg Clayton //        if (locker.TryLock(m_input_reader_stack.GetMutex()))
321644d93782SGreg Clayton //        {
321744d93782SGreg Clayton //            if (m_input_reader_stack.IsEmpty())
321844d93782SGreg Clayton //                break;
321944d93782SGreg Clayton //        }
322044d93782SGreg Clayton //
322144d93782SGreg Clayton         EventSP event_sp;
322244d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
322344d93782SGreg Clayton         {
322444d93782SGreg Clayton             if (event_sp)
322544d93782SGreg Clayton             {
322644d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
322744d93782SGreg Clayton                 if (broadcaster)
322844d93782SGreg Clayton                 {
322944d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
323044d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
323144d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
323244d93782SGreg Clayton                     {
323344d93782SGreg Clayton                         HandleProcessEvent (event_sp);
323444d93782SGreg Clayton                     }
323544d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
323644d93782SGreg Clayton                     {
323744d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
323844d93782SGreg Clayton                         {
323944d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
324044d93782SGreg Clayton                         }
324144d93782SGreg Clayton                     }
324244d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
324344d93782SGreg Clayton                     {
324444d93782SGreg Clayton                         HandleThreadEvent (event_sp);
324544d93782SGreg Clayton                     }
324644d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
324744d93782SGreg Clayton                     {
324844d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
324944d93782SGreg Clayton                         {
325044d93782SGreg Clayton                             done = true;
325144d93782SGreg Clayton                         }
325244d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
325344d93782SGreg Clayton                         {
325444d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
325544d93782SGreg Clayton                             if (data && data[0])
325644d93782SGreg Clayton                             {
325744d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
325844d93782SGreg Clayton                                 if (error_sp)
325944d93782SGreg Clayton                                 {
326044d93782SGreg Clayton                                     HideTopIOHandler();
326144d93782SGreg Clayton                                     error_sp->PutCString(data);
326244d93782SGreg Clayton                                     error_sp->Flush();
326344d93782SGreg Clayton                                     RefreshTopIOHandler();
326444d93782SGreg Clayton                                 }
326544d93782SGreg Clayton                             }
326644d93782SGreg Clayton                         }
326744d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
326844d93782SGreg Clayton                         {
326944d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
327044d93782SGreg Clayton                             if (data && data[0])
327144d93782SGreg Clayton                             {
327244d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
327344d93782SGreg Clayton                                 if (output_sp)
327444d93782SGreg Clayton                                 {
327544d93782SGreg Clayton                                     HideTopIOHandler();
327644d93782SGreg Clayton                                     output_sp->PutCString(data);
327744d93782SGreg Clayton                                     output_sp->Flush();
327844d93782SGreg Clayton                                     RefreshTopIOHandler();
327944d93782SGreg Clayton                                 }
328044d93782SGreg Clayton                             }
328144d93782SGreg Clayton                         }
328244d93782SGreg Clayton                     }
328344d93782SGreg Clayton                 }
328444d93782SGreg Clayton 
328544d93782SGreg Clayton                 if (m_forward_listener_sp)
328644d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
328744d93782SGreg Clayton             }
328844d93782SGreg Clayton         }
328944d93782SGreg Clayton     }
329044d93782SGreg Clayton }
329144d93782SGreg Clayton 
329244d93782SGreg Clayton lldb::thread_result_t
329344d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
329444d93782SGreg Clayton {
329544d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
329644d93782SGreg Clayton     return NULL;
329744d93782SGreg Clayton }
329844d93782SGreg Clayton 
329944d93782SGreg Clayton bool
330044d93782SGreg Clayton Debugger::StartEventHandlerThread()
330144d93782SGreg Clayton {
330244d93782SGreg Clayton     if (!IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread))
330344d93782SGreg Clayton         m_event_handler_thread = Host::ThreadCreate("lldb.debugger.event-handler", EventHandlerThread, this, NULL);
330444d93782SGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread);
330544d93782SGreg Clayton }
330644d93782SGreg Clayton 
330744d93782SGreg Clayton void
330844d93782SGreg Clayton Debugger::StopEventHandlerThread()
330944d93782SGreg Clayton {
331044d93782SGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread))
331144d93782SGreg Clayton     {
331244d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
331344d93782SGreg Clayton         Host::ThreadJoin(m_event_handler_thread, NULL, NULL);
331444d93782SGreg Clayton         m_event_handler_thread = LLDB_INVALID_HOST_THREAD;
331544d93782SGreg Clayton     }
331644d93782SGreg Clayton }
331744d93782SGreg Clayton 
331844d93782SGreg Clayton 
331944d93782SGreg Clayton lldb::thread_result_t
332044d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
332144d93782SGreg Clayton {
332244d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
332344d93782SGreg Clayton     debugger->ExecuteIOHanders();
332444d93782SGreg Clayton     debugger->StopEventHandlerThread();
332544d93782SGreg Clayton     return NULL;
332644d93782SGreg Clayton }
332744d93782SGreg Clayton 
332844d93782SGreg Clayton bool
332944d93782SGreg Clayton Debugger::StartIOHandlerThread()
333044d93782SGreg Clayton {
333144d93782SGreg Clayton     if (!IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread))
333244d93782SGreg Clayton         m_io_handler_thread = Host::ThreadCreate("lldb.debugger.io-handler", IOHandlerThread, this, NULL);
333344d93782SGreg Clayton     return IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread);
333444d93782SGreg Clayton }
333544d93782SGreg Clayton 
333644d93782SGreg Clayton void
333744d93782SGreg Clayton Debugger::StopIOHandlerThread()
333844d93782SGreg Clayton {
333944d93782SGreg Clayton     if (IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread))
334044d93782SGreg Clayton     {
334144d93782SGreg Clayton         if (m_input_file_sp)
334244d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
334344d93782SGreg Clayton         Host::ThreadJoin(m_io_handler_thread, NULL, NULL);
334444d93782SGreg Clayton         m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
334544d93782SGreg Clayton     }
334644d93782SGreg Clayton }
334744d93782SGreg Clayton 
334844d93782SGreg Clayton 
3349