1180740Sdes//===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
2180740Sdes//
3180740Sdes//                     The LLVM Compiler Infrastructure
4180740Sdes//
5180740Sdes// This file is distributed under the University of Illinois Open Source
6180740Sdes// License. See LICENSE.TXT for details.
7180740Sdes//
8180740Sdes//===----------------------------------------------------------------------===//
9180740Sdes
10180746Sdes#include "lldb/lldb-python.h"
11180746Sdes
12180746Sdes#include "lldb/API/SBDebugger.h"
13180740Sdes
14180740Sdes#include "lldb/Core/Debugger.h"
15180740Sdes
16180740Sdes#include <map>
17180740Sdes
18180740Sdes#include "clang/AST/DeclCXX.h"
19180740Sdes#include "clang/AST/Type.h"
20180740Sdes
21180740Sdes#include "lldb/lldb-private.h"
22180740Sdes#include "lldb/Core/ConnectionFileDescriptor.h"
23180740Sdes#include "lldb/Core/InputReader.h"
24180740Sdes#include "lldb/Core/Module.h"
25180746Sdes#include "lldb/Core/PluginManager.h"
26180746Sdes#include "lldb/Core/RegisterValue.h"
27180746Sdes#include "lldb/Core/State.h"
28180740Sdes#include "lldb/Core/StreamAsynchronousIO.h"
29180740Sdes#include "lldb/Core/StreamCallback.h"
30180740Sdes#include "lldb/Core/StreamString.h"
31180740Sdes#include "lldb/Core/Timer.h"
32180740Sdes#include "lldb/Core/ValueObject.h"
33180740Sdes#include "lldb/Core/ValueObjectVariable.h"
34180740Sdes#include "lldb/DataFormatters/DataVisualization.h"
35180740Sdes#include "lldb/DataFormatters/FormatManager.h"
36180740Sdes#include "lldb/Host/DynamicLibrary.h"
37180740Sdes#include "lldb/Host/Terminal.h"
38180740Sdes#include "lldb/Interpreter/CommandInterpreter.h"
39180740Sdes#include "lldb/Interpreter/OptionValueSInt64.h"
40180740Sdes#include "lldb/Interpreter/OptionValueString.h"
41180750Sdes#include "lldb/Symbol/ClangASTContext.h"
42180750Sdes#include "lldb/Symbol/CompileUnit.h"
43180750Sdes#include "lldb/Symbol/Function.h"
44180740Sdes#include "lldb/Symbol/Symbol.h"
45180740Sdes#include "lldb/Symbol/VariableList.h"
46180740Sdes#include "lldb/Target/TargetList.h"
47180740Sdes#include "lldb/Target/Process.h"
48180740Sdes#include "lldb/Target/RegisterContext.h"
49180740Sdes#include "lldb/Target/StopInfo.h"
50180740Sdes#include "lldb/Target/Target.h"
51180740Sdes#include "lldb/Target/Thread.h"
52180740Sdes#include "lldb/Utility/AnsiTerminal.h"
53180740Sdes
54180740Sdesusing namespace lldb;
55180740Sdesusing namespace lldb_private;
56180740Sdes
57180740Sdes
58180740Sdesstatic uint32_t g_shared_debugger_refcount = 0;
59180740Sdesstatic lldb::user_id_t g_unique_id = 1;
60180740Sdes
61180740Sdes#pragma mark Static Functions
62180740Sdes
63180740Sdesstatic Mutex &
64180740SdesGetDebuggerListMutex ()
65180746Sdes{
66180746Sdes    static Mutex g_mutex(Mutex::eMutexTypeRecursive);
67180746Sdes    return g_mutex;
68180740Sdes}
69180740Sdes
70180740Sdestypedef std::vector<DebuggerSP> DebuggerList;
71197679Sdes
72197679Sdesstatic DebuggerList &
73197679SdesGetDebuggerList()
74180740Sdes{
75180740Sdes    // hide the static debugger list inside a singleton accessor to avoid
76180740Sdes    // global init contructors
77180740Sdes    static DebuggerList g_list;
78180740Sdes    return g_list;
79180740Sdes}
80180740Sdes
81180740SdesOptionEnumValueElement
82180740Sdesg_show_disassembly_enum_values[] =
83180740Sdes{
84180740Sdes    { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
85180740Sdes    { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
86180740Sdes    { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
87180740Sdes    { 0, NULL, NULL }
88180740Sdes};
89180740Sdes
90180740SdesOptionEnumValueElement
91180740Sdesg_language_enumerators[] =
92180740Sdes{
93180740Sdes    { eScriptLanguageNone,      "none",     "Disable scripting languages."},
94180740Sdes    { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
95180740Sdes    { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
96180740Sdes    { 0, NULL, NULL }
97180740Sdes};
98180740Sdes
99180740Sdes#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
100180740Sdes#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
101180740Sdes
102180740Sdes#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
103180740Sdes    "{, ${frame.pc}}"\
104180740Sdes    MODULE_WITH_FUNC\
105180740Sdes    FILE_AND_LINE\
106180740Sdes    "{, name = '${thread.name}'}"\
107180740Sdes    "{, queue = '${thread.queue}'}"\
108180740Sdes    "{, stop reason = ${thread.stop-reason}}"\
109180740Sdes    "{\\nReturn value: ${thread.return-value}}"\
110180740Sdes    "\\n"
111180740Sdes
112180740Sdes#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
113180740Sdes    MODULE_WITH_FUNC\
114180740Sdes    FILE_AND_LINE\
115180740Sdes    "\\n"
116180740Sdes
117180740Sdes
118180740Sdes
119180740Sdesstatic PropertyDefinition
120180740Sdesg_properties[] =
121180740Sdes{
122204917Sdes{   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
123204917Sdes{   "frame-format",             OptionValue::eTypeString , true, 0    , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
124204917Sdes{   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
125180740Sdes{   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
126180740Sdes{   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
127180740Sdes{   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
128197679Sdes{   "stop-disassembly-display", OptionValue::eTypeEnum   , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
129180750Sdes{   "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." },
130180750Sdes{   "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." },
131197679Sdes{   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
132197679Sdes{   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
133197679Sdes{   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
134180740Sdes{   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
135180740Sdes
136180740Sdes    {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
137180740Sdes};
138180740Sdes
139180740Sdesenum
140180740Sdes{
141180740Sdes    ePropertyAutoConfirm = 0,
142180740Sdes    ePropertyFrameFormat,
143180740Sdes    ePropertyNotiftVoid,
144180740Sdes    ePropertyPrompt,
145180740Sdes    ePropertyScriptLanguage,
146180740Sdes    ePropertyStopDisassemblyCount,
147180740Sdes    ePropertyStopDisassemblyDisplay,
148180740Sdes    ePropertyStopLineCountAfter,
149180740Sdes    ePropertyStopLineCountBefore,
150180740Sdes    ePropertyTerminalWidth,
151180740Sdes    ePropertyThreadFormat,
152180740Sdes    ePropertyUseExternalEditor,
153180740Sdes    ePropertyUseColor,
154180740Sdes};
155180740Sdes
156180740Sdes//
157180740Sdes//const char *
158180740Sdes//Debugger::GetFrameFormat() const
159180740Sdes//{
160180740Sdes//    return m_properties_sp->GetFrameFormat();
161180740Sdes//}
162180740Sdes//const char *
163180740Sdes//Debugger::GetThreadFormat() const
164180740Sdes//{
165180740Sdes//    return m_properties_sp->GetThreadFormat();
166180740Sdes//}
167180740Sdes//
168180740Sdes
169180740Sdes
170180750SdesError
171180750SdesDebugger::SetPropertyValue (const ExecutionContext *exe_ctx,
172180750Sdes                            VarSetOperationType op,
173180750Sdes                            const char *property_path,
174180750Sdes                            const char *value)
175180750Sdes{
176180740Sdes    bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
177180740Sdes    TargetSP target_sp;
178180740Sdes    LoadScriptFromSymFile load_script_old_value;
179180740Sdes    if (is_load_script && exe_ctx->GetTargetSP())
180180740Sdes    {
181180740Sdes        target_sp = exe_ctx->GetTargetSP();
182180744Sdes        load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
183180744Sdes    }
184180744Sdes    Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
185180740Sdes    if (error.Success())
186180740Sdes    {
187180740Sdes        // FIXME it would be nice to have "on-change" callbacks for properties
188180746Sdes        if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
189180746Sdes        {
190180746Sdes            const char *new_prompt = GetPrompt();
191180740Sdes            std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
192180740Sdes            if (str.length())
193180740Sdes                new_prompt = str.c_str();
194180740Sdes            EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
195180740Sdes            GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
196180740Sdes        }
197180740Sdes        else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
198180740Sdes        {
199180740Sdes			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
200180740Sdes            SetPrompt (GetPrompt());
201180740Sdes        }
202180740Sdes        else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
203180740Sdes        {
204180740Sdes            if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
205180740Sdes            {
206180740Sdes                std::list<Error> errors;
207180740Sdes                StreamString feedback_stream;
208180740Sdes                if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
209180740Sdes                {
210180740Sdes                    for (auto error : errors)
211180740Sdes                    {
212180740Sdes                        GetErrorStream().Printf("%s\n",error.AsCString());
213180740Sdes                    }
214180740Sdes                    if (feedback_stream.GetSize())
215180740Sdes                        GetErrorStream().Printf("%s",feedback_stream.GetData());
216180740Sdes                }
217180740Sdes            }
218180740Sdes        }
219180740Sdes    }
220180740Sdes    return error;
221180740Sdes}
222180740Sdes
223180740Sdesbool
224180740SdesDebugger::GetAutoConfirm () const
225180740Sdes{
226180740Sdes    const uint32_t idx = ePropertyAutoConfirm;
227180740Sdes    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
228180740Sdes}
229180740Sdes
230180740Sdesconst char *
231180740SdesDebugger::GetFrameFormat() const
232180740Sdes{
233180740Sdes    const uint32_t idx = ePropertyFrameFormat;
234180740Sdes    return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
235180740Sdes}
236180740Sdes
237180740Sdesbool
238180740SdesDebugger::GetNotifyVoid () const
239180740Sdes{
240180740Sdes    const uint32_t idx = ePropertyNotiftVoid;
241180740Sdes    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
242180740Sdes}
243180740Sdes
244180740Sdesconst char *
245180740SdesDebugger::GetPrompt() const
246180740Sdes{
247180740Sdes    const uint32_t idx = ePropertyPrompt;
248180740Sdes    return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
249180740Sdes}
250180740Sdes
251180740Sdesvoid
252180740SdesDebugger::SetPrompt(const char *p)
253180740Sdes{
254180740Sdes    const uint32_t idx = ePropertyPrompt;
255180740Sdes    m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
256180740Sdes    const char *new_prompt = GetPrompt();
257180740Sdes    std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
258180740Sdes    if (str.length())
259180740Sdes        new_prompt = str.c_str();
260180740Sdes    EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
261180740Sdes    GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
262180740Sdes}
263180744Sdes
264180744Sdesconst char *
265180744SdesDebugger::GetThreadFormat() const
266180744Sdes{
267180744Sdes    const uint32_t idx = ePropertyThreadFormat;
268180744Sdes    return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
269180744Sdes}
270180744Sdes
271180740Sdeslldb::ScriptLanguage
272180740SdesDebugger::GetScriptLanguage() const
273180740Sdes{
274180740Sdes    const uint32_t idx = ePropertyScriptLanguage;
275180740Sdes    return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
276180740Sdes}
277180740Sdes
278180740Sdesbool
279180740SdesDebugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
280180740Sdes{
281180740Sdes    const uint32_t idx = ePropertyScriptLanguage;
282180740Sdes    return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
283180740Sdes}
284180740Sdes
285180740Sdesuint32_t
286180740SdesDebugger::GetTerminalWidth () const
287180740Sdes{
288180740Sdes    const uint32_t idx = ePropertyTerminalWidth;
289180740Sdes    return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
290180740Sdes}
291180740Sdes
292180740Sdesbool
293180740SdesDebugger::SetTerminalWidth (uint32_t term_width)
294180740Sdes{
295180740Sdes    const uint32_t idx = ePropertyTerminalWidth;
296180740Sdes    return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
297180740Sdes}
298180740Sdes
299180740Sdesbool
300180740SdesDebugger::GetUseExternalEditor () const
301180740Sdes{
302180740Sdes    const uint32_t idx = ePropertyUseExternalEditor;
303180740Sdes    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
304180740Sdes}
305180740Sdes
306180740Sdesbool
307180740SdesDebugger::SetUseExternalEditor (bool b)
308180740Sdes{
309180740Sdes    const uint32_t idx = ePropertyUseExternalEditor;
310180740Sdes    return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
311180740Sdes}
312180740Sdes
313180740Sdesbool
314180740SdesDebugger::GetUseColor () const
315180740Sdes{
316180740Sdes    const uint32_t idx = ePropertyUseColor;
317180740Sdes    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
318180740Sdes}
319180740Sdes
320180740Sdesbool
321180740SdesDebugger::SetUseColor (bool b)
322180740Sdes{
323180740Sdes    const uint32_t idx = ePropertyUseColor;
324180740Sdes    bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
325180740Sdes    SetPrompt (GetPrompt());
326180740Sdes    return ret;
327180740Sdes}
328180740Sdes
329180740Sdesuint32_t
330180740SdesDebugger::GetStopSourceLineCount (bool before) const
331180740Sdes{
332180740Sdes    const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
333180740Sdes    return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
334180740Sdes}
335180740Sdes
336180740SdesDebugger::StopDisassemblyType
337180740SdesDebugger::GetStopDisassemblyDisplay () const
338180740Sdes{
339180740Sdes    const uint32_t idx = ePropertyStopDisassemblyDisplay;
340180740Sdes    return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
341180740Sdes}
342180740Sdes
343180740Sdesuint32_t
344180740SdesDebugger::GetDisassemblyLineCount () const
345180740Sdes{
346180740Sdes    const uint32_t idx = ePropertyStopDisassemblyCount;
347180740Sdes    return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
348180740Sdes}
349180740Sdes
350180750Sdes#pragma mark Debugger
351180750Sdes
352180750Sdes//const DebuggerPropertiesSP &
353180740Sdes//Debugger::GetSettings() const
354180740Sdes//{
355180740Sdes//    return m_properties_sp;
356180750Sdes//}
357180750Sdes//
358180750Sdes
359180750Sdesint
360180750SdesDebugger::TestDebuggerRefCount ()
361180750Sdes{
362180750Sdes    return g_shared_debugger_refcount;
363180750Sdes}
364180750Sdes
365180740Sdesvoid
366180740SdesDebugger::Initialize ()
367180740Sdes{
368180740Sdes    if (g_shared_debugger_refcount++ == 0)
369180740Sdes        lldb_private::Initialize();
370180740Sdes}
371180740Sdes
372180740Sdesvoid
373180740SdesDebugger::Terminate ()
374180740Sdes{
375180740Sdes    if (g_shared_debugger_refcount > 0)
376180740Sdes    {
377180740Sdes        g_shared_debugger_refcount--;
378180740Sdes        if (g_shared_debugger_refcount == 0)
379180740Sdes        {
380180740Sdes            lldb_private::WillTerminate();
381180740Sdes            lldb_private::Terminate();
382180740Sdes
383180740Sdes            // Clear our master list of debugger objects
384180740Sdes            Mutex::Locker locker (GetDebuggerListMutex ());
385180740Sdes            GetDebuggerList().clear();
386180746Sdes        }
387180746Sdes    }
388180746Sdes}
389192595Sdes
390192595Sdesvoid
391192595SdesDebugger::SettingsInitialize ()
392180740Sdes{
393180740Sdes    Target::SettingsInitialize ();
394180740Sdes}
395180740Sdes
396180740Sdesvoid
397180740SdesDebugger::SettingsTerminate ()
398180740Sdes{
399180740Sdes    Target::SettingsTerminate ();
400180740Sdes}
401180740Sdes
402180740Sdesbool
403180740SdesDebugger::LoadPlugin (const FileSpec& spec, Error& error)
404180740Sdes{
405180740Sdes    lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
406180740Sdes    if (!dynlib_sp || dynlib_sp->IsValid() == false)
407180740Sdes    {
408180740Sdes        if (spec.Exists())
409180740Sdes            error.SetErrorString("this file does not represent a loadable dylib");
410180740Sdes        else
411180740Sdes            error.SetErrorString("no such file");
412180740Sdes        return false;
413180744Sdes    }
414180744Sdes    lldb::DebuggerSP debugger_sp(shared_from_this());
415180744Sdes    lldb::SBDebugger debugger_sb(debugger_sp);
416180740Sdes    // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function.
417180740Sdes    // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
418180740Sdes    LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
419180740Sdes    if (!init_func)
420180740Sdes    {
421180740Sdes        error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)");
422180740Sdes        return false;
423180740Sdes    }
424180740Sdes    if (init_func(debugger_sb))
425180740Sdes    {
426180740Sdes        m_loaded_plugins.push_back(dynlib_sp);
427180740Sdes        return true;
428180740Sdes    }
429180740Sdes    error.SetErrorString("dylib refused to be loaded");
430180740Sdes    return false;
431180740Sdes}
432180740Sdes
433180740Sdesstatic FileSpec::EnumerateDirectoryResult
434180740SdesLoadPluginCallback
435180740Sdes(
436180740Sdes void *baton,
437180740Sdes FileSpec::FileType file_type,
438180740Sdes const FileSpec &file_spec
439180740Sdes )
440180740Sdes{
441180740Sdes    Error error;
442180740Sdes
443180740Sdes    static ConstString g_dylibext("dylib");
444180740Sdes    static ConstString g_solibext("so");
445180740Sdes
446180740Sdes    if (!baton)
447180740Sdes        return FileSpec::eEnumerateDirectoryResultQuit;
448180740Sdes
449180740Sdes    Debugger *debugger = (Debugger*)baton;
450180740Sdes
451180740Sdes    // If we have a regular file, a symbolic link or unknown file type, try
452180740Sdes    // and process the file. We must handle unknown as sometimes the directory
453180740Sdes    // enumeration might be enumerating a file system that doesn't have correct
454180740Sdes    // file type information.
455207319Sdes    if (file_type == FileSpec::eFileTypeRegular         ||
456207319Sdes        file_type == FileSpec::eFileTypeSymbolicLink    ||
457207319Sdes        file_type == FileSpec::eFileTypeUnknown          )
458180740Sdes    {
459180740Sdes        FileSpec plugin_file_spec (file_spec);
460180740Sdes        plugin_file_spec.ResolvePath ();
461180740Sdes
462180740Sdes        if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
463180740Sdes            plugin_file_spec.GetFileNameExtension() != g_solibext)
464180740Sdes        {
465180740Sdes            return FileSpec::eEnumerateDirectoryResultNext;
466180740Sdes        }
467204917Sdes
468204917Sdes        Error plugin_load_error;
469204917Sdes        debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
470180740Sdes
471180740Sdes        return FileSpec::eEnumerateDirectoryResultNext;
472180740Sdes    }
473180740Sdes
474180740Sdes    else if (file_type == FileSpec::eFileTypeUnknown     ||
475180740Sdes        file_type == FileSpec::eFileTypeDirectory   ||
476180740Sdes        file_type == FileSpec::eFileTypeSymbolicLink )
477180740Sdes    {
478180740Sdes        // Try and recurse into anything that a directory or symbolic link.
479180740Sdes        // We must also do this for unknown as sometimes the directory enumeration
480180740Sdes        // might be enurating a file system that doesn't have correct file type
481180740Sdes        // information.
482180740Sdes        return FileSpec::eEnumerateDirectoryResultEnter;
483180740Sdes    }
484180740Sdes
485180740Sdes    return FileSpec::eEnumerateDirectoryResultNext;
486180740Sdes}
487180740Sdes
488180740Sdesvoid
489180740SdesDebugger::InstanceInitialize ()
490180740Sdes{
491180740Sdes    FileSpec dir_spec;
492180740Sdes    const bool find_directories = true;
493180740Sdes    const bool find_files = true;
494180740Sdes    const bool find_other = true;
495180740Sdes    char dir_path[PATH_MAX];
496180740Sdes    if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
497180740Sdes    {
498180740Sdes        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
499180740Sdes        {
500180740Sdes            FileSpec::EnumerateDirectory (dir_path,
501180740Sdes                                          find_directories,
502180740Sdes                                          find_files,
503180740Sdes                                          find_other,
504180740Sdes                                          LoadPluginCallback,
505180740Sdes                                          this);
506180740Sdes        }
507180740Sdes    }
508180740Sdes
509180740Sdes    if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
510180740Sdes    {
511180740Sdes        if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
512180740Sdes        {
513180740Sdes            FileSpec::EnumerateDirectory (dir_path,
514180740Sdes                                          find_directories,
515180740Sdes                                          find_files,
516180740Sdes                                          find_other,
517180740Sdes                                          LoadPluginCallback,
518180740Sdes                                          this);
519180740Sdes        }
520180740Sdes    }
521180740Sdes
522180740Sdes    PluginManager::DebuggerInitialize (*this);
523180740Sdes}
524180740Sdes
525180740SdesDebuggerSP
526180740SdesDebugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
527180740Sdes{
528180740Sdes    DebuggerSP debugger_sp (new Debugger(log_callback, baton));
529180740Sdes    if (g_shared_debugger_refcount > 0)
530180740Sdes    {
531180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
532180740Sdes        GetDebuggerList().push_back(debugger_sp);
533197679Sdes    }
534197679Sdes    debugger_sp->InstanceInitialize ();
535197679Sdes    return debugger_sp;
536180740Sdes}
537180740Sdes
538180740Sdesvoid
539180740SdesDebugger::Destroy (DebuggerSP &debugger_sp)
540180740Sdes{
541180740Sdes    if (debugger_sp.get() == NULL)
542180740Sdes        return;
543180740Sdes
544180740Sdes    debugger_sp->Clear();
545180740Sdes
546180740Sdes    if (g_shared_debugger_refcount > 0)
547180740Sdes    {
548180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
549180740Sdes        DebuggerList &debugger_list = GetDebuggerList ();
550180740Sdes        DebuggerList::iterator pos, end = debugger_list.end();
551180746Sdes        for (pos = debugger_list.begin (); pos != end; ++pos)
552180746Sdes        {
553180746Sdes            if ((*pos).get() == debugger_sp.get())
554207319Sdes            {
555207319Sdes                debugger_list.erase (pos);
556207319Sdes                return;
557180740Sdes            }
558180740Sdes        }
559180740Sdes    }
560180740Sdes}
561180740Sdes
562180740SdesDebuggerSP
563180740SdesDebugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
564180740Sdes{
565180740Sdes    DebuggerSP debugger_sp;
566180740Sdes    if (g_shared_debugger_refcount > 0)
567180740Sdes    {
568180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
569180740Sdes        DebuggerList &debugger_list = GetDebuggerList();
570180740Sdes        DebuggerList::iterator pos, end = debugger_list.end();
571180740Sdes
572180740Sdes        for (pos = debugger_list.begin(); pos != end; ++pos)
573180740Sdes        {
574180740Sdes            if ((*pos).get()->m_instance_name == instance_name)
575180740Sdes            {
576180740Sdes                debugger_sp = *pos;
577180740Sdes                break;
578180740Sdes            }
579180740Sdes        }
580180740Sdes    }
581180740Sdes    return debugger_sp;
582180740Sdes}
583180740Sdes
584180740SdesTargetSP
585180740SdesDebugger::FindTargetWithProcessID (lldb::pid_t pid)
586180740Sdes{
587180740Sdes    TargetSP target_sp;
588180740Sdes    if (g_shared_debugger_refcount > 0)
589180740Sdes    {
590180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
591180740Sdes        DebuggerList &debugger_list = GetDebuggerList();
592180740Sdes        DebuggerList::iterator pos, end = debugger_list.end();
593180740Sdes        for (pos = debugger_list.begin(); pos != end; ++pos)
594180740Sdes        {
595180740Sdes            target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
596180740Sdes            if (target_sp)
597180740Sdes                break;
598180740Sdes        }
599180740Sdes    }
600180740Sdes    return target_sp;
601180740Sdes}
602180740Sdes
603180740SdesTargetSP
604180740SdesDebugger::FindTargetWithProcess (Process *process)
605180740Sdes{
606180740Sdes    TargetSP target_sp;
607180740Sdes    if (g_shared_debugger_refcount > 0)
608180740Sdes    {
609180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
610180740Sdes        DebuggerList &debugger_list = GetDebuggerList();
611180740Sdes        DebuggerList::iterator pos, end = debugger_list.end();
612180740Sdes        for (pos = debugger_list.begin(); pos != end; ++pos)
613180740Sdes        {
614180740Sdes            target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
615180740Sdes            if (target_sp)
616180740Sdes                break;
617180740Sdes        }
618180740Sdes    }
619180740Sdes    return target_sp;
620180740Sdes}
621180740Sdes
622180740SdesDebugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
623180740Sdes    UserID (g_unique_id++),
624180740Sdes    Properties(OptionValuePropertiesSP(new OptionValueProperties())),
625180740Sdes    m_input_comm("debugger.input"),
626180740Sdes    m_input_file (),
627180740Sdes    m_output_file (),
628180740Sdes    m_error_file (),
629180740Sdes    m_terminal_state (),
630180740Sdes    m_target_list (*this),
631180740Sdes    m_platform_list (),
632180740Sdes    m_listener ("lldb.Debugger"),
633180740Sdes    m_source_manager_ap(),
634180740Sdes    m_source_file_cache(),
635180740Sdes    m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
636180740Sdes    m_input_reader_stack (),
637180740Sdes    m_input_reader_data (),
638180740Sdes    m_instance_name()
639180740Sdes{
640180740Sdes    char instance_cstr[256];
641180740Sdes    snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
642180740Sdes    m_instance_name.SetCString(instance_cstr);
643180740Sdes    if (log_callback)
644180740Sdes        m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
645180740Sdes    m_command_interpreter_ap->Initialize ();
646180740Sdes    // Always add our default platform to the platform list
647180740Sdes    PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
648180740Sdes    assert (default_platform_sp.get());
649180740Sdes    m_platform_list.Append (default_platform_sp, true);
650180740Sdes
651180740Sdes    m_collection_sp->Initialize (g_properties);
652180740Sdes    m_collection_sp->AppendProperty (ConstString("target"),
653180740Sdes                                     ConstString("Settings specify to debugging targets."),
654180740Sdes                                     true,
655180740Sdes                                     Target::GetGlobalProperties()->GetValueProperties());
656180740Sdes    if (m_command_interpreter_ap.get())
657180740Sdes    {
658180740Sdes        m_collection_sp->AppendProperty (ConstString("interpreter"),
659180740Sdes                                         ConstString("Settings specify to the debugger's command interpreter."),
660180740Sdes                                         true,
661180740Sdes                                         m_command_interpreter_ap->GetValueProperties());
662180740Sdes    }
663180740Sdes    OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
664180740Sdes    term_width->SetMinimumValue(10);
665180740Sdes    term_width->SetMaximumValue(1024);
666180740Sdes
667180740Sdes    // Turn off use-color if this is a dumb terminal.
668180740Sdes    const char *term = getenv ("TERM");
669180740Sdes    if (term && !strcmp (term, "dumb"))
670180740Sdes        SetUseColor (false);
671180740Sdes}
672180740Sdes
673180740SdesDebugger::~Debugger ()
674180740Sdes{
675180740Sdes    Clear();
676180740Sdes}
677180740Sdes
678180740Sdesvoid
679180740SdesDebugger::Clear()
680180740Sdes{
681180740Sdes    CleanUpInputReaders();
682180740Sdes    m_listener.Clear();
683180740Sdes    int num_targets = m_target_list.GetNumTargets();
684180740Sdes    for (int i = 0; i < num_targets; i++)
685180740Sdes    {
686180740Sdes        TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
687180740Sdes        if (target_sp)
688180740Sdes        {
689180740Sdes            ProcessSP process_sp (target_sp->GetProcessSP());
690180744Sdes            if (process_sp)
691180744Sdes                process_sp->Finalize();
692180744Sdes            target_sp->Destroy();
693180744Sdes        }
694180744Sdes    }
695180744Sdes    BroadcasterManager::Clear ();
696180740Sdes
697180740Sdes    // Close the input file _before_ we close the input read communications class
698180740Sdes    // as it does NOT own the input file, our m_input_file does.
699180740Sdes    m_terminal_state.Clear();
700180740Sdes    GetInputFile().Close ();
701180740Sdes    // Now that we have closed m_input_file, we can now tell our input communication
702180740Sdes    // class to close down. Its read thread should quickly exit after we close
703180740Sdes    // the input file handle above.
704180740Sdes    m_input_comm.Clear ();
705180740Sdes}
706180740Sdes
707180740Sdesbool
708180740SdesDebugger::GetCloseInputOnEOF () const
709180740Sdes{
710180740Sdes    return m_input_comm.GetCloseOnEOF();
711180740Sdes}
712180740Sdes
713180740Sdesvoid
714180740SdesDebugger::SetCloseInputOnEOF (bool b)
715180740Sdes{
716180740Sdes    m_input_comm.SetCloseOnEOF(b);
717180740Sdes}
718180740Sdes
719180740Sdesbool
720180740SdesDebugger::GetAsyncExecution ()
721180740Sdes{
722180740Sdes    return !m_command_interpreter_ap->GetSynchronous();
723180740Sdes}
724180740Sdes
725180740Sdesvoid
726180740SdesDebugger::SetAsyncExecution (bool async_execution)
727180740Sdes{
728180740Sdes    m_command_interpreter_ap->SetSynchronous (!async_execution);
729180740Sdes}
730180740Sdes
731180740Sdes
732180740Sdesvoid
733180740SdesDebugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
734180740Sdes{
735180740Sdes    File &in_file = GetInputFile();
736180740Sdes    in_file.SetStream (fh, tranfer_ownership);
737180740Sdes    if (in_file.IsValid() == false)
738180740Sdes        in_file.SetStream (stdin, true);
739180740Sdes
740180740Sdes    // Disconnect from any old connection if we had one
741180740Sdes    m_input_comm.Disconnect ();
742180740Sdes    // Pass false as the second argument to ConnectionFileDescriptor below because
743180740Sdes    // our "in_file" above will already take ownership if requested and we don't
744180740Sdes    // want to objects trying to own and close a file descriptor.
745180740Sdes    m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
746180740Sdes    m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
747180740Sdes
748180740Sdes    // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
749180740Sdes    SaveInputTerminalState ();
750180740Sdes
751180740Sdes    Error error;
752180740Sdes    if (m_input_comm.StartReadThread (&error) == false)
753180740Sdes    {
754180740Sdes        File &err_file = GetErrorFile();
755180740Sdes
756180740Sdes        err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
757180740Sdes        exit(1);
758180740Sdes    }
759180740Sdes}
760180740Sdes
761180740Sdesvoid
762180740SdesDebugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
763180740Sdes{
764180740Sdes    File &out_file = GetOutputFile();
765180740Sdes    out_file.SetStream (fh, tranfer_ownership);
766180740Sdes    if (out_file.IsValid() == false)
767180740Sdes        out_file.SetStream (stdout, false);
768204917Sdes
769204917Sdes    // do not create the ScriptInterpreter just for setting the output file handle
770204917Sdes    // as the constructor will know how to do the right thing on its own
771180740Sdes    const bool can_create = false;
772180740Sdes    ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
773180740Sdes    if (script_interpreter)
774180740Sdes        script_interpreter->ResetOutputFileHandle (fh);
775180740Sdes}
776180740Sdes
777180740Sdesvoid
778180740SdesDebugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
779180740Sdes{
780204917Sdes    File &err_file = GetErrorFile();
781204917Sdes    err_file.SetStream (fh, tranfer_ownership);
782204917Sdes    if (err_file.IsValid() == false)
783180740Sdes        err_file.SetStream (stderr, false);
784180740Sdes}
785180740Sdes
786180740Sdesvoid
787180740SdesDebugger::SaveInputTerminalState ()
788180740Sdes{
789180740Sdes    File &in_file = GetInputFile();
790180740Sdes    if (in_file.GetDescriptor() != File::kInvalidDescriptor)
791180740Sdes        m_terminal_state.Save(in_file.GetDescriptor(), true);
792180740Sdes}
793180740Sdes
794180740Sdesvoid
795180740SdesDebugger::RestoreInputTerminalState ()
796180740Sdes{
797180740Sdes    m_terminal_state.Restore();
798180740Sdes}
799180740Sdes
800180740SdesExecutionContext
801180740SdesDebugger::GetSelectedExecutionContext ()
802180740Sdes{
803180740Sdes    ExecutionContext exe_ctx;
804180740Sdes    TargetSP target_sp(GetSelectedTarget());
805180740Sdes    exe_ctx.SetTargetSP (target_sp);
806180740Sdes
807180740Sdes    if (target_sp)
808180740Sdes    {
809180740Sdes        ProcessSP process_sp (target_sp->GetProcessSP());
810207319Sdes        exe_ctx.SetProcessSP (process_sp);
811207319Sdes        if (process_sp && process_sp->IsRunning() == false)
812207319Sdes        {
813180740Sdes            ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
814180740Sdes            if (thread_sp)
815180740Sdes            {
816180740Sdes                exe_ctx.SetThreadSP (thread_sp);
817180740Sdes                exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
818180740Sdes                if (exe_ctx.GetFramePtr() == NULL)
819180744Sdes                    exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
820180744Sdes            }
821180744Sdes        }
822180740Sdes    }
823180740Sdes    return exe_ctx;
824180740Sdes
825180740Sdes}
826180740Sdes
827180740SdesInputReaderSP
828180740SdesDebugger::GetCurrentInputReader ()
829180740Sdes{
830180740Sdes    InputReaderSP reader_sp;
831180740Sdes
832180740Sdes    if (!m_input_reader_stack.IsEmpty())
833180740Sdes    {
834180740Sdes        // Clear any finished readers from the stack
835180740Sdes        while (CheckIfTopInputReaderIsDone()) ;
836180740Sdes
837180740Sdes        if (!m_input_reader_stack.IsEmpty())
838180740Sdes            reader_sp = m_input_reader_stack.Top();
839180740Sdes    }
840180740Sdes
841180740Sdes    return reader_sp;
842180740Sdes}
843180740Sdes
844180740Sdesvoid
845180740SdesDebugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
846180740Sdes{
847180740Sdes    if (bytes_len > 0)
848180740Sdes        ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
849180740Sdes    else
850180740Sdes        ((Debugger *)baton)->DispatchInputEndOfFile ();
851180740Sdes}
852180740Sdes
853180740Sdes
854180740Sdesvoid
855180740SdesDebugger::DispatchInput (const char *bytes, size_t bytes_len)
856180740Sdes{
857180740Sdes    if (bytes == NULL || bytes_len == 0)
858180750Sdes        return;
859180750Sdes
860180750Sdes    WriteToDefaultReader (bytes, bytes_len);
861180750Sdes}
862180750Sdes
863180750Sdesvoid
864180740SdesDebugger::DispatchInputInterrupt ()
865180740Sdes{
866180740Sdes    m_input_reader_data.clear();
867180740Sdes
868180740Sdes    InputReaderSP reader_sp (GetCurrentInputReader ());
869180740Sdes    if (reader_sp)
870180740Sdes    {
871180740Sdes        reader_sp->Notify (eInputReaderInterrupt);
872180740Sdes
873180740Sdes        // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
874180740Sdes        while (CheckIfTopInputReaderIsDone ()) ;
875180740Sdes    }
876180740Sdes}
877180740Sdes
878180740Sdesvoid
879180740SdesDebugger::DispatchInputEndOfFile ()
880180740Sdes{
881180740Sdes    m_input_reader_data.clear();
882180740Sdes
883180740Sdes    InputReaderSP reader_sp (GetCurrentInputReader ());
884180740Sdes    if (reader_sp)
885180740Sdes    {
886180740Sdes        reader_sp->Notify (eInputReaderEndOfFile);
887180740Sdes
888180740Sdes        // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
889180740Sdes        while (CheckIfTopInputReaderIsDone ()) ;
890180740Sdes    }
891180740Sdes}
892180740Sdes
893180740Sdesvoid
894180740SdesDebugger::CleanUpInputReaders ()
895180740Sdes{
896180740Sdes    m_input_reader_data.clear();
897180740Sdes
898180740Sdes    // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
899180740Sdes    while (m_input_reader_stack.GetSize() > 1)
900180740Sdes    {
901180740Sdes        InputReaderSP reader_sp (GetCurrentInputReader ());
902180740Sdes        if (reader_sp)
903180740Sdes        {
904180740Sdes            reader_sp->Notify (eInputReaderEndOfFile);
905180740Sdes            reader_sp->SetIsDone (true);
906180740Sdes        }
907180740Sdes    }
908180740Sdes}
909180740Sdes
910180740Sdesvoid
911180740SdesDebugger::NotifyTopInputReader (InputReaderAction notification)
912180740Sdes{
913180740Sdes    InputReaderSP reader_sp (GetCurrentInputReader());
914180740Sdes    if (reader_sp)
915180740Sdes	{
916180740Sdes        reader_sp->Notify (notification);
917180740Sdes
918180740Sdes        // Flush out any input readers that are done.
919180740Sdes        while (CheckIfTopInputReaderIsDone ())
920180740Sdes            /* Do nothing. */;
921180740Sdes    }
922180740Sdes}
923180740Sdes
924192595Sdesbool
925192595SdesDebugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
926192595Sdes{
927180740Sdes    InputReaderSP top_reader_sp (GetCurrentInputReader());
928180740Sdes
929180740Sdes    return (reader_sp.get() == top_reader_sp.get());
930180740Sdes}
931180740Sdes
932180740Sdes
933180740Sdesvoid
934180740SdesDebugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
935180740Sdes{
936180740Sdes    if (bytes && bytes_len)
937180740Sdes        m_input_reader_data.append (bytes, bytes_len);
938180740Sdes
939180744Sdes    if (m_input_reader_data.empty())
940180744Sdes        return;
941180744Sdes
942180740Sdes    while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
943180740Sdes    {
944180740Sdes        // Get the input reader from the top of the stack
945180740Sdes        InputReaderSP reader_sp (GetCurrentInputReader ());
946180740Sdes        if (!reader_sp)
947180740Sdes            break;
948180740Sdes
949180740Sdes        size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
950180740Sdes                                                          m_input_reader_data.size());
951180740Sdes        if (bytes_handled)
952180740Sdes        {
953180740Sdes            m_input_reader_data.erase (0, bytes_handled);
954180740Sdes        }
955180740Sdes        else
956180740Sdes        {
957180740Sdes            // No bytes were handled, we might not have reached our
958180740Sdes            // granularity, just return and wait for more data
959180740Sdes            break;
960180740Sdes        }
961180740Sdes    }
962180740Sdes
963180740Sdes    // Flush out any input readers that are done.
964180740Sdes    while (CheckIfTopInputReaderIsDone ())
965180740Sdes        /* Do nothing. */;
966180740Sdes
967180740Sdes}
968180740Sdes
969180750Sdesvoid
970180750SdesDebugger::PushInputReader (const InputReaderSP& reader_sp)
971180750Sdes{
972180740Sdes    if (!reader_sp)
973180740Sdes        return;
974180740Sdes
975180740Sdes    // Deactivate the old top reader
976180740Sdes    InputReaderSP top_reader_sp (GetCurrentInputReader ());
977180740Sdes
978180746Sdes    if (top_reader_sp)
979180746Sdes        top_reader_sp->Notify (eInputReaderDeactivate);
980180746Sdes
981180740Sdes    m_input_reader_stack.Push (reader_sp);
982180740Sdes    reader_sp->Notify (eInputReaderActivate);
983180740Sdes    ActivateInputReader (reader_sp);
984180740Sdes}
985180740Sdes
986180740Sdesbool
987180740SdesDebugger::PopInputReader (const InputReaderSP& pop_reader_sp)
988180740Sdes{
989180740Sdes    bool result = false;
990180740Sdes
991180740Sdes    // The reader on the stop of the stack is done, so let the next
992180740Sdes    // read on the stack referesh its prompt and if there is one...
993180750Sdes    if (!m_input_reader_stack.IsEmpty())
994180750Sdes    {
995180750Sdes        // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
996180740Sdes        InputReaderSP reader_sp(m_input_reader_stack.Top());
997180740Sdes
998180740Sdes        if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
999180740Sdes        {
1000180740Sdes            m_input_reader_stack.Pop ();
1001180740Sdes            reader_sp->Notify (eInputReaderDeactivate);
1002180740Sdes            reader_sp->Notify (eInputReaderDone);
1003180740Sdes            result = true;
1004180740Sdes
1005180740Sdes            if (!m_input_reader_stack.IsEmpty())
1006180740Sdes            {
1007180740Sdes                reader_sp = m_input_reader_stack.Top();
1008180740Sdes                if (reader_sp)
1009180740Sdes                {
1010180740Sdes                    ActivateInputReader (reader_sp);
1011180740Sdes                    reader_sp->Notify (eInputReaderReactivate);
1012180740Sdes                }
1013180740Sdes            }
1014180740Sdes        }
1015180740Sdes    }
1016180740Sdes    return result;
1017180740Sdes}
1018180740Sdes
1019180740Sdesbool
1020180740SdesDebugger::CheckIfTopInputReaderIsDone ()
1021180740Sdes{
1022180740Sdes    bool result = false;
1023180740Sdes    if (!m_input_reader_stack.IsEmpty())
1024180740Sdes    {
1025180740Sdes        // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
1026180740Sdes        InputReaderSP reader_sp(m_input_reader_stack.Top());
1027180740Sdes
1028180740Sdes        if (reader_sp && reader_sp->IsDone())
1029180740Sdes        {
1030180740Sdes            result = true;
1031180740Sdes            PopInputReader (reader_sp);
1032180740Sdes        }
1033180740Sdes    }
1034180740Sdes    return result;
1035180740Sdes}
1036180740Sdes
1037180740Sdesvoid
1038180740SdesDebugger::ActivateInputReader (const InputReaderSP &reader_sp)
1039180740Sdes{
1040180740Sdes    int input_fd = m_input_file.GetFile().GetDescriptor();
1041180740Sdes
1042180740Sdes    if (input_fd >= 0)
1043180740Sdes    {
1044180740Sdes        Terminal tty(input_fd);
1045180740Sdes
1046180740Sdes        tty.SetEcho(reader_sp->GetEcho());
1047180740Sdes
1048180740Sdes        switch (reader_sp->GetGranularity())
1049180740Sdes        {
1050180740Sdes        case eInputReaderGranularityByte:
1051180740Sdes        case eInputReaderGranularityWord:
1052180740Sdes            tty.SetCanonical (false);
1053180740Sdes            break;
1054180740Sdes
1055180740Sdes        case eInputReaderGranularityLine:
1056180740Sdes        case eInputReaderGranularityAll:
1057180740Sdes            tty.SetCanonical (true);
1058180740Sdes            break;
1059180740Sdes
1060180740Sdes        default:
1061180740Sdes            break;
1062180740Sdes        }
1063180740Sdes    }
1064180740Sdes}
1065180744Sdes
1066180744SdesStreamSP
1067180744SdesDebugger::GetAsyncOutputStream ()
1068180740Sdes{
1069180740Sdes    return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1070180740Sdes                                               CommandInterpreter::eBroadcastBitAsynchronousOutputData));
1071180740Sdes}
1072180740Sdes
1073180740SdesStreamSP
1074180740SdesDebugger::GetAsyncErrorStream ()
1075180740Sdes{
1076180740Sdes    return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1077180740Sdes                                               CommandInterpreter::eBroadcastBitAsynchronousErrorData));
1078180740Sdes}
1079180740Sdes
1080180740Sdessize_t
1081180740SdesDebugger::GetNumDebuggers()
1082180740Sdes{
1083180740Sdes    if (g_shared_debugger_refcount > 0)
1084180740Sdes    {
1085180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
1086180740Sdes        return GetDebuggerList().size();
1087180740Sdes    }
1088180740Sdes    return 0;
1089204917Sdes}
1090204917Sdes
1091204917Sdeslldb::DebuggerSP
1092180740SdesDebugger::GetDebuggerAtIndex (size_t index)
1093180740Sdes{
1094180740Sdes    DebuggerSP debugger_sp;
1095180740Sdes
1096180740Sdes    if (g_shared_debugger_refcount > 0)
1097180740Sdes    {
1098180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
1099180740Sdes        DebuggerList &debugger_list = GetDebuggerList();
1100180740Sdes
1101180740Sdes        if (index < debugger_list.size())
1102180740Sdes            debugger_sp = debugger_list[index];
1103180740Sdes    }
1104180740Sdes
1105180740Sdes    return debugger_sp;
1106180740Sdes}
1107180740Sdes
1108180740SdesDebuggerSP
1109180740SdesDebugger::FindDebuggerWithID (lldb::user_id_t id)
1110180740Sdes{
1111180740Sdes    DebuggerSP debugger_sp;
1112180740Sdes
1113180740Sdes    if (g_shared_debugger_refcount > 0)
1114180740Sdes    {
1115180740Sdes        Mutex::Locker locker (GetDebuggerListMutex ());
1116180740Sdes        DebuggerList &debugger_list = GetDebuggerList();
1117180740Sdes        DebuggerList::iterator pos, end = debugger_list.end();
1118180740Sdes        for (pos = debugger_list.begin(); pos != end; ++pos)
1119180740Sdes        {
1120180740Sdes            if ((*pos).get()->GetID() == id)
1121180740Sdes            {
1122180740Sdes                debugger_sp = *pos;
1123180740Sdes                break;
1124180740Sdes            }
1125180740Sdes        }
1126180740Sdes    }
1127180740Sdes    return debugger_sp;
1128180740Sdes}
1129180740Sdes
1130180740Sdesstatic void
1131180740SdesTestPromptFormats (StackFrame *frame)
1132180740Sdes{
1133180740Sdes    if (frame == NULL)
1134180740Sdes        return;
1135180740Sdes
1136180740Sdes    StreamString s;
1137180740Sdes    const char *prompt_format =
1138180740Sdes    "{addr = '${addr}'\n}"
1139180740Sdes    "{process.id = '${process.id}'\n}"
1140180740Sdes    "{process.name = '${process.name}'\n}"
1141180740Sdes    "{process.file.basename = '${process.file.basename}'\n}"
1142180740Sdes    "{process.file.fullpath = '${process.file.fullpath}'\n}"
1143180740Sdes    "{thread.id = '${thread.id}'\n}"
1144180740Sdes    "{thread.index = '${thread.index}'\n}"
1145180740Sdes    "{thread.name = '${thread.name}'\n}"
1146180740Sdes    "{thread.queue = '${thread.queue}'\n}"
1147180740Sdes    "{thread.stop-reason = '${thread.stop-reason}'\n}"
1148180740Sdes    "{target.arch = '${target.arch}'\n}"
1149180740Sdes    "{module.file.basename = '${module.file.basename}'\n}"
1150180740Sdes    "{module.file.fullpath = '${module.file.fullpath}'\n}"
1151180740Sdes    "{file.basename = '${file.basename}'\n}"
1152180744Sdes    "{file.fullpath = '${file.fullpath}'\n}"
1153180744Sdes    "{frame.index = '${frame.index}'\n}"
1154180744Sdes    "{frame.pc = '${frame.pc}'\n}"
1155180740Sdes    "{frame.sp = '${frame.sp}'\n}"
1156180740Sdes    "{frame.fp = '${frame.fp}'\n}"
1157180740Sdes    "{frame.flags = '${frame.flags}'\n}"
1158180740Sdes    "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
1159180740Sdes    "{frame.reg.rip = '${frame.reg.rip}'\n}"
1160180740Sdes    "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
1161180740Sdes    "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
1162180740Sdes    "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
1163180740Sdes    "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
1164180740Sdes    "{frame.reg.carp = '${frame.reg.carp}'\n}"
1165180740Sdes    "{function.id = '${function.id}'\n}"
1166180740Sdes    "{function.name = '${function.name}'\n}"
1167180740Sdes    "{function.name-with-args = '${function.name-with-args}'\n}"
1168180740Sdes    "{function.addr-offset = '${function.addr-offset}'\n}"
1169180740Sdes    "{function.line-offset = '${function.line-offset}'\n}"
1170180740Sdes    "{function.pc-offset = '${function.pc-offset}'\n}"
1171180740Sdes    "{line.file.basename = '${line.file.basename}'\n}"
1172180740Sdes    "{line.file.fullpath = '${line.file.fullpath}'\n}"
1173180740Sdes    "{line.number = '${line.number}'\n}"
1174180740Sdes    "{line.start-addr = '${line.start-addr}'\n}"
1175180740Sdes    "{line.end-addr = '${line.end-addr}'\n}"
1176180740Sdes;
1177180740Sdes
1178180740Sdes    SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
1179180740Sdes    ExecutionContext exe_ctx;
1180180740Sdes    frame->CalculateExecutionContext(exe_ctx);
1181180740Sdes    if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
1182180740Sdes    {
1183180740Sdes        printf("%s\n", s.GetData());
1184180740Sdes    }
1185180740Sdes    else
1186180740Sdes    {
1187180740Sdes        printf ("what we got: %s\n", s.GetData());
1188180740Sdes    }
1189180740Sdes}
1190180740Sdes
1191192595Sdesstatic bool
1192192595SdesScanFormatDescriptor (const char* var_name_begin,
1193192595Sdes                      const char* var_name_end,
1194180740Sdes                      const char** var_name_final,
1195180740Sdes                      const char** percent_position,
1196180740Sdes                      Format* custom_format,
1197180740Sdes                      ValueObject::ValueObjectRepresentationStyle* val_obj_display)
1198180740Sdes{
1199180740Sdes    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1200180740Sdes    *percent_position = ::strchr(var_name_begin,'%');
1201204917Sdes    if (!*percent_position || *percent_position > var_name_end)
1202204917Sdes    {
1203204917Sdes        if (log)
1204180740Sdes            log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
1205180740Sdes        *var_name_final = var_name_end;
1206180740Sdes    }
1207180740Sdes    else
1208180740Sdes    {
1209180740Sdes        *var_name_final = *percent_position;
1210180740Sdes        std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1211180740Sdes        if (log)
1212180740Sdes            log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
1213180740Sdes        if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
1214180740Sdes                                                  true,
1215180740Sdes                                                  *custom_format) )
1216180740Sdes        {
1217180740Sdes            if (log)
1218180740Sdes                log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
1219180740Sdes
1220180740Sdes            switch (format_name.front())
1221180740Sdes            {
1222180740Sdes                case '@':             // if this is an @ sign, print ObjC description
1223180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
1224180740Sdes                    break;
1225180740Sdes                case 'V': // if this is a V, print the value using the default format
1226180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1227180740Sdes                    break;
1228180740Sdes                case 'L': // if this is an L, print the location of the value
1229180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
1230180740Sdes                    break;
1231180740Sdes                case 'S': // if this is an S, print the summary after all
1232180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1233180740Sdes                    break;
1234180740Sdes                case '#': // if this is a '#', print the number of children
1235180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
1236180740Sdes                    break;
1237180740Sdes                case 'T': // if this is a 'T', print the type
1238180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
1239180740Sdes                    break;
1240180740Sdes                case 'N': // if this is a 'N', print the name
1241180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
1242180740Sdes                    break;
1243180740Sdes                case '>': // if this is a '>', print the name
1244180740Sdes                    *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
1245180740Sdes                    break;
1246180740Sdes                default:
1247180740Sdes                    if (log)
1248180740Sdes                        log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
1249180740Sdes                    break;
1250180740Sdes            }
1251180740Sdes        }
1252180740Sdes        // a good custom format tells us to print the value using it
1253180740Sdes        else
1254180740Sdes        {
1255180740Sdes            if (log)
1256197679Sdes                log->Printf("[ScanFormatDescriptor] will display value for this VO");
1257197679Sdes            *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1258197679Sdes        }
1259180740Sdes    }
1260180740Sdes    if (log)
1261180740Sdes        log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1262180740Sdes                    *custom_format,
1263180740Sdes                    *val_obj_display);
1264180740Sdes    return true;
1265180740Sdes}
1266180740Sdes
1267180740Sdesstatic bool
1268180740SdesScanBracketedRange (const char* var_name_begin,
1269180740Sdes                    const char* var_name_end,
1270180740Sdes                    const char* var_name_final,
1271180740Sdes                    const char** open_bracket_position,
1272180740Sdes                    const char** separator_position,
1273180740Sdes                    const char** close_bracket_position,
1274180740Sdes                    const char** var_name_final_if_array_range,
1275180740Sdes                    int64_t* index_lower,
1276180740Sdes                    int64_t* index_higher)
1277180740Sdes{
1278180740Sdes    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1279180740Sdes    *open_bracket_position = ::strchr(var_name_begin,'[');
1280180740Sdes    if (*open_bracket_position && *open_bracket_position < var_name_final)
1281180740Sdes    {
1282180740Sdes        *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
1283180740Sdes        *close_bracket_position = ::strchr(*open_bracket_position,']');
1284180740Sdes        // as usual, we assume that [] will come before %
1285180740Sdes        //printf("trying to expand a []\n");
1286180740Sdes        *var_name_final_if_array_range = *open_bracket_position;
1287180740Sdes        if (*close_bracket_position - *open_bracket_position == 1)
1288180740Sdes        {
1289180740Sdes            if (log)
1290180740Sdes                log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
1291180740Sdes            *index_lower = 0;
1292180740Sdes        }
1293180740Sdes        else if (*separator_position == NULL || *separator_position > var_name_end)
1294180740Sdes        {
1295180740Sdes            char *end = NULL;
1296180740Sdes            *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1297180740Sdes            *index_higher = *index_lower;
1298180740Sdes            if (log)
1299180740Sdes                log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
1300180740Sdes        }
1301180740Sdes        else if (*close_bracket_position && *close_bracket_position < var_name_end)
1302180740Sdes        {
1303180740Sdes            char *end = NULL;
1304180740Sdes            *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1305180740Sdes            *index_higher = ::strtoul (*separator_position+1, &end, 0);
1306180740Sdes            if (log)
1307180740Sdes                log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
1308180740Sdes        }
1309180740Sdes        else
1310180740Sdes        {
1311180740Sdes            if (log)
1312180740Sdes                log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
1313180740Sdes            return false;
1314180740Sdes        }
1315180740Sdes        if (*index_lower > *index_higher && *index_higher > 0)
1316180740Sdes        {
1317180740Sdes            if (log)
1318180740Sdes                log->Printf("[ScanBracketedRange] swapping indices");
1319180740Sdes            int64_t temp = *index_lower;
1320180740Sdes            *index_lower = *index_higher;
1321180740Sdes            *index_higher = temp;
1322180740Sdes        }
1323180740Sdes    }
1324180740Sdes    else if (log)
1325180740Sdes            log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
1326180740Sdes    return true;
1327180740Sdes}
1328180740Sdes
1329180740Sdestemplate <typename T>
1330180740Sdesstatic bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
1331180740Sdes{
1332180740Sdes    if (script_interpreter)
1333180740Sdes    {
1334180740Sdes        Error script_error;
1335180740Sdes        std::string script_output;
1336180740Sdes
1337180740Sdes        if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
1338180740Sdes        {
1339197679Sdes            s.Printf("%s", script_output.c_str());
1340197679Sdes            return true;
1341197679Sdes        }
1342180740Sdes        else
1343180740Sdes        {
1344180740Sdes            s.Printf("<error: %s>",script_error.AsCString());
1345180740Sdes        }
1346180740Sdes    }
1347180740Sdes    return false;
1348180740Sdes}
1349180740Sdes
1350180740Sdesstatic ValueObjectSP
1351180740SdesExpandIndexedExpression (ValueObject* valobj,
1352180740Sdes                         size_t index,
1353180740Sdes                         StackFrame* frame,
1354180740Sdes                         bool deref_pointer)
1355180740Sdes{
1356180740Sdes    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1357180740Sdes    const char* ptr_deref_format = "[%d]";
1358180740Sdes    std::string ptr_deref_buffer(10,0);
1359180740Sdes    ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1360180740Sdes    if (log)
1361180740Sdes        log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1362180740Sdes    const char* first_unparsed;
1363180740Sdes    ValueObject::GetValueForExpressionPathOptions options;
1364180740Sdes    ValueObject::ExpressionPathEndResultType final_value_type;
1365180740Sdes    ValueObject::ExpressionPathScanEndReason reason_to_stop;
1366180740Sdes    ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1367180740Sdes    ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1368180740Sdes                                                          &first_unparsed,
1369180740Sdes                                                          &reason_to_stop,
1370180740Sdes                                                          &final_value_type,
1371180740Sdes                                                          options,
1372180740Sdes                                                          &what_next);
1373180740Sdes    if (!item)
1374180740Sdes    {
1375180740Sdes        if (log)
1376180740Sdes            log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1377180740Sdes               " final_value_type %d",
1378180740Sdes               first_unparsed, reason_to_stop, final_value_type);
1379180740Sdes    }
1380180740Sdes    else
1381180740Sdes    {
1382180740Sdes        if (log)
1383180740Sdes            log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1384180740Sdes               " final_value_type %d",
1385180740Sdes               first_unparsed, reason_to_stop, final_value_type);
1386180740Sdes    }
1387180740Sdes    return item;
1388180740Sdes}
1389180740Sdes
1390180740Sdesstatic inline bool
1391180740SdesIsToken(const char *var_name_begin, const char *var)
1392180740Sdes{
1393180740Sdes    return (::strncmp (var_name_begin, var, strlen(var)) == 0);
1394180740Sdes}
1395180740Sdes
1396180740Sdesstatic bool
1397180740SdesIsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
1398180740Sdes    const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
1399180740Sdes{
1400180740Sdes    int var_len = strlen(var);
1401180740Sdes    if (::strncmp (var_name_begin, var, var_len) == 0)
1402180740Sdes    {
1403180740Sdes        var_name_begin += var_len;
1404180740Sdes        if (*var_name_begin == '}')
1405180740Sdes        {
1406180740Sdes            format = default_format;
1407180740Sdes            return true;
1408180740Sdes        }
1409180740Sdes        else if (*var_name_begin == '%')
1410180740Sdes        {
1411180740Sdes            // Allow format specifiers: x|X|u with optional width specifiers.
1412180740Sdes            //   ${thread.id%x}    ; hex
1413180740Sdes            //   ${thread.id%X}    ; uppercase hex
1414180740Sdes            //   ${thread.id%u}    ; unsigned decimal
1415180740Sdes            //   ${thread.id%8.8X} ; width.precision + specifier
1416180740Sdes            //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
1417180740Sdes            int dot_count = 0;
1418180740Sdes            const char *specifier = NULL;
1419180740Sdes            int width_precision_length = 0;
1420180740Sdes            const char *width_precision = ++var_name_begin;
1421180740Sdes            while (isdigit(*var_name_begin) || *var_name_begin == '.')
1422180740Sdes            {
1423180740Sdes                dot_count += (*var_name_begin == '.');
1424204917Sdes                if (dot_count > 1)
1425204917Sdes                    break;
1426204917Sdes                var_name_begin++;
1427180740Sdes                width_precision_length++;
1428180740Sdes            }
1429180740Sdes
1430180740Sdes            if (IsToken (var_name_begin, "tid}"))
1431180740Sdes            {
1432180740Sdes                Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
1433180740Sdes                if (target)
1434180740Sdes                {
1435180740Sdes                    ArchSpec arch (target->GetArchitecture ());
1436180740Sdes                    llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
1437180740Sdes                    if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
1438180740Sdes                        specifier = PRIu64;
1439180740Sdes                }
1440180740Sdes                if (!specifier)
1441180740Sdes                {
1442180740Sdes                    format = default_format;
1443180740Sdes                    return true;
1444180740Sdes                }
1445180740Sdes            }
1446180740Sdes            else if (IsToken (var_name_begin, "x}"))
1447180740Sdes                specifier = PRIx64;
1448180740Sdes            else if (IsToken (var_name_begin, "X}"))
1449180740Sdes                specifier = PRIX64;
1450180740Sdes            else if (IsToken (var_name_begin, "u}"))
1451180740Sdes                specifier = PRIu64;
1452180740Sdes
1453180740Sdes            if (specifier)
1454180740Sdes            {
1455180740Sdes                format = "%";
1456180740Sdes                if (width_precision_length)
1457                    format += std::string(width_precision, width_precision_length);
1458                format += specifier;
1459                return true;
1460            }
1461        }
1462    }
1463    return false;
1464}
1465
1466static bool
1467FormatPromptRecurse
1468(
1469    const char *format,
1470    const SymbolContext *sc,
1471    const ExecutionContext *exe_ctx,
1472    const Address *addr,
1473    Stream &s,
1474    const char **end,
1475    ValueObject* valobj
1476)
1477{
1478    ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
1479    bool success = true;
1480    const char *p;
1481    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1482
1483    for (p = format; *p != '\0'; ++p)
1484    {
1485        if (realvalobj)
1486        {
1487            valobj = realvalobj;
1488            realvalobj = NULL;
1489        }
1490        size_t non_special_chars = ::strcspn (p, "${}\\");
1491        if (non_special_chars > 0)
1492        {
1493            if (success)
1494                s.Write (p, non_special_chars);
1495            p += non_special_chars;
1496        }
1497
1498        if (*p == '\0')
1499        {
1500            break;
1501        }
1502        else if (*p == '{')
1503        {
1504            // Start a new scope that must have everything it needs if it is to
1505            // to make it into the final output stream "s". If you want to make
1506            // a format that only prints out the function or symbol name if there
1507            // is one in the symbol context you can use:
1508            //      "{function =${function.name}}"
1509            // The first '{' starts a new scope that end with the matching '}' at
1510            // the end of the string. The contents "function =${function.name}"
1511            // will then be evaluated and only be output if there is a function
1512            // or symbol with a valid name.
1513            StreamString sub_strm;
1514
1515            ++p;  // Skip the '{'
1516
1517            if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
1518            {
1519                // The stream had all it needed
1520                s.Write(sub_strm.GetData(), sub_strm.GetSize());
1521            }
1522            if (*p != '}')
1523            {
1524                success = false;
1525                break;
1526            }
1527        }
1528        else if (*p == '}')
1529        {
1530            // End of a enclosing scope
1531            break;
1532        }
1533        else if (*p == '$')
1534        {
1535            // We have a prompt variable to print
1536            ++p;
1537            if (*p == '{')
1538            {
1539                ++p;
1540                const char *var_name_begin = p;
1541                const char *var_name_end = ::strchr (p, '}');
1542
1543                if (var_name_end && var_name_begin < var_name_end)
1544                {
1545                    // if we have already failed to parse, skip this variable
1546                    if (success)
1547                    {
1548                        const char *cstr = NULL;
1549                        std::string token_format;
1550                        Address format_addr;
1551                        bool calculate_format_addr_function_offset = false;
1552                        // Set reg_kind and reg_num to invalid values
1553                        RegisterKind reg_kind = kNumRegisterKinds;
1554                        uint32_t reg_num = LLDB_INVALID_REGNUM;
1555                        FileSpec format_file_spec;
1556                        const RegisterInfo *reg_info = NULL;
1557                        RegisterContext *reg_ctx = NULL;
1558                        bool do_deref_pointer = false;
1559                        ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
1560                        ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
1561
1562                        // Each variable must set success to true below...
1563                        bool var_success = false;
1564                        switch (var_name_begin[0])
1565                        {
1566                        case '*':
1567                        case 'v':
1568                        case 's':
1569                            {
1570                                if (!valobj)
1571                                    break;
1572
1573                                if (log)
1574                                    log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1575
1576                                // check for *var and *svar
1577                                if (*var_name_begin == '*')
1578                                {
1579                                    do_deref_pointer = true;
1580                                    var_name_begin++;
1581                                    if (log)
1582                                        log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
1583                                }
1584
1585                                if (*var_name_begin == 's')
1586                                {
1587                                    if (!valobj->IsSynthetic())
1588                                        valobj = valobj->GetSyntheticValue().get();
1589                                    if (!valobj)
1590                                        break;
1591                                    var_name_begin++;
1592                                    if (log)
1593                                        log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
1594                                }
1595
1596                                // should be a 'v' by now
1597                                if (*var_name_begin != 'v')
1598                                    break;
1599
1600                                if (log)
1601                                    log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1602
1603                                ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
1604                                                                                  ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1605                                ValueObject::GetValueForExpressionPathOptions options;
1606                                options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
1607                                ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1608                                ValueObject* target = NULL;
1609                                Format custom_format = eFormatInvalid;
1610                                const char* var_name_final = NULL;
1611                                const char* var_name_final_if_array_range = NULL;
1612                                const char* close_bracket_position = NULL;
1613                                int64_t index_lower = -1;
1614                                int64_t index_higher = -1;
1615                                bool is_array_range = false;
1616                                const char* first_unparsed;
1617                                bool was_plain_var = false;
1618                                bool was_var_format = false;
1619                                bool was_var_indexed = false;
1620
1621                                if (!valobj) break;
1622                                // simplest case ${var}, just print valobj's value
1623                                if (IsToken (var_name_begin, "var}"))
1624                                {
1625                                    was_plain_var = true;
1626                                    target = valobj;
1627                                    val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1628                                }
1629                                else if (IsToken (var_name_begin,"var%"))
1630                                {
1631                                    was_var_format = true;
1632                                    // this is a variable with some custom format applied to it
1633                                    const char* percent_position;
1634                                    target = valobj;
1635                                    val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1636                                    ScanFormatDescriptor (var_name_begin,
1637                                                          var_name_end,
1638                                                          &var_name_final,
1639                                                          &percent_position,
1640                                                          &custom_format,
1641                                                          &val_obj_display);
1642                                }
1643                                    // this is ${var.something} or multiple .something nested
1644                                else if (IsToken (var_name_begin, "var"))
1645                                {
1646                                    if (IsToken (var_name_begin, "var["))
1647                                        was_var_indexed = true;
1648                                    const char* percent_position;
1649                                    ScanFormatDescriptor (var_name_begin,
1650                                                          var_name_end,
1651                                                          &var_name_final,
1652                                                          &percent_position,
1653                                                          &custom_format,
1654                                                          &val_obj_display);
1655
1656                                    const char* open_bracket_position;
1657                                    const char* separator_position;
1658                                    ScanBracketedRange (var_name_begin,
1659                                                        var_name_end,
1660                                                        var_name_final,
1661                                                        &open_bracket_position,
1662                                                        &separator_position,
1663                                                        &close_bracket_position,
1664                                                        &var_name_final_if_array_range,
1665                                                        &index_lower,
1666                                                        &index_higher);
1667
1668                                    Error error;
1669
1670                                    std::string expr_path(var_name_final-var_name_begin-1,0);
1671                                    memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1672
1673                                    if (log)
1674                                        log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1675
1676                                    target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1677                                                                             &first_unparsed,
1678                                                                             &reason_to_stop,
1679                                                                             &final_value_type,
1680                                                                             options,
1681                                                                             &what_next).get();
1682
1683                                    if (!target)
1684                                    {
1685                                        if (log)
1686                                            log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1687                                               " final_value_type %d",
1688                                               first_unparsed, reason_to_stop, final_value_type);
1689                                        break;
1690                                    }
1691                                    else
1692                                    {
1693                                        if (log)
1694                                            log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1695                                               " final_value_type %d",
1696                                               first_unparsed, reason_to_stop, final_value_type);
1697                                    }
1698                                }
1699                                else
1700                                    break;
1701
1702                                is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
1703                                                  final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1704
1705                                do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1706
1707                                if (do_deref_pointer && !is_array_range)
1708                                {
1709                                    // I have not deref-ed yet, let's do it
1710                                    // this happens when we are not going through GetValueForVariableExpressionPath
1711                                    // to get to the target ValueObject
1712                                    Error error;
1713                                    target = target->Dereference(error).get();
1714                                    if (error.Fail())
1715                                    {
1716                                        if (log)
1717                                            log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1718                                        break;
1719                                    }
1720                                    do_deref_pointer = false;
1721                                }
1722
1723                                // <rdar://problem/11338654>
1724                                // we do not want to use the summary for a bitfield of type T:n
1725                                // if we were originally dealing with just a T - that would get
1726                                // us into an endless recursion
1727                                if (target->IsBitfield() && was_var_indexed)
1728                                {
1729                                    // TODO: check for a (T:n)-specific summary - we should still obey that
1730                                    StreamString bitfield_name;
1731                                    bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1732                                    lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1733                                    if (!DataVisualization::GetSummaryForType(type_sp))
1734                                        val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1735                                }
1736
1737                                // TODO use flags for these
1738                                const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
1739                                bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0;
1740                                bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0;
1741                                bool is_aggregate = target->GetClangType().IsAggregateType();
1742
1743                                if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1744                                {
1745                                    StreamString str_temp;
1746                                    if (log)
1747                                        log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1748
1749                                    if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1750                                    {
1751                                        // try to use the special cases
1752                                        var_success = target->DumpPrintableRepresentation(str_temp,
1753                                                                                          val_obj_display,
1754                                                                                          custom_format);
1755                                        if (log)
1756                                            log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1757
1758                                        // should not happen
1759                                        if (var_success)
1760                                            s << str_temp.GetData();
1761                                        var_success = true;
1762                                        break;
1763                                    }
1764                                    else
1765                                    {
1766                                        if (was_plain_var) // if ${var}
1767                                        {
1768                                            s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1769                                        }
1770                                        else if (is_pointer) // if pointer, value is the address stored
1771                                        {
1772                                            target->DumpPrintableRepresentation (s,
1773                                                                                 val_obj_display,
1774                                                                                 custom_format,
1775                                                                                 ValueObject::ePrintableRepresentationSpecialCasesDisable);
1776                                        }
1777                                        var_success = true;
1778                                        break;
1779                                    }
1780                                }
1781
1782                                // if directly trying to print ${var}, and this is an aggregate, display a nice
1783                                // type @ location message
1784                                if (is_aggregate && was_plain_var)
1785                                {
1786                                    s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1787                                    var_success = true;
1788                                    break;
1789                                }
1790
1791                                // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
1792                                if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
1793                                {
1794                                    s << "<invalid use of aggregate type>";
1795                                    var_success = true;
1796                                    break;
1797                                }
1798
1799                                if (!is_array_range)
1800                                {
1801                                    if (log)
1802                                        log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
1803                                    var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1804                                }
1805                                else
1806                                {
1807                                    if (log)
1808                                        log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
1809                                    if (!is_array && !is_pointer)
1810                                        break;
1811                                    if (log)
1812                                        log->Printf("[Debugger::FormatPrompt] handle as array");
1813                                    const char* special_directions = NULL;
1814                                    StreamString special_directions_writer;
1815                                    if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1816                                    {
1817                                        ConstString additional_data;
1818                                        additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1819                                        special_directions_writer.Printf("${%svar%s}",
1820                                                                         do_deref_pointer ? "*" : "",
1821                                                                         additional_data.GetCString());
1822                                        special_directions = special_directions_writer.GetData();
1823                                    }
1824
1825                                    // let us display items index_lower thru index_higher of this array
1826                                    s.PutChar('[');
1827                                    var_success = true;
1828
1829                                    if (index_higher < 0)
1830                                        index_higher = valobj->GetNumChildren() - 1;
1831
1832                                    uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1833
1834                                    for (;index_lower<=index_higher;index_lower++)
1835                                    {
1836                                        ValueObject* item = ExpandIndexedExpression (target,
1837                                                                                     index_lower,
1838                                                                                     exe_ctx->GetFramePtr(),
1839                                                                                     false).get();
1840
1841                                        if (!item)
1842                                        {
1843                                            if (log)
1844                                                log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1845                                        }
1846                                        else
1847                                        {
1848                                            if (log)
1849                                                log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1850                                        }
1851
1852                                        if (!special_directions)
1853                                            var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1854                                        else
1855                                            var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item);
1856
1857                                        if (--max_num_children == 0)
1858                                        {
1859                                            s.PutCString(", ...");
1860                                            break;
1861                                        }
1862
1863                                        if (index_lower < index_higher)
1864                                            s.PutChar(',');
1865                                    }
1866                                    s.PutChar(']');
1867                                }
1868                            }
1869                            break;
1870                        case 'a':
1871                            if (IsToken (var_name_begin, "addr}"))
1872                            {
1873                                if (addr && addr->IsValid())
1874                                {
1875                                    var_success = true;
1876                                    format_addr = *addr;
1877                                }
1878                            }
1879                            break;
1880
1881                        case 'p':
1882                            if (IsToken (var_name_begin, "process."))
1883                            {
1884                                if (exe_ctx)
1885                                {
1886                                    Process *process = exe_ctx->GetProcessPtr();
1887                                    if (process)
1888                                    {
1889                                        var_name_begin += ::strlen ("process.");
1890                                        if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
1891                                        {
1892                                            s.Printf(token_format.c_str(), process->GetID());
1893                                            var_success = true;
1894                                        }
1895                                        else if ((IsToken (var_name_begin, "name}")) ||
1896                                                (IsToken (var_name_begin, "file.basename}")) ||
1897                                                (IsToken (var_name_begin, "file.fullpath}")))
1898                                        {
1899                                            Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1900                                            if (exe_module)
1901                                            {
1902                                                if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
1903                                                {
1904                                                    format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
1905                                                    var_success = format_file_spec;
1906                                                }
1907                                                else
1908                                                {
1909                                                    format_file_spec = exe_module->GetFileSpec();
1910                                                    var_success = format_file_spec;
1911                                                }
1912                                            }
1913                                        }
1914                                        else if (IsToken (var_name_begin, "script:"))
1915                                        {
1916                                            var_name_begin += ::strlen("script:");
1917                                            std::string script_name(var_name_begin,var_name_end);
1918                                            ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1919                                            if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
1920                                                var_success = true;
1921                                        }
1922                                    }
1923                                }
1924                            }
1925                            break;
1926
1927                        case 't':
1928                           if (IsToken (var_name_begin, "thread."))
1929                            {
1930                                if (exe_ctx)
1931                                {
1932                                    Thread *thread = exe_ctx->GetThreadPtr();
1933                                    if (thread)
1934                                    {
1935                                        var_name_begin += ::strlen ("thread.");
1936                                        if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1937                                        {
1938                                            s.Printf(token_format.c_str(), thread->GetID());
1939                                            var_success = true;
1940                                        }
1941                                        else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1942                                        {
1943                                            s.Printf(token_format.c_str(), thread->GetProtocolID());
1944                                            var_success = true;
1945                                        }
1946                                        else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
1947                                        {
1948                                            s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
1949                                            var_success = true;
1950                                        }
1951                                        else if (IsToken (var_name_begin, "name}"))
1952                                        {
1953                                            cstr = thread->GetName();
1954                                            var_success = cstr && cstr[0];
1955                                            if (var_success)
1956                                                s.PutCString(cstr);
1957                                        }
1958                                        else if (IsToken (var_name_begin, "queue}"))
1959                                        {
1960                                            cstr = thread->GetQueueName();
1961                                            var_success = cstr && cstr[0];
1962                                            if (var_success)
1963                                                s.PutCString(cstr);
1964                                        }
1965                                        else if (IsToken (var_name_begin, "stop-reason}"))
1966                                        {
1967                                            StopInfoSP stop_info_sp = thread->GetStopInfo ();
1968                                            if (stop_info_sp && stop_info_sp->IsValid())
1969                                            {
1970                                                cstr = stop_info_sp->GetDescription();
1971                                                if (cstr && cstr[0])
1972                                                {
1973                                                    s.PutCString(cstr);
1974                                                    var_success = true;
1975                                                }
1976                                            }
1977                                        }
1978                                        else if (IsToken (var_name_begin, "return-value}"))
1979                                        {
1980                                            StopInfoSP stop_info_sp = thread->GetStopInfo ();
1981                                            if (stop_info_sp && stop_info_sp->IsValid())
1982                                            {
1983                                                ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
1984                                                if (return_valobj_sp)
1985                                                {
1986                                                    ValueObject::DumpValueObject (s, return_valobj_sp.get());
1987                                                    var_success = true;
1988                                                }
1989                                            }
1990                                        }
1991                                        else if (IsToken (var_name_begin, "script:"))
1992                                        {
1993                                            var_name_begin += ::strlen("script:");
1994                                            std::string script_name(var_name_begin,var_name_end);
1995                                            ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1996                                            if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
1997                                                var_success = true;
1998                                        }
1999                                    }
2000                                }
2001                            }
2002                            else if (IsToken (var_name_begin, "target."))
2003                            {
2004                                // TODO: hookup properties
2005//                                if (!target_properties_sp)
2006//                                {
2007//                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2008//                                    if (target)
2009//                                        target_properties_sp = target->GetProperties();
2010//                                }
2011//
2012//                                if (target_properties_sp)
2013//                                {
2014//                                    var_name_begin += ::strlen ("target.");
2015//                                    const char *end_property = strchr(var_name_begin, '}');
2016//                                    if (end_property)
2017//                                    {
2018//                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
2019//                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
2020//                                        if (!property_value.empty())
2021//                                        {
2022//                                            s.PutCString (property_value.c_str());
2023//                                            var_success = true;
2024//                                        }
2025//                                    }
2026//                                }
2027                                Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2028                                if (target)
2029                                {
2030                                    var_name_begin += ::strlen ("target.");
2031                                    if (IsToken (var_name_begin, "arch}"))
2032                                    {
2033                                        ArchSpec arch (target->GetArchitecture ());
2034                                        if (arch.IsValid())
2035                                        {
2036                                            s.PutCString (arch.GetArchitectureName());
2037                                            var_success = true;
2038                                        }
2039                                    }
2040                                    else if (IsToken (var_name_begin, "script:"))
2041                                    {
2042                                        var_name_begin += ::strlen("script:");
2043                                        std::string script_name(var_name_begin,var_name_end);
2044                                        ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2045                                        if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2046                                            var_success = true;
2047                                    }
2048                                }
2049                            }
2050                            break;
2051
2052
2053                        case 'm':
2054                           if (IsToken (var_name_begin, "module."))
2055                            {
2056                                if (sc && sc->module_sp.get())
2057                                {
2058                                    Module *module = sc->module_sp.get();
2059                                    var_name_begin += ::strlen ("module.");
2060
2061                                    if (IsToken (var_name_begin, "file."))
2062                                    {
2063                                        if (module->GetFileSpec())
2064                                        {
2065                                            var_name_begin += ::strlen ("file.");
2066
2067                                            if (IsToken (var_name_begin, "basename}"))
2068                                            {
2069                                                format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
2070                                                var_success = format_file_spec;
2071                                            }
2072                                            else if (IsToken (var_name_begin, "fullpath}"))
2073                                            {
2074                                                format_file_spec = module->GetFileSpec();
2075                                                var_success = format_file_spec;
2076                                            }
2077                                        }
2078                                    }
2079                                }
2080                            }
2081                            break;
2082
2083
2084                        case 'f':
2085                           if (IsToken (var_name_begin, "file."))
2086                            {
2087                                if (sc && sc->comp_unit != NULL)
2088                                {
2089                                    var_name_begin += ::strlen ("file.");
2090
2091                                    if (IsToken (var_name_begin, "basename}"))
2092                                    {
2093                                        format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
2094                                        var_success = format_file_spec;
2095                                    }
2096                                    else if (IsToken (var_name_begin, "fullpath}"))
2097                                    {
2098                                        format_file_spec = *sc->comp_unit;
2099                                        var_success = format_file_spec;
2100                                    }
2101                                }
2102                            }
2103                           else if (IsToken (var_name_begin, "frame."))
2104                            {
2105                                if (exe_ctx)
2106                                {
2107                                    StackFrame *frame = exe_ctx->GetFramePtr();
2108                                    if (frame)
2109                                    {
2110                                        var_name_begin += ::strlen ("frame.");
2111                                        if (IsToken (var_name_begin, "index}"))
2112                                        {
2113                                            s.Printf("%u", frame->GetFrameIndex());
2114                                            var_success = true;
2115                                        }
2116                                        else if (IsToken (var_name_begin, "pc}"))
2117                                        {
2118                                            reg_kind = eRegisterKindGeneric;
2119                                            reg_num = LLDB_REGNUM_GENERIC_PC;
2120                                            var_success = true;
2121                                        }
2122                                        else if (IsToken (var_name_begin, "sp}"))
2123                                        {
2124                                            reg_kind = eRegisterKindGeneric;
2125                                            reg_num = LLDB_REGNUM_GENERIC_SP;
2126                                            var_success = true;
2127                                        }
2128                                        else if (IsToken (var_name_begin, "fp}"))
2129                                        {
2130                                            reg_kind = eRegisterKindGeneric;
2131                                            reg_num = LLDB_REGNUM_GENERIC_FP;
2132                                            var_success = true;
2133                                        }
2134                                        else if (IsToken (var_name_begin, "flags}"))
2135                                        {
2136                                            reg_kind = eRegisterKindGeneric;
2137                                            reg_num = LLDB_REGNUM_GENERIC_FLAGS;
2138                                            var_success = true;
2139                                        }
2140                                        else if (IsToken (var_name_begin, "reg."))
2141                                        {
2142                                            reg_ctx = frame->GetRegisterContext().get();
2143                                            if (reg_ctx)
2144                                            {
2145                                                var_name_begin += ::strlen ("reg.");
2146                                                if (var_name_begin < var_name_end)
2147                                                {
2148                                                    std::string reg_name (var_name_begin, var_name_end);
2149                                                    reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
2150                                                    if (reg_info)
2151                                                        var_success = true;
2152                                                }
2153                                            }
2154                                        }
2155                                        else if (IsToken (var_name_begin, "script:"))
2156                                        {
2157                                            var_name_begin += ::strlen("script:");
2158                                            std::string script_name(var_name_begin,var_name_end);
2159                                            ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2160                                            if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2161                                                var_success = true;
2162                                        }
2163                                    }
2164                                }
2165                            }
2166                            else if (IsToken (var_name_begin, "function."))
2167                            {
2168                                if (sc && (sc->function != NULL || sc->symbol != NULL))
2169                                {
2170                                    var_name_begin += ::strlen ("function.");
2171                                    if (IsToken (var_name_begin, "id}"))
2172                                    {
2173                                        if (sc->function)
2174                                            s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
2175                                        else
2176                                            s.Printf("symbol[%u]", sc->symbol->GetID());
2177
2178                                        var_success = true;
2179                                    }
2180                                    else if (IsToken (var_name_begin, "name}"))
2181                                    {
2182                                        if (sc->function)
2183                                            cstr = sc->function->GetName().AsCString (NULL);
2184                                        else if (sc->symbol)
2185                                            cstr = sc->symbol->GetName().AsCString (NULL);
2186                                        if (cstr)
2187                                        {
2188                                            s.PutCString(cstr);
2189
2190                                            if (sc->block)
2191                                            {
2192                                                Block *inline_block = sc->block->GetContainingInlinedBlock ();
2193                                                if (inline_block)
2194                                                {
2195                                                    const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
2196                                                    if (inline_info)
2197                                                    {
2198                                                        s.PutCString(" [inlined] ");
2199                                                        inline_info->GetName().Dump(&s);
2200                                                    }
2201                                                }
2202                                            }
2203                                            var_success = true;
2204                                        }
2205                                    }
2206                                    else if (IsToken (var_name_begin, "name-with-args}"))
2207                                    {
2208                                        // Print the function name with arguments in it
2209
2210                                        if (sc->function)
2211                                        {
2212                                            var_success = true;
2213                                            ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
2214                                            cstr = sc->function->GetName().AsCString (NULL);
2215                                            if (cstr)
2216                                            {
2217                                                const InlineFunctionInfo *inline_info = NULL;
2218                                                VariableListSP variable_list_sp;
2219                                                bool get_function_vars = true;
2220                                                if (sc->block)
2221                                                {
2222                                                    Block *inline_block = sc->block->GetContainingInlinedBlock ();
2223
2224                                                    if (inline_block)
2225                                                    {
2226                                                        get_function_vars = false;
2227                                                        inline_info = sc->block->GetInlinedFunctionInfo();
2228                                                        if (inline_info)
2229                                                            variable_list_sp = inline_block->GetBlockVariableList (true);
2230                                                    }
2231                                                }
2232
2233                                                if (get_function_vars)
2234                                                {
2235                                                    variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
2236                                                }
2237
2238                                                if (inline_info)
2239                                                {
2240                                                    s.PutCString (cstr);
2241                                                    s.PutCString (" [inlined] ");
2242                                                    cstr = inline_info->GetName().GetCString();
2243                                                }
2244
2245                                                VariableList args;
2246                                                if (variable_list_sp)
2247                                                    variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
2248                                                if (args.GetSize() > 0)
2249                                                {
2250                                                    const char *open_paren = strchr (cstr, '(');
2251                                                    const char *close_paren = NULL;
2252                                                    if (open_paren)
2253                                                    {
2254                                                        if (IsToken (open_paren, "(anonymous namespace)"))
2255                                                        {
2256                                                            open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2257                                                            if (open_paren)
2258                                                                close_paren = strchr (open_paren, ')');
2259                                                        }
2260                                                        else
2261                                                            close_paren = strchr (open_paren, ')');
2262                                                    }
2263
2264                                                    if (open_paren)
2265                                                        s.Write(cstr, open_paren - cstr + 1);
2266                                                    else
2267                                                    {
2268                                                        s.PutCString (cstr);
2269                                                        s.PutChar ('(');
2270                                                    }
2271                                                    const size_t num_args = args.GetSize();
2272                                                    for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
2273                                                    {
2274                                                        VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
2275                                                        ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2276                                                        const char *var_name = var_value_sp->GetName().GetCString();
2277                                                        const char *var_value = var_value_sp->GetValueAsCString();
2278                                                        if (arg_idx > 0)
2279                                                            s.PutCString (", ");
2280                                                        if (var_value_sp->GetError().Success())
2281                                                        {
2282                                                            if (var_value)
2283                                                                s.Printf ("%s=%s", var_name, var_value);
2284                                                            else
2285                                                                s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2286                                                        }
2287                                                        else
2288                                                            s.Printf ("%s=<unavailable>", var_name);
2289                                                    }
2290
2291                                                    if (close_paren)
2292                                                        s.PutCString (close_paren);
2293                                                    else
2294                                                        s.PutChar(')');
2295
2296                                                }
2297                                                else
2298                                                {
2299                                                    s.PutCString(cstr);
2300                                                }
2301                                            }
2302                                        }
2303                                        else if (sc->symbol)
2304                                        {
2305                                            cstr = sc->symbol->GetName().AsCString (NULL);
2306                                            if (cstr)
2307                                            {
2308                                                s.PutCString(cstr);
2309                                                var_success = true;
2310                                            }
2311                                        }
2312                                    }
2313                                    else if (IsToken (var_name_begin, "addr-offset}"))
2314                                    {
2315                                        var_success = addr != NULL;
2316                                        if (var_success)
2317                                        {
2318                                            format_addr = *addr;
2319                                            calculate_format_addr_function_offset = true;
2320                                        }
2321                                    }
2322                                    else if (IsToken (var_name_begin, "line-offset}"))
2323                                    {
2324                                        var_success = sc->line_entry.range.GetBaseAddress().IsValid();
2325                                        if (var_success)
2326                                        {
2327                                            format_addr = sc->line_entry.range.GetBaseAddress();
2328                                            calculate_format_addr_function_offset = true;
2329                                        }
2330                                    }
2331                                    else if (IsToken (var_name_begin, "pc-offset}"))
2332                                    {
2333                                        StackFrame *frame = exe_ctx->GetFramePtr();
2334                                        var_success = frame != NULL;
2335                                        if (var_success)
2336                                        {
2337                                            format_addr = frame->GetFrameCodeAddress();
2338                                            calculate_format_addr_function_offset = true;
2339                                        }
2340                                    }
2341                                }
2342                            }
2343                            break;
2344
2345                        case 'l':
2346                            if (IsToken (var_name_begin, "line."))
2347                            {
2348                                if (sc && sc->line_entry.IsValid())
2349                                {
2350                                    var_name_begin += ::strlen ("line.");
2351                                    if (IsToken (var_name_begin, "file."))
2352                                    {
2353                                        var_name_begin += ::strlen ("file.");
2354
2355                                        if (IsToken (var_name_begin, "basename}"))
2356                                        {
2357                                            format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
2358                                            var_success = format_file_spec;
2359                                        }
2360                                        else if (IsToken (var_name_begin, "fullpath}"))
2361                                        {
2362                                            format_file_spec = sc->line_entry.file;
2363                                            var_success = format_file_spec;
2364                                        }
2365                                    }
2366                                    else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
2367                                    {
2368                                        var_success = true;
2369                                        s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
2370                                    }
2371                                    else if ((IsToken (var_name_begin, "start-addr}")) ||
2372                                             (IsToken (var_name_begin, "end-addr}")))
2373                                    {
2374                                        var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
2375                                        if (var_success)
2376                                        {
2377                                            format_addr = sc->line_entry.range.GetBaseAddress();
2378                                            if (var_name_begin[0] == 'e')
2379                                                format_addr.Slide (sc->line_entry.range.GetByteSize());
2380                                        }
2381                                    }
2382                                }
2383                            }
2384                            break;
2385                        }
2386
2387                        if (var_success)
2388                        {
2389                            // If format addr is valid, then we need to print an address
2390                            if (reg_num != LLDB_INVALID_REGNUM)
2391                            {
2392                                StackFrame *frame = exe_ctx->GetFramePtr();
2393                                // We have a register value to display...
2394                                if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
2395                                {
2396                                    format_addr = frame->GetFrameCodeAddress();
2397                                }
2398                                else
2399                                {
2400                                    if (reg_ctx == NULL)
2401                                        reg_ctx = frame->GetRegisterContext().get();
2402
2403                                    if (reg_ctx)
2404                                    {
2405                                        if (reg_kind != kNumRegisterKinds)
2406                                            reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
2407                                        reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
2408                                        var_success = reg_info != NULL;
2409                                    }
2410                                }
2411                            }
2412
2413                            if (reg_info != NULL)
2414                            {
2415                                RegisterValue reg_value;
2416                                var_success = reg_ctx->ReadRegister (reg_info, reg_value);
2417                                if (var_success)
2418                                {
2419                                    reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
2420                                }
2421                            }
2422
2423                            if (format_file_spec)
2424                            {
2425                                s << format_file_spec;
2426                            }
2427
2428                            // If format addr is valid, then we need to print an address
2429                            if (format_addr.IsValid())
2430                            {
2431                                var_success = false;
2432
2433                                if (calculate_format_addr_function_offset)
2434                                {
2435                                    Address func_addr;
2436
2437                                    if (sc)
2438                                    {
2439                                        if (sc->function)
2440                                        {
2441                                            func_addr = sc->function->GetAddressRange().GetBaseAddress();
2442                                            if (sc->block)
2443                                            {
2444                                                // Check to make sure we aren't in an inline
2445                                                // function. If we are, use the inline block
2446                                                // range that contains "format_addr" since
2447                                                // blocks can be discontiguous.
2448                                                Block *inline_block = sc->block->GetContainingInlinedBlock ();
2449                                                AddressRange inline_range;
2450                                                if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
2451                                                    func_addr = inline_range.GetBaseAddress();
2452                                            }
2453                                        }
2454                                        else if (sc->symbol && sc->symbol->ValueIsAddress())
2455                                            func_addr = sc->symbol->GetAddress();
2456                                    }
2457
2458                                    if (func_addr.IsValid())
2459                                    {
2460                                        if (func_addr.GetSection() == format_addr.GetSection())
2461                                        {
2462                                            addr_t func_file_addr = func_addr.GetFileAddress();
2463                                            addr_t addr_file_addr = format_addr.GetFileAddress();
2464                                            if (addr_file_addr > func_file_addr)
2465                                                s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
2466                                            else if (addr_file_addr < func_file_addr)
2467                                                s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
2468                                            var_success = true;
2469                                        }
2470                                        else
2471                                        {
2472                                            Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2473                                            if (target)
2474                                            {
2475                                                addr_t func_load_addr = func_addr.GetLoadAddress (target);
2476                                                addr_t addr_load_addr = format_addr.GetLoadAddress (target);
2477                                                if (addr_load_addr > func_load_addr)
2478                                                    s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
2479                                                else if (addr_load_addr < func_load_addr)
2480                                                    s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
2481                                                var_success = true;
2482                                            }
2483                                        }
2484                                    }
2485                                }
2486                                else
2487                                {
2488                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2489                                    addr_t vaddr = LLDB_INVALID_ADDRESS;
2490                                    if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
2491                                        vaddr = format_addr.GetLoadAddress (target);
2492                                    if (vaddr == LLDB_INVALID_ADDRESS)
2493                                        vaddr = format_addr.GetFileAddress ();
2494
2495                                    if (vaddr != LLDB_INVALID_ADDRESS)
2496                                    {
2497                                        int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2498                                        if (addr_width == 0)
2499                                            addr_width = 16;
2500                                        s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
2501                                        var_success = true;
2502                                    }
2503                                }
2504                            }
2505                        }
2506
2507                        if (var_success == false)
2508                            success = false;
2509                    }
2510                    p = var_name_end;
2511                }
2512                else
2513                    break;
2514            }
2515            else
2516            {
2517                // We got a dollar sign with no '{' after it, it must just be a dollar sign
2518                s.PutChar(*p);
2519            }
2520        }
2521        else if (*p == '\\')
2522        {
2523            ++p; // skip the slash
2524            switch (*p)
2525            {
2526            case 'a': s.PutChar ('\a'); break;
2527            case 'b': s.PutChar ('\b'); break;
2528            case 'f': s.PutChar ('\f'); break;
2529            case 'n': s.PutChar ('\n'); break;
2530            case 'r': s.PutChar ('\r'); break;
2531            case 't': s.PutChar ('\t'); break;
2532            case 'v': s.PutChar ('\v'); break;
2533            case '\'': s.PutChar ('\''); break;
2534            case '\\': s.PutChar ('\\'); break;
2535            case '0':
2536                // 1 to 3 octal chars
2537                {
2538                    // Make a string that can hold onto the initial zero char,
2539                    // up to 3 octal digits, and a terminating NULL.
2540                    char oct_str[5] = { 0, 0, 0, 0, 0 };
2541
2542                    int i;
2543                    for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2544                        oct_str[i] = p[i];
2545
2546                    // We don't want to consume the last octal character since
2547                    // the main for loop will do this for us, so we advance p by
2548                    // one less than i (even if i is zero)
2549                    p += i - 1;
2550                    unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2551                    if (octal_value <= UINT8_MAX)
2552                    {
2553                        s.PutChar((char)octal_value);
2554                    }
2555                }
2556                break;
2557
2558            case 'x':
2559                // hex number in the format
2560                if (isxdigit(p[1]))
2561                {
2562                    ++p;    // Skip the 'x'
2563
2564                    // Make a string that can hold onto two hex chars plus a
2565                    // NULL terminator
2566                    char hex_str[3] = { 0,0,0 };
2567                    hex_str[0] = *p;
2568                    if (isxdigit(p[1]))
2569                    {
2570                        ++p; // Skip the first of the two hex chars
2571                        hex_str[1] = *p;
2572                    }
2573
2574                    unsigned long hex_value = strtoul (hex_str, NULL, 16);
2575                    if (hex_value <= UINT8_MAX)
2576                        s.PutChar ((char)hex_value);
2577                }
2578                else
2579                {
2580                    s.PutChar('x');
2581                }
2582                break;
2583
2584            default:
2585                // Just desensitize any other character by just printing what
2586                // came after the '\'
2587                s << *p;
2588                break;
2589
2590            }
2591
2592        }
2593    }
2594    if (end)
2595        *end = p;
2596    return success;
2597}
2598
2599bool
2600Debugger::FormatPrompt
2601(
2602    const char *format,
2603    const SymbolContext *sc,
2604    const ExecutionContext *exe_ctx,
2605    const Address *addr,
2606    Stream &s,
2607    ValueObject* valobj
2608)
2609{
2610    bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2611    std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2612    if (format_str.length())
2613        format = format_str.c_str();
2614    return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj);
2615}
2616
2617void
2618Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2619{
2620    // For simplicity's sake, I am not going to deal with how to close down any
2621    // open logging streams, I just redirect everything from here on out to the
2622    // callback.
2623    m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2624}
2625
2626bool
2627Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2628{
2629    Log::Callbacks log_callbacks;
2630
2631    StreamSP log_stream_sp;
2632    if (m_log_callback_stream_sp)
2633    {
2634        log_stream_sp = m_log_callback_stream_sp;
2635        // For now when using the callback mode you always get thread & timestamp.
2636        log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2637    }
2638    else if (log_file == NULL || *log_file == '\0')
2639    {
2640        log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2641    }
2642    else
2643    {
2644        LogStreamMap::iterator pos = m_log_streams.find(log_file);
2645        if (pos != m_log_streams.end())
2646            log_stream_sp = pos->second.lock();
2647        if (!log_stream_sp)
2648        {
2649            log_stream_sp.reset (new StreamFile (log_file));
2650            m_log_streams[log_file] = log_stream_sp;
2651        }
2652    }
2653    assert (log_stream_sp.get());
2654
2655    if (log_options == 0)
2656        log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2657
2658    if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2659    {
2660        log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2661        return true;
2662    }
2663    else
2664    {
2665        LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2666        if (log_channel_sp)
2667        {
2668            if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2669            {
2670                return true;
2671            }
2672            else
2673            {
2674                error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2675                return false;
2676            }
2677        }
2678        else
2679        {
2680            error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2681            return false;
2682        }
2683    }
2684    return false;
2685}
2686
2687SourceManager &
2688Debugger::GetSourceManager ()
2689{
2690    if (m_source_manager_ap.get() == NULL)
2691        m_source_manager_ap.reset (new SourceManager (shared_from_this()));
2692    return *m_source_manager_ap;
2693}
2694
2695
2696