1 //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-python.h"
11 
12 #include "lldb/Core/Debugger.h"
13 
14 #include <map>
15 
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/Type.h"
18 #include "llvm/ADT/StringRef.h"
19 
20 #include "lldb/lldb-private.h"
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/PluginManager.h"
23 #include "lldb/Core/RegisterValue.h"
24 #include "lldb/Core/State.h"
25 #include "lldb/Core/StreamAsynchronousIO.h"
26 #include "lldb/Core/StreamCallback.h"
27 #include "lldb/Core/StreamFile.h"
28 #include "lldb/Core/StreamString.h"
29 #include "lldb/Core/StructuredData.h"
30 #include "lldb/Core/Timer.h"
31 #include "lldb/Core/ValueObject.h"
32 #include "lldb/Core/ValueObjectVariable.h"
33 #include "lldb/DataFormatters/DataVisualization.h"
34 #include "lldb/DataFormatters/FormatManager.h"
35 #include "lldb/DataFormatters/TypeSummary.h"
36 #include "lldb/Host/ConnectionFileDescriptor.h"
37 #include "lldb/Host/HostInfo.h"
38 #include "lldb/Host/Terminal.h"
39 #include "lldb/Host/ThreadLauncher.h"
40 #include "lldb/Interpreter/CommandInterpreter.h"
41 #include "lldb/Interpreter/OptionValueSInt64.h"
42 #include "lldb/Interpreter/OptionValueString.h"
43 #include "lldb/Symbol/ClangASTContext.h"
44 #include "lldb/Symbol/CompileUnit.h"
45 #include "lldb/Symbol/Function.h"
46 #include "lldb/Symbol/Symbol.h"
47 #include "lldb/Symbol/VariableList.h"
48 #include "lldb/Target/CPPLanguageRuntime.h"
49 #include "lldb/Target/ObjCLanguageRuntime.h"
50 #include "lldb/Target/TargetList.h"
51 #include "lldb/Target/Process.h"
52 #include "lldb/Target/RegisterContext.h"
53 #include "lldb/Target/SectionLoadList.h"
54 #include "lldb/Target/StopInfo.h"
55 #include "lldb/Target/Target.h"
56 #include "lldb/Target/Thread.h"
57 #include "lldb/Utility/AnsiTerminal.h"
58 
59 #include "llvm/Support/DynamicLibrary.h"
60 
61 using namespace lldb;
62 using namespace lldb_private;
63 
64 
65 static uint32_t g_shared_debugger_refcount = 0;
66 static lldb::user_id_t g_unique_id = 1;
67 static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
68 
69 #pragma mark Static Functions
70 
71 static Mutex &
72 GetDebuggerListMutex ()
73 {
74     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
75     return g_mutex;
76 }
77 
78 typedef std::vector<DebuggerSP> DebuggerList;
79 
80 static DebuggerList &
81 GetDebuggerList()
82 {
83     // hide the static debugger list inside a singleton accessor to avoid
84     // global init constructors
85     static DebuggerList g_list;
86     return g_list;
87 }
88 
89 OptionEnumValueElement
90 g_show_disassembly_enum_values[] =
91 {
92     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
93     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
94     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
95     { 0, NULL, NULL }
96 };
97 
98 OptionEnumValueElement
99 g_language_enumerators[] =
100 {
101     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
102     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
103     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
104     { 0, NULL, NULL }
105 };
106 
107 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
108 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
109 
110 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
111     "{, ${frame.pc}}"\
112     MODULE_WITH_FUNC\
113     FILE_AND_LINE\
114     "{, name = '${thread.name}'}"\
115     "{, queue = '${thread.queue}'}"\
116     "{, activity = '${thread.info.activity.name}'}" \
117     "{, ${thread.info.trace_messages} messages}" \
118     "{, stop reason = ${thread.stop-reason}}"\
119     "{\\nReturn value: ${thread.return-value}}"\
120     "{\\nCompleted expression: ${thread.completed-expression}}"\
121     "\\n"
122 
123 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
124     MODULE_WITH_FUNC\
125     FILE_AND_LINE\
126     "\\n"
127 
128 #define DEFAULT_DISASSEMBLY_FORMAT "${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: "
129 
130 static PropertyDefinition
131 g_properties[] =
132 {
133 {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
134 {   "disassembly-format",       OptionValue::eTypeString , true, 0    , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
135 {   "frame-format",             OptionValue::eTypeString , true, 0    , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
136 {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
137 {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
138 {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
139 {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
140 {   "stop-disassembly-display", OptionValue::eTypeEnum   , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
141 {   "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." },
142 {   "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." },
143 {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
144 {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
145 {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
146 {   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
147 {   "auto-one-line-summaries",  OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
148 {   "escape-non-printables",    OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
149 
150     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
151 };
152 
153 enum
154 {
155     ePropertyAutoConfirm = 0,
156     ePropertyDisassemblyFormat,
157     ePropertyFrameFormat,
158     ePropertyNotiftVoid,
159     ePropertyPrompt,
160     ePropertyScriptLanguage,
161     ePropertyStopDisassemblyCount,
162     ePropertyStopDisassemblyDisplay,
163     ePropertyStopLineCountAfter,
164     ePropertyStopLineCountBefore,
165     ePropertyTerminalWidth,
166     ePropertyThreadFormat,
167     ePropertyUseExternalEditor,
168     ePropertyUseColor,
169     ePropertyAutoOneLineSummaries,
170     ePropertyEscapeNonPrintables
171 };
172 
173 Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
174 
175 Error
176 Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
177                             VarSetOperationType op,
178                             const char *property_path,
179                             const char *value)
180 {
181     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
182     bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
183     TargetSP target_sp;
184     LoadScriptFromSymFile load_script_old_value;
185     if (is_load_script && exe_ctx->GetTargetSP())
186     {
187         target_sp = exe_ctx->GetTargetSP();
188         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
189     }
190     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
191     if (error.Success())
192     {
193         // FIXME it would be nice to have "on-change" callbacks for properties
194         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
195         {
196             const char *new_prompt = GetPrompt();
197             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
198             if (str.length())
199                 new_prompt = str.c_str();
200             GetCommandInterpreter().UpdatePrompt(new_prompt);
201             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
202             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
203         }
204         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
205         {
206 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
207             SetPrompt (GetPrompt());
208         }
209         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
210         {
211             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
212             {
213                 std::list<Error> errors;
214                 StreamString feedback_stream;
215                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
216                 {
217                     StreamFileSP stream_sp (GetErrorFile());
218                     if (stream_sp)
219                     {
220                         for (auto error : errors)
221                         {
222                             stream_sp->Printf("%s\n",error.AsCString());
223                         }
224                         if (feedback_stream.GetSize())
225                             stream_sp->Printf("%s",feedback_stream.GetData());
226                     }
227                 }
228             }
229         }
230         else if (is_escape_non_printables)
231         {
232             DataVisualization::ForceUpdate();
233         }
234     }
235     return error;
236 }
237 
238 bool
239 Debugger::GetAutoConfirm () const
240 {
241     const uint32_t idx = ePropertyAutoConfirm;
242     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
243 }
244 
245 const char *
246 Debugger::GetDisassemblyFormat() const
247 {
248     const uint32_t idx = ePropertyDisassemblyFormat;
249     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
250 }
251 
252 const char *
253 Debugger::GetFrameFormat() const
254 {
255     const uint32_t idx = ePropertyFrameFormat;
256     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
257 }
258 
259 bool
260 Debugger::GetNotifyVoid () const
261 {
262     const uint32_t idx = ePropertyNotiftVoid;
263     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
264 }
265 
266 const char *
267 Debugger::GetPrompt() const
268 {
269     const uint32_t idx = ePropertyPrompt;
270     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
271 }
272 
273 void
274 Debugger::SetPrompt(const char *p)
275 {
276     const uint32_t idx = ePropertyPrompt;
277     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
278     const char *new_prompt = GetPrompt();
279     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
280     if (str.length())
281         new_prompt = str.c_str();
282     GetCommandInterpreter().UpdatePrompt(new_prompt);
283 }
284 
285 const char *
286 Debugger::GetThreadFormat() const
287 {
288     const uint32_t idx = ePropertyThreadFormat;
289     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
290 }
291 
292 lldb::ScriptLanguage
293 Debugger::GetScriptLanguage() const
294 {
295     const uint32_t idx = ePropertyScriptLanguage;
296     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
297 }
298 
299 bool
300 Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
301 {
302     const uint32_t idx = ePropertyScriptLanguage;
303     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
304 }
305 
306 uint32_t
307 Debugger::GetTerminalWidth () const
308 {
309     const uint32_t idx = ePropertyTerminalWidth;
310     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
311 }
312 
313 bool
314 Debugger::SetTerminalWidth (uint32_t term_width)
315 {
316     const uint32_t idx = ePropertyTerminalWidth;
317     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
318 }
319 
320 bool
321 Debugger::GetUseExternalEditor () const
322 {
323     const uint32_t idx = ePropertyUseExternalEditor;
324     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
325 }
326 
327 bool
328 Debugger::SetUseExternalEditor (bool b)
329 {
330     const uint32_t idx = ePropertyUseExternalEditor;
331     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
332 }
333 
334 bool
335 Debugger::GetUseColor () const
336 {
337     const uint32_t idx = ePropertyUseColor;
338     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
339 }
340 
341 bool
342 Debugger::SetUseColor (bool b)
343 {
344     const uint32_t idx = ePropertyUseColor;
345     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
346     SetPrompt (GetPrompt());
347     return ret;
348 }
349 
350 uint32_t
351 Debugger::GetStopSourceLineCount (bool before) const
352 {
353     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
354     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
355 }
356 
357 Debugger::StopDisassemblyType
358 Debugger::GetStopDisassemblyDisplay () const
359 {
360     const uint32_t idx = ePropertyStopDisassemblyDisplay;
361     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
362 }
363 
364 uint32_t
365 Debugger::GetDisassemblyLineCount () const
366 {
367     const uint32_t idx = ePropertyStopDisassemblyCount;
368     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
369 }
370 
371 bool
372 Debugger::GetAutoOneLineSummaries () const
373 {
374     const uint32_t idx = ePropertyAutoOneLineSummaries;
375     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
376 }
377 
378 bool
379 Debugger::GetEscapeNonPrintables () const
380 {
381     const uint32_t idx = ePropertyEscapeNonPrintables;
382     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
383 }
384 
385 #pragma mark Debugger
386 
387 //const DebuggerPropertiesSP &
388 //Debugger::GetSettings() const
389 //{
390 //    return m_properties_sp;
391 //}
392 //
393 
394 int
395 Debugger::TestDebuggerRefCount ()
396 {
397     return g_shared_debugger_refcount;
398 }
399 
400 void
401 Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
402 {
403     g_load_plugin_callback = load_plugin_callback;
404     if (g_shared_debugger_refcount++ == 0)
405         lldb_private::Initialize();
406 }
407 
408 void
409 Debugger::Terminate ()
410 {
411     if (g_shared_debugger_refcount > 0)
412     {
413         g_shared_debugger_refcount--;
414         if (g_shared_debugger_refcount == 0)
415         {
416             lldb_private::WillTerminate();
417             lldb_private::Terminate();
418 
419             // Clear our master list of debugger objects
420             Mutex::Locker locker (GetDebuggerListMutex ());
421             GetDebuggerList().clear();
422         }
423     }
424 }
425 
426 void
427 Debugger::SettingsInitialize ()
428 {
429     Target::SettingsInitialize ();
430 }
431 
432 void
433 Debugger::SettingsTerminate ()
434 {
435     Target::SettingsTerminate ();
436 }
437 
438 bool
439 Debugger::LoadPlugin (const FileSpec& spec, Error& error)
440 {
441     if (g_load_plugin_callback)
442     {
443         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
444         if (dynlib.isValid())
445         {
446             m_loaded_plugins.push_back(dynlib);
447             return true;
448         }
449     }
450     else
451     {
452         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
453         // and if the public API layer isn't available (code is linking against
454         // all of the internal LLDB static libraries), then we can't load plugins
455         error.SetErrorString("Public API layer is not available");
456     }
457     return false;
458 }
459 
460 static FileSpec::EnumerateDirectoryResult
461 LoadPluginCallback
462 (
463  void *baton,
464  FileSpec::FileType file_type,
465  const FileSpec &file_spec
466  )
467 {
468     Error error;
469 
470     static ConstString g_dylibext("dylib");
471     static ConstString g_solibext("so");
472 
473     if (!baton)
474         return FileSpec::eEnumerateDirectoryResultQuit;
475 
476     Debugger *debugger = (Debugger*)baton;
477 
478     // If we have a regular file, a symbolic link or unknown file type, try
479     // and process the file. We must handle unknown as sometimes the directory
480     // enumeration might be enumerating a file system that doesn't have correct
481     // file type information.
482     if (file_type == FileSpec::eFileTypeRegular         ||
483         file_type == FileSpec::eFileTypeSymbolicLink    ||
484         file_type == FileSpec::eFileTypeUnknown          )
485     {
486         FileSpec plugin_file_spec (file_spec);
487         plugin_file_spec.ResolvePath ();
488 
489         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
490             plugin_file_spec.GetFileNameExtension() != g_solibext)
491         {
492             return FileSpec::eEnumerateDirectoryResultNext;
493         }
494 
495         Error plugin_load_error;
496         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
497 
498         return FileSpec::eEnumerateDirectoryResultNext;
499     }
500 
501     else if (file_type == FileSpec::eFileTypeUnknown     ||
502         file_type == FileSpec::eFileTypeDirectory   ||
503         file_type == FileSpec::eFileTypeSymbolicLink )
504     {
505         // Try and recurse into anything that a directory or symbolic link.
506         // We must also do this for unknown as sometimes the directory enumeration
507         // might be enumerating a file system that doesn't have correct file type
508         // information.
509         return FileSpec::eEnumerateDirectoryResultEnter;
510     }
511 
512     return FileSpec::eEnumerateDirectoryResultNext;
513 }
514 
515 void
516 Debugger::InstanceInitialize ()
517 {
518     FileSpec dir_spec;
519     const bool find_directories = true;
520     const bool find_files = true;
521     const bool find_other = true;
522     char dir_path[PATH_MAX];
523     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
524     {
525         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
526         {
527             FileSpec::EnumerateDirectory (dir_path,
528                                           find_directories,
529                                           find_files,
530                                           find_other,
531                                           LoadPluginCallback,
532                                           this);
533         }
534     }
535 
536     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
537     {
538         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
539         {
540             FileSpec::EnumerateDirectory (dir_path,
541                                           find_directories,
542                                           find_files,
543                                           find_other,
544                                           LoadPluginCallback,
545                                           this);
546         }
547     }
548 
549     PluginManager::DebuggerInitialize (*this);
550 }
551 
552 DebuggerSP
553 Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
554 {
555     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
556     if (g_shared_debugger_refcount > 0)
557     {
558         Mutex::Locker locker (GetDebuggerListMutex ());
559         GetDebuggerList().push_back(debugger_sp);
560     }
561     debugger_sp->InstanceInitialize ();
562     return debugger_sp;
563 }
564 
565 void
566 Debugger::Destroy (DebuggerSP &debugger_sp)
567 {
568     if (debugger_sp.get() == NULL)
569         return;
570 
571     debugger_sp->Clear();
572 
573     if (g_shared_debugger_refcount > 0)
574     {
575         Mutex::Locker locker (GetDebuggerListMutex ());
576         DebuggerList &debugger_list = GetDebuggerList ();
577         DebuggerList::iterator pos, end = debugger_list.end();
578         for (pos = debugger_list.begin (); pos != end; ++pos)
579         {
580             if ((*pos).get() == debugger_sp.get())
581             {
582                 debugger_list.erase (pos);
583                 return;
584             }
585         }
586     }
587 }
588 
589 DebuggerSP
590 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
591 {
592     DebuggerSP debugger_sp;
593     if (g_shared_debugger_refcount > 0)
594     {
595         Mutex::Locker locker (GetDebuggerListMutex ());
596         DebuggerList &debugger_list = GetDebuggerList();
597         DebuggerList::iterator pos, end = debugger_list.end();
598 
599         for (pos = debugger_list.begin(); pos != end; ++pos)
600         {
601             if ((*pos).get()->m_instance_name == instance_name)
602             {
603                 debugger_sp = *pos;
604                 break;
605             }
606         }
607     }
608     return debugger_sp;
609 }
610 
611 TargetSP
612 Debugger::FindTargetWithProcessID (lldb::pid_t pid)
613 {
614     TargetSP target_sp;
615     if (g_shared_debugger_refcount > 0)
616     {
617         Mutex::Locker locker (GetDebuggerListMutex ());
618         DebuggerList &debugger_list = GetDebuggerList();
619         DebuggerList::iterator pos, end = debugger_list.end();
620         for (pos = debugger_list.begin(); pos != end; ++pos)
621         {
622             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
623             if (target_sp)
624                 break;
625         }
626     }
627     return target_sp;
628 }
629 
630 TargetSP
631 Debugger::FindTargetWithProcess (Process *process)
632 {
633     TargetSP target_sp;
634     if (g_shared_debugger_refcount > 0)
635     {
636         Mutex::Locker locker (GetDebuggerListMutex ());
637         DebuggerList &debugger_list = GetDebuggerList();
638         DebuggerList::iterator pos, end = debugger_list.end();
639         for (pos = debugger_list.begin(); pos != end; ++pos)
640         {
641             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
642             if (target_sp)
643                 break;
644         }
645     }
646     return target_sp;
647 }
648 
649 Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
650     UserID(g_unique_id++),
651     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
652     m_input_file_sp(new StreamFile(stdin, false)),
653     m_output_file_sp(new StreamFile(stdout, false)),
654     m_error_file_sp(new StreamFile(stderr, false)),
655     m_terminal_state(),
656     m_target_list(*this),
657     m_platform_list(),
658     m_listener("lldb.Debugger"),
659     m_source_manager_ap(),
660     m_source_file_cache(),
661     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
662     m_input_reader_stack(),
663     m_instance_name(),
664     m_loaded_plugins(),
665     m_event_handler_thread (),
666     m_io_handler_thread (),
667     m_sync_broadcaster (NULL, "lldb.debugger.sync")
668 {
669     char instance_cstr[256];
670     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
671     m_instance_name.SetCString(instance_cstr);
672     if (log_callback)
673         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
674     m_command_interpreter_ap->Initialize ();
675     // Always add our default platform to the platform list
676     PlatformSP default_platform_sp (Platform::GetHostPlatform());
677     assert (default_platform_sp.get());
678     m_platform_list.Append (default_platform_sp, true);
679 
680     m_collection_sp->Initialize (g_properties);
681     m_collection_sp->AppendProperty (ConstString("target"),
682                                      ConstString("Settings specify to debugging targets."),
683                                      true,
684                                      Target::GetGlobalProperties()->GetValueProperties());
685     if (m_command_interpreter_ap.get())
686     {
687         m_collection_sp->AppendProperty (ConstString("interpreter"),
688                                          ConstString("Settings specify to the debugger's command interpreter."),
689                                          true,
690                                          m_command_interpreter_ap->GetValueProperties());
691     }
692     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
693     term_width->SetMinimumValue(10);
694     term_width->SetMaximumValue(1024);
695 
696     // Turn off use-color if this is a dumb terminal.
697     const char *term = getenv ("TERM");
698     if (term && !strcmp (term, "dumb"))
699         SetUseColor (false);
700 }
701 
702 Debugger::~Debugger ()
703 {
704     Clear();
705 }
706 
707 void
708 Debugger::Clear()
709 {
710     ClearIOHandlers();
711     StopIOHandlerThread();
712     StopEventHandlerThread();
713     m_listener.Clear();
714     int num_targets = m_target_list.GetNumTargets();
715     for (int i = 0; i < num_targets; i++)
716     {
717         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
718         if (target_sp)
719         {
720             ProcessSP process_sp (target_sp->GetProcessSP());
721             if (process_sp)
722                 process_sp->Finalize();
723             target_sp->Destroy();
724         }
725     }
726     BroadcasterManager::Clear ();
727 
728     // Close the input file _before_ we close the input read communications class
729     // as it does NOT own the input file, our m_input_file does.
730     m_terminal_state.Clear();
731     if (m_input_file_sp)
732         m_input_file_sp->GetFile().Close ();
733 
734     m_command_interpreter_ap->Clear();
735 }
736 
737 bool
738 Debugger::GetCloseInputOnEOF () const
739 {
740 //    return m_input_comm.GetCloseOnEOF();
741     return false;
742 }
743 
744 void
745 Debugger::SetCloseInputOnEOF (bool b)
746 {
747 //    m_input_comm.SetCloseOnEOF(b);
748 }
749 
750 bool
751 Debugger::GetAsyncExecution ()
752 {
753     return !m_command_interpreter_ap->GetSynchronous();
754 }
755 
756 void
757 Debugger::SetAsyncExecution (bool async_execution)
758 {
759     m_command_interpreter_ap->SetSynchronous (!async_execution);
760 }
761 
762 
763 void
764 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
765 {
766     if (m_input_file_sp)
767         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
768     else
769         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
770 
771     File &in_file = m_input_file_sp->GetFile();
772     if (in_file.IsValid() == false)
773         in_file.SetStream (stdin, true);
774 
775     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
776     SaveInputTerminalState ();
777 }
778 
779 void
780 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
781 {
782     if (m_output_file_sp)
783         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
784     else
785         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
786 
787     File &out_file = m_output_file_sp->GetFile();
788     if (out_file.IsValid() == false)
789         out_file.SetStream (stdout, false);
790 
791     // do not create the ScriptInterpreter just for setting the output file handle
792     // as the constructor will know how to do the right thing on its own
793     const bool can_create = false;
794     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
795     if (script_interpreter)
796         script_interpreter->ResetOutputFileHandle (fh);
797 }
798 
799 void
800 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
801 {
802     if (m_error_file_sp)
803         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
804     else
805         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
806 
807     File &err_file = m_error_file_sp->GetFile();
808     if (err_file.IsValid() == false)
809         err_file.SetStream (stderr, false);
810 }
811 
812 void
813 Debugger::SaveInputTerminalState ()
814 {
815     if (m_input_file_sp)
816     {
817         File &in_file = m_input_file_sp->GetFile();
818         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
819             m_terminal_state.Save(in_file.GetDescriptor(), true);
820     }
821 }
822 
823 void
824 Debugger::RestoreInputTerminalState ()
825 {
826     m_terminal_state.Restore();
827 }
828 
829 ExecutionContext
830 Debugger::GetSelectedExecutionContext ()
831 {
832     ExecutionContext exe_ctx;
833     TargetSP target_sp(GetSelectedTarget());
834     exe_ctx.SetTargetSP (target_sp);
835 
836     if (target_sp)
837     {
838         ProcessSP process_sp (target_sp->GetProcessSP());
839         exe_ctx.SetProcessSP (process_sp);
840         if (process_sp && process_sp->IsRunning() == false)
841         {
842             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
843             if (thread_sp)
844             {
845                 exe_ctx.SetThreadSP (thread_sp);
846                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
847                 if (exe_ctx.GetFramePtr() == NULL)
848                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
849             }
850         }
851     }
852     return exe_ctx;
853 }
854 
855 void
856 Debugger::DispatchInputInterrupt ()
857 {
858     Mutex::Locker locker (m_input_reader_stack.GetMutex());
859     IOHandlerSP reader_sp (m_input_reader_stack.Top());
860     if (reader_sp)
861         reader_sp->Interrupt();
862 }
863 
864 void
865 Debugger::DispatchInputEndOfFile ()
866 {
867     Mutex::Locker locker (m_input_reader_stack.GetMutex());
868     IOHandlerSP reader_sp (m_input_reader_stack.Top());
869     if (reader_sp)
870         reader_sp->GotEOF();
871 }
872 
873 void
874 Debugger::ClearIOHandlers ()
875 {
876     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
877     Mutex::Locker locker (m_input_reader_stack.GetMutex());
878     while (m_input_reader_stack.GetSize() > 1)
879     {
880         IOHandlerSP reader_sp (m_input_reader_stack.Top());
881         if (reader_sp)
882         {
883             m_input_reader_stack.Pop();
884             reader_sp->SetIsDone(true);
885             reader_sp->Cancel();
886         }
887     }
888 }
889 
890 void
891 Debugger::ExecuteIOHanders()
892 {
893 
894     while (1)
895     {
896         IOHandlerSP reader_sp(m_input_reader_stack.Top());
897         if (!reader_sp)
898             break;
899 
900         reader_sp->Activate();
901         reader_sp->Run();
902         reader_sp->Deactivate();
903 
904         // Remove all input readers that are done from the top of the stack
905         while (1)
906         {
907             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
908             if (top_reader_sp && top_reader_sp->GetIsDone())
909                 m_input_reader_stack.Pop();
910             else
911                 break;
912         }
913     }
914     ClearIOHandlers();
915 }
916 
917 bool
918 Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
919 {
920     return m_input_reader_stack.IsTop (reader_sp);
921 }
922 
923 
924 ConstString
925 Debugger::GetTopIOHandlerControlSequence(char ch)
926 {
927     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
928 }
929 
930 const char *
931 Debugger::GetIOHandlerCommandPrefix()
932 {
933     return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
934 }
935 
936 const char *
937 Debugger::GetIOHandlerHelpPrologue()
938 {
939     return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
940 }
941 
942 void
943 Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
944 {
945     PushIOHandler (reader_sp);
946 
947     IOHandlerSP top_reader_sp = reader_sp;
948     while (top_reader_sp)
949     {
950         top_reader_sp->Activate();
951         top_reader_sp->Run();
952         top_reader_sp->Deactivate();
953 
954         if (top_reader_sp.get() == reader_sp.get())
955         {
956             if (PopIOHandler (reader_sp))
957                 break;
958         }
959 
960         while (1)
961         {
962             top_reader_sp = m_input_reader_stack.Top();
963             if (top_reader_sp && top_reader_sp->GetIsDone())
964                 m_input_reader_stack.Pop();
965             else
966                 break;
967         }
968     }
969 }
970 
971 void
972 Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
973 {
974     // Before an IOHandler runs, it must have in/out/err streams.
975     // This function is called when one ore more of the streams
976     // are NULL. We use the top input reader's in/out/err streams,
977     // or fall back to the debugger file handles, or we fall back
978     // onto stdin/stdout/stderr as a last resort.
979 
980     Mutex::Locker locker (m_input_reader_stack.GetMutex());
981     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
982     // If no STDIN has been set, then set it appropriately
983     if (!in)
984     {
985         if (top_reader_sp)
986             in = top_reader_sp->GetInputStreamFile();
987         else
988             in = GetInputFile();
989 
990         // If there is nothing, use stdin
991         if (!in)
992             in = StreamFileSP(new StreamFile(stdin, false));
993     }
994     // If no STDOUT has been set, then set it appropriately
995     if (!out)
996     {
997         if (top_reader_sp)
998             out = top_reader_sp->GetOutputStreamFile();
999         else
1000             out = GetOutputFile();
1001 
1002         // If there is nothing, use stdout
1003         if (!out)
1004             out = StreamFileSP(new StreamFile(stdout, false));
1005     }
1006     // If no STDERR has been set, then set it appropriately
1007     if (!err)
1008     {
1009         if (top_reader_sp)
1010             err = top_reader_sp->GetErrorStreamFile();
1011         else
1012             err = GetErrorFile();
1013 
1014         // If there is nothing, use stderr
1015         if (!err)
1016             err = StreamFileSP(new StreamFile(stdout, false));
1017 
1018     }
1019 }
1020 
1021 void
1022 Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
1023 {
1024     if (!reader_sp)
1025         return;
1026 
1027     // Got the current top input reader...
1028     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1029 
1030     // Don't push the same IO handler twice...
1031     if (reader_sp.get() != top_reader_sp.get())
1032     {
1033         // Push our new input reader
1034         m_input_reader_stack.Push (reader_sp);
1035 
1036         // Interrupt the top input reader to it will exit its Run() function
1037         // and let this new input reader take over
1038         if (top_reader_sp)
1039             top_reader_sp->Deactivate();
1040     }
1041 }
1042 
1043 bool
1044 Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
1045 {
1046     bool result = false;
1047 
1048     Mutex::Locker locker (m_input_reader_stack.GetMutex());
1049 
1050     // The reader on the stop of the stack is done, so let the next
1051     // read on the stack refresh its prompt and if there is one...
1052     if (!m_input_reader_stack.IsEmpty())
1053     {
1054         IOHandlerSP reader_sp(m_input_reader_stack.Top());
1055 
1056         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
1057         {
1058             reader_sp->Deactivate();
1059             reader_sp->Cancel();
1060             m_input_reader_stack.Pop ();
1061 
1062             reader_sp = m_input_reader_stack.Top();
1063             if (reader_sp)
1064                 reader_sp->Activate();
1065 
1066             result = true;
1067         }
1068     }
1069     return result;
1070 }
1071 
1072 bool
1073 Debugger::HideTopIOHandler()
1074 {
1075     Mutex::Locker locker;
1076 
1077     if (locker.TryLock(m_input_reader_stack.GetMutex()))
1078     {
1079         IOHandlerSP reader_sp(m_input_reader_stack.Top());
1080         if (reader_sp)
1081             reader_sp->Hide();
1082         return true;
1083     }
1084     return false;
1085 }
1086 
1087 void
1088 Debugger::RefreshTopIOHandler()
1089 {
1090     IOHandlerSP reader_sp(m_input_reader_stack.Top());
1091     if (reader_sp)
1092         reader_sp->Refresh();
1093 }
1094 
1095 
1096 StreamSP
1097 Debugger::GetAsyncOutputStream ()
1098 {
1099     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1100                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
1101 }
1102 
1103 StreamSP
1104 Debugger::GetAsyncErrorStream ()
1105 {
1106     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1107                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
1108 }
1109 
1110 size_t
1111 Debugger::GetNumDebuggers()
1112 {
1113     if (g_shared_debugger_refcount > 0)
1114     {
1115         Mutex::Locker locker (GetDebuggerListMutex ());
1116         return GetDebuggerList().size();
1117     }
1118     return 0;
1119 }
1120 
1121 lldb::DebuggerSP
1122 Debugger::GetDebuggerAtIndex (size_t index)
1123 {
1124     DebuggerSP debugger_sp;
1125 
1126     if (g_shared_debugger_refcount > 0)
1127     {
1128         Mutex::Locker locker (GetDebuggerListMutex ());
1129         DebuggerList &debugger_list = GetDebuggerList();
1130 
1131         if (index < debugger_list.size())
1132             debugger_sp = debugger_list[index];
1133     }
1134 
1135     return debugger_sp;
1136 }
1137 
1138 DebuggerSP
1139 Debugger::FindDebuggerWithID (lldb::user_id_t id)
1140 {
1141     DebuggerSP debugger_sp;
1142 
1143     if (g_shared_debugger_refcount > 0)
1144     {
1145         Mutex::Locker locker (GetDebuggerListMutex ());
1146         DebuggerList &debugger_list = GetDebuggerList();
1147         DebuggerList::iterator pos, end = debugger_list.end();
1148         for (pos = debugger_list.begin(); pos != end; ++pos)
1149         {
1150             if ((*pos).get()->GetID() == id)
1151             {
1152                 debugger_sp = *pos;
1153                 break;
1154             }
1155         }
1156     }
1157     return debugger_sp;
1158 }
1159 
1160 #if 0
1161 static void
1162 TestPromptFormats (StackFrame *frame)
1163 {
1164     if (frame == NULL)
1165         return;
1166 
1167     StreamString s;
1168     const char *prompt_format =
1169     "{addr = '${addr}'\n}"
1170     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1171     "{current-pc-arrow = '${current-pc-arrow}'\n}"
1172     "{process.id = '${process.id}'\n}"
1173     "{process.name = '${process.name}'\n}"
1174     "{process.file.basename = '${process.file.basename}'\n}"
1175     "{process.file.fullpath = '${process.file.fullpath}'\n}"
1176     "{thread.id = '${thread.id}'\n}"
1177     "{thread.index = '${thread.index}'\n}"
1178     "{thread.name = '${thread.name}'\n}"
1179     "{thread.queue = '${thread.queue}'\n}"
1180     "{thread.stop-reason = '${thread.stop-reason}'\n}"
1181     "{target.arch = '${target.arch}'\n}"
1182     "{module.file.basename = '${module.file.basename}'\n}"
1183     "{module.file.fullpath = '${module.file.fullpath}'\n}"
1184     "{file.basename = '${file.basename}'\n}"
1185     "{file.fullpath = '${file.fullpath}'\n}"
1186     "{frame.index = '${frame.index}'\n}"
1187     "{frame.pc = '${frame.pc}'\n}"
1188     "{frame.sp = '${frame.sp}'\n}"
1189     "{frame.fp = '${frame.fp}'\n}"
1190     "{frame.flags = '${frame.flags}'\n}"
1191     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
1192     "{frame.reg.rip = '${frame.reg.rip}'\n}"
1193     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
1194     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
1195     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
1196     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
1197     "{frame.reg.carp = '${frame.reg.carp}'\n}"
1198     "{function.id = '${function.id}'\n}"
1199     "{function.changed = '${function.changed}'\n}"
1200     "{function.initial-function = '${function.initial-function}'\n}"
1201     "{function.name = '${function.name}'\n}"
1202     "{function.name-without-args = '${function.name-without-args}'\n}"
1203     "{function.name-with-args = '${function.name-with-args}'\n}"
1204     "{function.addr-offset = '${function.addr-offset}'\n}"
1205     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
1206     "{function.line-offset = '${function.line-offset}'\n}"
1207     "{function.pc-offset = '${function.pc-offset}'\n}"
1208     "{line.file.basename = '${line.file.basename}'\n}"
1209     "{line.file.fullpath = '${line.file.fullpath}'\n}"
1210     "{line.number = '${line.number}'\n}"
1211     "{line.start-addr = '${line.start-addr}'\n}"
1212     "{line.end-addr = '${line.end-addr}'\n}"
1213 ;
1214 
1215     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
1216     ExecutionContext exe_ctx;
1217     frame->CalculateExecutionContext(exe_ctx);
1218     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
1219     {
1220         printf("%s\n", s.GetData());
1221     }
1222     else
1223     {
1224         printf ("what we got: %s\n", s.GetData());
1225     }
1226 }
1227 #endif
1228 
1229 static bool
1230 ScanFormatDescriptor (const char* var_name_begin,
1231                       const char* var_name_end,
1232                       const char** var_name_final,
1233                       const char** percent_position,
1234                       Format* custom_format,
1235                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
1236 {
1237     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1238     *percent_position = ::strchr(var_name_begin,'%');
1239     if (!*percent_position || *percent_position > var_name_end)
1240     {
1241         if (log)
1242             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
1243         *var_name_final = var_name_end;
1244     }
1245     else
1246     {
1247         *var_name_final = *percent_position;
1248         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1249         if (log)
1250             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
1251         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
1252                                                   true,
1253                                                   *custom_format) )
1254         {
1255             if (log)
1256                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
1257 
1258             switch (format_name.front())
1259             {
1260                 case '@':             // if this is an @ sign, print ObjC description
1261                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
1262                     break;
1263                 case 'V': // if this is a V, print the value using the default format
1264                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1265                     break;
1266                 case 'L': // if this is an L, print the location of the value
1267                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
1268                     break;
1269                 case 'S': // if this is an S, print the summary after all
1270                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1271                     break;
1272                 case '#': // if this is a '#', print the number of children
1273                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
1274                     break;
1275                 case 'T': // if this is a 'T', print the type
1276                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
1277                     break;
1278                 case 'N': // if this is a 'N', print the name
1279                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
1280                     break;
1281                 case '>': // if this is a '>', print the name
1282                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
1283                     break;
1284                 default:
1285                     if (log)
1286                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
1287                     break;
1288             }
1289         }
1290         // a good custom format tells us to print the value using it
1291         else
1292         {
1293             if (log)
1294                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
1295             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1296         }
1297     }
1298     if (log)
1299         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1300                     *custom_format,
1301                     *val_obj_display);
1302     return true;
1303 }
1304 
1305 static bool
1306 ScanBracketedRange (const char* var_name_begin,
1307                     const char* var_name_end,
1308                     const char* var_name_final,
1309                     const char** open_bracket_position,
1310                     const char** separator_position,
1311                     const char** close_bracket_position,
1312                     const char** var_name_final_if_array_range,
1313                     int64_t* index_lower,
1314                     int64_t* index_higher)
1315 {
1316     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1317     *open_bracket_position = ::strchr(var_name_begin,'[');
1318     if (*open_bracket_position && *open_bracket_position < var_name_final)
1319     {
1320         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
1321         *close_bracket_position = ::strchr(*open_bracket_position,']');
1322         // as usual, we assume that [] will come before %
1323         //printf("trying to expand a []\n");
1324         *var_name_final_if_array_range = *open_bracket_position;
1325         if (*close_bracket_position - *open_bracket_position == 1)
1326         {
1327             if (log)
1328                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
1329             *index_lower = 0;
1330         }
1331         else if (*separator_position == NULL || *separator_position > var_name_end)
1332         {
1333             char *end = NULL;
1334             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1335             *index_higher = *index_lower;
1336             if (log)
1337                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
1338         }
1339         else if (*close_bracket_position && *close_bracket_position < var_name_end)
1340         {
1341             char *end = NULL;
1342             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1343             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1344             if (log)
1345                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
1346         }
1347         else
1348         {
1349             if (log)
1350                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
1351             return false;
1352         }
1353         if (*index_lower > *index_higher && *index_higher > 0)
1354         {
1355             if (log)
1356                 log->Printf("[ScanBracketedRange] swapping indices");
1357             int64_t temp = *index_lower;
1358             *index_lower = *index_higher;
1359             *index_higher = temp;
1360         }
1361     }
1362     else if (log)
1363             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
1364     return true;
1365 }
1366 
1367 template <typename T>
1368 static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
1369 {
1370     if (script_interpreter)
1371     {
1372         Error script_error;
1373         std::string script_output;
1374 
1375         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
1376         {
1377             s.Printf("%s", script_output.c_str());
1378             return true;
1379         }
1380         else
1381         {
1382             s.Printf("<error: %s>",script_error.AsCString());
1383         }
1384     }
1385     return false;
1386 }
1387 
1388 static ValueObjectSP
1389 ExpandIndexedExpression (ValueObject* valobj,
1390                          size_t index,
1391                          StackFrame* frame,
1392                          bool deref_pointer)
1393 {
1394     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1395     const char* ptr_deref_format = "[%d]";
1396     std::string ptr_deref_buffer(10,0);
1397     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1398     if (log)
1399         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1400     const char* first_unparsed;
1401     ValueObject::GetValueForExpressionPathOptions options;
1402     ValueObject::ExpressionPathEndResultType final_value_type;
1403     ValueObject::ExpressionPathScanEndReason reason_to_stop;
1404     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1405     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1406                                                           &first_unparsed,
1407                                                           &reason_to_stop,
1408                                                           &final_value_type,
1409                                                           options,
1410                                                           &what_next);
1411     if (!item)
1412     {
1413         if (log)
1414             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1415                " final_value_type %d",
1416                first_unparsed, reason_to_stop, final_value_type);
1417     }
1418     else
1419     {
1420         if (log)
1421             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1422                " final_value_type %d",
1423                first_unparsed, reason_to_stop, final_value_type);
1424     }
1425     return item;
1426 }
1427 
1428 static inline bool
1429 IsToken(const char *var_name_begin, const char *var)
1430 {
1431     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
1432 }
1433 
1434 static bool
1435 IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
1436     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
1437 {
1438     int var_len = strlen(var);
1439     if (::strncmp (var_name_begin, var, var_len) == 0)
1440     {
1441         var_name_begin += var_len;
1442         if (*var_name_begin == '}')
1443         {
1444             format = default_format;
1445             return true;
1446         }
1447         else if (*var_name_begin == '%')
1448         {
1449             // Allow format specifiers: x|X|u with optional width specifiers.
1450             //   ${thread.id%x}    ; hex
1451             //   ${thread.id%X}    ; uppercase hex
1452             //   ${thread.id%u}    ; unsigned decimal
1453             //   ${thread.id%8.8X} ; width.precision + specifier
1454             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
1455             int dot_count = 0;
1456             const char *specifier = NULL;
1457             int width_precision_length = 0;
1458             const char *width_precision = ++var_name_begin;
1459             while (isdigit(*var_name_begin) || *var_name_begin == '.')
1460             {
1461                 dot_count += (*var_name_begin == '.');
1462                 if (dot_count > 1)
1463                     break;
1464                 var_name_begin++;
1465                 width_precision_length++;
1466             }
1467 
1468             if (IsToken (var_name_begin, "tid}"))
1469             {
1470                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
1471                 if (target)
1472                 {
1473                     ArchSpec arch (target->GetArchitecture ());
1474                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
1475                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
1476                         specifier = PRIu64;
1477                 }
1478                 if (!specifier)
1479                 {
1480                     format = default_format;
1481                     return true;
1482                 }
1483             }
1484             else if (IsToken (var_name_begin, "x}"))
1485                 specifier = PRIx64;
1486             else if (IsToken (var_name_begin, "X}"))
1487                 specifier = PRIX64;
1488             else if (IsToken (var_name_begin, "u}"))
1489                 specifier = PRIu64;
1490 
1491             if (specifier)
1492             {
1493                 format = "%";
1494                 if (width_precision_length)
1495                     format += std::string(width_precision, width_precision_length);
1496                 format += specifier;
1497                 return true;
1498             }
1499         }
1500     }
1501     return false;
1502 }
1503 
1504 // Find information for the "thread.info.*" specifiers in a format string
1505 static bool
1506 FormatThreadExtendedInfoRecurse
1507 (
1508     const char *var_name_begin,
1509     StructuredData::ObjectSP thread_info_dictionary,
1510     const SymbolContext *sc,
1511     const ExecutionContext *exe_ctx,
1512     Stream &s
1513 )
1514 {
1515     bool var_success = false;
1516     std::string token_format;
1517 
1518     llvm::StringRef var_name(var_name_begin);
1519     size_t percent_idx = var_name.find('%');
1520     size_t close_curly_idx = var_name.find('}');
1521     llvm::StringRef path = var_name;
1522     llvm::StringRef formatter = var_name;
1523 
1524     // 'path' will be the dot separated list of objects to transverse up until we hit
1525     // a close curly brace, a percent sign, or an end of string.
1526     if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
1527     {
1528         if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
1529         {
1530             if (percent_idx < close_curly_idx)
1531             {
1532                 path = var_name.slice(0, percent_idx);
1533                 formatter = var_name.substr (percent_idx);
1534             }
1535             else
1536             {
1537                 path = var_name.slice(0, close_curly_idx);
1538                 formatter = var_name.substr (close_curly_idx);
1539             }
1540         }
1541         else if (percent_idx != llvm::StringRef::npos)
1542         {
1543             path = var_name.slice(0, percent_idx);
1544             formatter = var_name.substr (percent_idx);
1545         }
1546         else if (close_curly_idx != llvm::StringRef::npos)
1547         {
1548             path = var_name.slice(0, close_curly_idx);
1549             formatter = var_name.substr (close_curly_idx);
1550         }
1551     }
1552 
1553     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1554 
1555     if (value.get())
1556     {
1557         if (value->GetType() == StructuredData::Type::eTypeInteger)
1558         {
1559             if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1560             {
1561                 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
1562                 var_success = true;
1563             }
1564         }
1565         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1566         {
1567             s.Printf ("%f", value->GetAsFloat()->GetValue());
1568             var_success = true;
1569         }
1570         else if (value->GetType() == StructuredData::Type::eTypeString)
1571         {
1572             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1573             var_success = true;
1574         }
1575         else if (value->GetType() == StructuredData::Type::eTypeArray)
1576         {
1577             if (value->GetAsArray()->GetSize() > 0)
1578             {
1579                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1580                 var_success = true;
1581             }
1582         }
1583         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1584         {
1585             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1586             var_success = true;
1587         }
1588     }
1589 
1590     return var_success;
1591 }
1592 
1593 
1594 static bool
1595 FormatPromptRecurse
1596 (
1597     const char *format,
1598     const SymbolContext *sc,
1599     const ExecutionContext *exe_ctx,
1600     const Address *addr,
1601     Stream &s,
1602     const char **end,
1603     ValueObject* valobj,
1604     bool function_changed,
1605     bool initial_function
1606 )
1607 {
1608     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
1609     bool success = true;
1610     const char *p;
1611     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1612 
1613     for (p = format; *p != '\0'; ++p)
1614     {
1615         if (realvalobj)
1616         {
1617             valobj = realvalobj;
1618             realvalobj = NULL;
1619         }
1620         size_t non_special_chars = ::strcspn (p, "${}\\");
1621         if (non_special_chars > 0)
1622         {
1623             if (success)
1624                 s.Write (p, non_special_chars);
1625             p += non_special_chars;
1626         }
1627 
1628         if (*p == '\0')
1629         {
1630             break;
1631         }
1632         else if (*p == '{')
1633         {
1634             // Start a new scope that must have everything it needs if it is to
1635             // to make it into the final output stream "s". If you want to make
1636             // a format that only prints out the function or symbol name if there
1637             // is one in the symbol context you can use:
1638             //      "{function =${function.name}}"
1639             // The first '{' starts a new scope that end with the matching '}' at
1640             // the end of the string. The contents "function =${function.name}"
1641             // will then be evaluated and only be output if there is a function
1642             // or symbol with a valid name.
1643             StreamString sub_strm;
1644 
1645             ++p;  // Skip the '{'
1646 
1647             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function))
1648             {
1649                 // The stream had all it needed
1650                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
1651             }
1652             if (*p != '}')
1653             {
1654                 success = false;
1655                 break;
1656             }
1657         }
1658         else if (*p == '}')
1659         {
1660             // End of a enclosing scope
1661             break;
1662         }
1663         else if (*p == '$')
1664         {
1665             // We have a prompt variable to print
1666             ++p;
1667             if (*p == '{')
1668             {
1669                 ++p;
1670                 const char *var_name_begin = p;
1671                 const char *var_name_end = ::strchr (p, '}');
1672 
1673                 if (var_name_end && var_name_begin < var_name_end)
1674                 {
1675                     // if we have already failed to parse, skip this variable
1676                     if (success)
1677                     {
1678                         const char *cstr = NULL;
1679                         std::string token_format;
1680                         Address format_addr;
1681 
1682                         // normally "addr" means print a raw address but
1683                         // "file-addr-or-load-addr" means print a module + file addr if there's no load addr
1684                         bool print_file_addr_or_load_addr = false;
1685                         bool addr_offset_concrete_func_only = false;
1686                         bool addr_offset_print_with_no_padding = false;
1687                         bool calculate_format_addr_function_offset = false;
1688                         // Set reg_kind and reg_num to invalid values
1689                         RegisterKind reg_kind = kNumRegisterKinds;
1690                         uint32_t reg_num = LLDB_INVALID_REGNUM;
1691                         FileSpec format_file_spec;
1692                         const RegisterInfo *reg_info = NULL;
1693                         RegisterContext *reg_ctx = NULL;
1694                         bool do_deref_pointer = false;
1695                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
1696                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
1697 
1698                         // Each variable must set success to true below...
1699                         bool var_success = false;
1700                         switch (var_name_begin[0])
1701                         {
1702                         case '*':
1703                         case 'v':
1704                         case 's':
1705                             {
1706                                 if (!valobj)
1707                                     break;
1708 
1709                                 if (log)
1710                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1711 
1712                                 // check for *var and *svar
1713                                 if (*var_name_begin == '*')
1714                                 {
1715                                     do_deref_pointer = true;
1716                                     var_name_begin++;
1717                                     if (log)
1718                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
1719                                 }
1720 
1721                                 if (*var_name_begin == 's')
1722                                 {
1723                                     if (!valobj->IsSynthetic())
1724                                         valobj = valobj->GetSyntheticValue().get();
1725                                     if (!valobj)
1726                                         break;
1727                                     var_name_begin++;
1728                                     if (log)
1729                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
1730                                 }
1731 
1732                                 // should be a 'v' by now
1733                                 if (*var_name_begin != 'v')
1734                                     break;
1735 
1736                                 if (log)
1737                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1738 
1739                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
1740                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1741                                 ValueObject::GetValueForExpressionPathOptions options;
1742                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
1743                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1744                                 ValueObject* target = NULL;
1745                                 Format custom_format = eFormatInvalid;
1746                                 const char* var_name_final = NULL;
1747                                 const char* var_name_final_if_array_range = NULL;
1748                                 const char* close_bracket_position = NULL;
1749                                 int64_t index_lower = -1;
1750                                 int64_t index_higher = -1;
1751                                 bool is_array_range = false;
1752                                 const char* first_unparsed;
1753                                 bool was_plain_var = false;
1754                                 bool was_var_format = false;
1755                                 bool was_var_indexed = false;
1756 
1757                                 if (!valobj) break;
1758                                 // simplest case ${var}, just print valobj's value
1759                                 if (IsToken (var_name_begin, "var}"))
1760                                 {
1761                                     was_plain_var = true;
1762                                     target = valobj;
1763                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1764                                 }
1765                                 else if (IsToken (var_name_begin, "var.script:"))
1766                                 {
1767                                     var_name_begin += ::strlen("var.script:");
1768                                     std::string script_name(var_name_begin,var_name_end);
1769                                     ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1770                                     if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name))
1771                                         var_success = true;
1772                                     break;
1773                                 }
1774                                 else if (IsToken (var_name_begin,"var%"))
1775                                 {
1776                                     was_var_format = true;
1777                                     // this is a variable with some custom format applied to it
1778                                     const char* percent_position;
1779                                     target = valobj;
1780                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1781                                     ScanFormatDescriptor (var_name_begin,
1782                                                           var_name_end,
1783                                                           &var_name_final,
1784                                                           &percent_position,
1785                                                           &custom_format,
1786                                                           &val_obj_display);
1787                                 }
1788                                     // this is ${var.something} or multiple .something nested
1789                                 else if (IsToken (var_name_begin, "var"))
1790                                 {
1791                                     if (IsToken (var_name_begin, "var["))
1792                                         was_var_indexed = true;
1793                                     const char* percent_position;
1794                                     ScanFormatDescriptor (var_name_begin,
1795                                                           var_name_end,
1796                                                           &var_name_final,
1797                                                           &percent_position,
1798                                                           &custom_format,
1799                                                           &val_obj_display);
1800 
1801                                     const char* open_bracket_position;
1802                                     const char* separator_position;
1803                                     ScanBracketedRange (var_name_begin,
1804                                                         var_name_end,
1805                                                         var_name_final,
1806                                                         &open_bracket_position,
1807                                                         &separator_position,
1808                                                         &close_bracket_position,
1809                                                         &var_name_final_if_array_range,
1810                                                         &index_lower,
1811                                                         &index_higher);
1812 
1813                                     Error error;
1814 
1815                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1816                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1817 
1818                                     if (log)
1819                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1820 
1821                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1822                                                                              &first_unparsed,
1823                                                                              &reason_to_stop,
1824                                                                              &final_value_type,
1825                                                                              options,
1826                                                                              &what_next).get();
1827 
1828                                     if (!target)
1829                                     {
1830                                         if (log)
1831                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1832                                                " final_value_type %d",
1833                                                first_unparsed, reason_to_stop, final_value_type);
1834                                         break;
1835                                     }
1836                                     else
1837                                     {
1838                                         if (log)
1839                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1840                                                " final_value_type %d",
1841                                                first_unparsed, reason_to_stop, final_value_type);
1842                                         target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
1843                                     }
1844                                 }
1845                                 else
1846                                     break;
1847 
1848                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
1849                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1850 
1851                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1852 
1853                                 if (do_deref_pointer && !is_array_range)
1854                                 {
1855                                     // I have not deref-ed yet, let's do it
1856                                     // this happens when we are not going through GetValueForVariableExpressionPath
1857                                     // to get to the target ValueObject
1858                                     Error error;
1859                                     target = target->Dereference(error).get();
1860                                     if (error.Fail())
1861                                     {
1862                                         if (log)
1863                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1864                                         break;
1865                                     }
1866                                     do_deref_pointer = false;
1867                                 }
1868 
1869                                 if (!target)
1870                                 {
1871                                     if (log)
1872                                         log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
1873                                     break;
1874                                 }
1875 
1876                                 // we do not want to use the summary for a bitfield of type T:n
1877                                 // if we were originally dealing with just a T - that would get
1878                                 // us into an endless recursion
1879                                 if (target->IsBitfield() && was_var_indexed)
1880                                 {
1881                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1882                                     StreamString bitfield_name;
1883                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1884                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1885                                     if (!DataVisualization::GetSummaryForType(type_sp))
1886                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1887                                 }
1888 
1889                                 // TODO use flags for these
1890                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
1891                                 bool is_array = (type_info_flags & eTypeIsArray) != 0;
1892                                 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
1893                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1894 
1895                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1896                                 {
1897                                     StreamString str_temp;
1898                                     if (log)
1899                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1900 
1901                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1902                                     {
1903                                         // try to use the special cases
1904                                         var_success = target->DumpPrintableRepresentation(str_temp,
1905                                                                                           val_obj_display,
1906                                                                                           custom_format);
1907                                         if (log)
1908                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1909 
1910                                         // should not happen
1911                                         if (var_success)
1912                                             s << str_temp.GetData();
1913                                         var_success = true;
1914                                         break;
1915                                     }
1916                                     else
1917                                     {
1918                                         if (was_plain_var) // if ${var}
1919                                         {
1920                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1921                                         }
1922                                         else if (is_pointer) // if pointer, value is the address stored
1923                                         {
1924                                             target->DumpPrintableRepresentation (s,
1925                                                                                  val_obj_display,
1926                                                                                  custom_format,
1927                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
1928                                         }
1929                                         var_success = true;
1930                                         break;
1931                                     }
1932                                 }
1933 
1934                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1935                                 // type @ location message
1936                                 if (is_aggregate && was_plain_var)
1937                                 {
1938                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1939                                     var_success = true;
1940                                     break;
1941                                 }
1942 
1943                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
1944                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
1945                                 {
1946                                     s << "<invalid use of aggregate type>";
1947                                     var_success = true;
1948                                     break;
1949                                 }
1950 
1951                                 if (!is_array_range)
1952                                 {
1953                                     if (log)
1954                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
1955                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1956                                 }
1957                                 else
1958                                 {
1959                                     if (log)
1960                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
1961                                     if (!is_array && !is_pointer)
1962                                         break;
1963                                     if (log)
1964                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1965                                     const char* special_directions = NULL;
1966                                     StreamString special_directions_writer;
1967                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1968                                     {
1969                                         ConstString additional_data;
1970                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1971                                         special_directions_writer.Printf("${%svar%s}",
1972                                                                          do_deref_pointer ? "*" : "",
1973                                                                          additional_data.GetCString());
1974                                         special_directions = special_directions_writer.GetData();
1975                                     }
1976 
1977                                     // let us display items index_lower thru index_higher of this array
1978                                     s.PutChar('[');
1979                                     var_success = true;
1980 
1981                                     if (index_higher < 0)
1982                                         index_higher = valobj->GetNumChildren() - 1;
1983 
1984                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1985 
1986                                     for (;index_lower<=index_higher;index_lower++)
1987                                     {
1988                                         ValueObject* item = ExpandIndexedExpression (target,
1989                                                                                      index_lower,
1990                                                                                      exe_ctx->GetFramePtr(),
1991                                                                                      false).get();
1992 
1993                                         if (!item)
1994                                         {
1995                                             if (log)
1996                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1997                                         }
1998                                         else
1999                                         {
2000                                             if (log)
2001                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
2002                                         }
2003 
2004                                         if (!special_directions)
2005                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
2006                                         else
2007                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function);
2008 
2009                                         if (--max_num_children == 0)
2010                                         {
2011                                             s.PutCString(", ...");
2012                                             break;
2013                                         }
2014 
2015                                         if (index_lower < index_higher)
2016                                             s.PutChar(',');
2017                                     }
2018                                     s.PutChar(']');
2019                                 }
2020                             }
2021                             break;
2022                         case 'a':
2023                             if (IsToken (var_name_begin, "addr-file-or-load}"))
2024                             {
2025                                 print_file_addr_or_load_addr = true;
2026                             }
2027                             if (IsToken (var_name_begin, "addr}")
2028                                 || IsToken (var_name_begin, "addr-file-or-load}"))
2029                             {
2030                                 if (addr && addr->IsValid())
2031                                 {
2032                                     var_success = true;
2033                                     format_addr = *addr;
2034                                 }
2035                             }
2036                             break;
2037 
2038                         case 'p':
2039                             if (IsToken (var_name_begin, "process."))
2040                             {
2041                                 if (exe_ctx)
2042                                 {
2043                                     Process *process = exe_ctx->GetProcessPtr();
2044                                     if (process)
2045                                     {
2046                                         var_name_begin += ::strlen ("process.");
2047                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
2048                                         {
2049                                             s.Printf(token_format.c_str(), process->GetID());
2050                                             var_success = true;
2051                                         }
2052                                         else if ((IsToken (var_name_begin, "name}")) ||
2053                                                 (IsToken (var_name_begin, "file.basename}")) ||
2054                                                 (IsToken (var_name_begin, "file.fullpath}")))
2055                                         {
2056                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
2057                                             if (exe_module)
2058                                             {
2059                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
2060                                                 {
2061                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
2062                                                     var_success = (bool)format_file_spec;
2063                                                 }
2064                                                 else
2065                                                 {
2066                                                     format_file_spec = exe_module->GetFileSpec();
2067                                                     var_success = (bool)format_file_spec;
2068                                                 }
2069                                             }
2070                                         }
2071                                         else if (IsToken (var_name_begin, "script:"))
2072                                         {
2073                                             var_name_begin += ::strlen("script:");
2074                                             std::string script_name(var_name_begin,var_name_end);
2075                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2076                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
2077                                                 var_success = true;
2078                                         }
2079                                     }
2080                                 }
2081                             }
2082                             break;
2083 
2084                         case 't':
2085                            if (IsToken (var_name_begin, "thread."))
2086                             {
2087                                 if (exe_ctx)
2088                                 {
2089                                     Thread *thread = exe_ctx->GetThreadPtr();
2090                                     if (thread)
2091                                     {
2092                                         var_name_begin += ::strlen ("thread.");
2093                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2094                                         {
2095                                             s.Printf(token_format.c_str(), thread->GetID());
2096                                             var_success = true;
2097                                         }
2098                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2099                                         {
2100                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
2101                                             var_success = true;
2102                                         }
2103                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
2104                                         {
2105                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
2106                                             var_success = true;
2107                                         }
2108                                         else if (IsToken (var_name_begin, "name}"))
2109                                         {
2110                                             cstr = thread->GetName();
2111                                             var_success = cstr && cstr[0];
2112                                             if (var_success)
2113                                                 s.PutCString(cstr);
2114                                         }
2115                                         else if (IsToken (var_name_begin, "queue}"))
2116                                         {
2117                                             cstr = thread->GetQueueName();
2118                                             var_success = cstr && cstr[0];
2119                                             if (var_success)
2120                                                 s.PutCString(cstr);
2121                                         }
2122                                         else if (IsToken (var_name_begin, "stop-reason}"))
2123                                         {
2124                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2125                                             if (stop_info_sp && stop_info_sp->IsValid())
2126                                             {
2127                                                 cstr = stop_info_sp->GetDescription();
2128                                                 if (cstr && cstr[0])
2129                                                 {
2130                                                     s.PutCString(cstr);
2131                                                     var_success = true;
2132                                                 }
2133                                             }
2134                                         }
2135                                         else if (IsToken (var_name_begin, "return-value}"))
2136                                         {
2137                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2138                                             if (stop_info_sp && stop_info_sp->IsValid())
2139                                             {
2140                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
2141                                                 if (return_valobj_sp)
2142                                                 {
2143                                                     return_valobj_sp->Dump(s);
2144                                                     var_success = true;
2145                                                 }
2146                                             }
2147                                         }
2148                                         else if (IsToken (var_name_begin, "completed-expression}"))
2149                                         {
2150                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2151                                             if (stop_info_sp && stop_info_sp->IsValid())
2152                                             {
2153                                                 ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
2154                                                 if (expression_var_sp && expression_var_sp->GetValueObject())
2155                                                 {
2156                                                     expression_var_sp->GetValueObject()->Dump(s);
2157                                                     var_success = true;
2158                                                 }
2159                                             }
2160                                         }
2161                                         else if (IsToken (var_name_begin, "script:"))
2162                                         {
2163                                             var_name_begin += ::strlen("script:");
2164                                             std::string script_name(var_name_begin,var_name_end);
2165                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2166                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2167                                                 var_success = true;
2168                                         }
2169                                         else if (IsToken (var_name_begin, "info."))
2170                                         {
2171                                             var_name_begin += ::strlen("info.");
2172                                             StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
2173                                             if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
2174                                             {
2175                                                 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
2176                                             }
2177                                         }
2178                                     }
2179                                 }
2180                             }
2181                             else if (IsToken (var_name_begin, "target."))
2182                             {
2183                                 // TODO: hookup properties
2184 //                                if (!target_properties_sp)
2185 //                                {
2186 //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2187 //                                    if (target)
2188 //                                        target_properties_sp = target->GetProperties();
2189 //                                }
2190 //
2191 //                                if (target_properties_sp)
2192 //                                {
2193 //                                    var_name_begin += ::strlen ("target.");
2194 //                                    const char *end_property = strchr(var_name_begin, '}');
2195 //                                    if (end_property)
2196 //                                    {
2197 //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
2198 //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
2199 //                                        if (!property_value.empty())
2200 //                                        {
2201 //                                            s.PutCString (property_value.c_str());
2202 //                                            var_success = true;
2203 //                                        }
2204 //                                    }
2205 //                                }
2206                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2207                                 if (target)
2208                                 {
2209                                     var_name_begin += ::strlen ("target.");
2210                                     if (IsToken (var_name_begin, "arch}"))
2211                                     {
2212                                         ArchSpec arch (target->GetArchitecture ());
2213                                         if (arch.IsValid())
2214                                         {
2215                                             s.PutCString (arch.GetArchitectureName());
2216                                             var_success = true;
2217                                         }
2218                                     }
2219                                     else if (IsToken (var_name_begin, "script:"))
2220                                     {
2221                                         var_name_begin += ::strlen("script:");
2222                                         std::string script_name(var_name_begin,var_name_end);
2223                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2224                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2225                                             var_success = true;
2226                                     }
2227                                 }
2228                             }
2229                             break;
2230 
2231                         case 'm':
2232                            if (IsToken (var_name_begin, "module."))
2233                             {
2234                                 if (sc && sc->module_sp.get())
2235                                 {
2236                                     Module *module = sc->module_sp.get();
2237                                     var_name_begin += ::strlen ("module.");
2238 
2239                                     if (IsToken (var_name_begin, "file."))
2240                                     {
2241                                         if (module->GetFileSpec())
2242                                         {
2243                                             var_name_begin += ::strlen ("file.");
2244 
2245                                             if (IsToken (var_name_begin, "basename}"))
2246                                             {
2247                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
2248                                                 var_success = (bool)format_file_spec;
2249                                             }
2250                                             else if (IsToken (var_name_begin, "fullpath}"))
2251                                             {
2252                                                 format_file_spec = module->GetFileSpec();
2253                                                 var_success = (bool)format_file_spec;
2254                                             }
2255                                         }
2256                                     }
2257                                 }
2258                             }
2259                             break;
2260 
2261 
2262                         case 'f':
2263                            if (IsToken (var_name_begin, "file."))
2264                             {
2265                                 if (sc && sc->comp_unit != NULL)
2266                                 {
2267                                     var_name_begin += ::strlen ("file.");
2268 
2269                                     if (IsToken (var_name_begin, "basename}"))
2270                                     {
2271                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
2272                                         var_success = (bool)format_file_spec;
2273                                     }
2274                                     else if (IsToken (var_name_begin, "fullpath}"))
2275                                     {
2276                                         format_file_spec = *sc->comp_unit;
2277                                         var_success = (bool)format_file_spec;
2278                                     }
2279                                 }
2280                             }
2281                            else if (IsToken (var_name_begin, "frame."))
2282                             {
2283                                 if (exe_ctx)
2284                                 {
2285                                     StackFrame *frame = exe_ctx->GetFramePtr();
2286                                     if (frame)
2287                                     {
2288                                         var_name_begin += ::strlen ("frame.");
2289                                         if (IsToken (var_name_begin, "index}"))
2290                                         {
2291                                             s.Printf("%u", frame->GetFrameIndex());
2292                                             var_success = true;
2293                                         }
2294                                         else if (IsToken (var_name_begin, "pc}"))
2295                                         {
2296                                             reg_kind = eRegisterKindGeneric;
2297                                             reg_num = LLDB_REGNUM_GENERIC_PC;
2298                                             var_success = true;
2299                                         }
2300                                         else if (IsToken (var_name_begin, "sp}"))
2301                                         {
2302                                             reg_kind = eRegisterKindGeneric;
2303                                             reg_num = LLDB_REGNUM_GENERIC_SP;
2304                                             var_success = true;
2305                                         }
2306                                         else if (IsToken (var_name_begin, "fp}"))
2307                                         {
2308                                             reg_kind = eRegisterKindGeneric;
2309                                             reg_num = LLDB_REGNUM_GENERIC_FP;
2310                                             var_success = true;
2311                                         }
2312                                         else if (IsToken (var_name_begin, "flags}"))
2313                                         {
2314                                             reg_kind = eRegisterKindGeneric;
2315                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
2316                                             var_success = true;
2317                                         }
2318                                         else if (IsToken (var_name_begin, "reg."))
2319                                         {
2320                                             reg_ctx = frame->GetRegisterContext().get();
2321                                             if (reg_ctx)
2322                                             {
2323                                                 var_name_begin += ::strlen ("reg.");
2324                                                 if (var_name_begin < var_name_end)
2325                                                 {
2326                                                     std::string reg_name (var_name_begin, var_name_end);
2327                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
2328                                                     if (reg_info)
2329                                                         var_success = true;
2330                                                 }
2331                                             }
2332                                         }
2333                                         else if (IsToken (var_name_begin, "script:"))
2334                                         {
2335                                             var_name_begin += ::strlen("script:");
2336                                             std::string script_name(var_name_begin,var_name_end);
2337                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2338                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2339                                                 var_success = true;
2340                                         }
2341                                     }
2342                                 }
2343                             }
2344                             else if (IsToken (var_name_begin, "function."))
2345                             {
2346                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
2347                                 {
2348                                     var_name_begin += ::strlen ("function.");
2349                                     if (IsToken (var_name_begin, "id}"))
2350                                     {
2351                                         if (sc->function)
2352                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
2353                                         else
2354                                             s.Printf("symbol[%u]", sc->symbol->GetID());
2355 
2356                                         var_success = true;
2357                                     }
2358                                     if (IsToken (var_name_begin, "changed}") && function_changed)
2359                                     {
2360                                         var_success = true;
2361                                     }
2362                                     if (IsToken (var_name_begin, "initial-function}") && initial_function)
2363                                     {
2364                                         var_success = true;
2365                                     }
2366                                     else if (IsToken (var_name_begin, "name}"))
2367                                     {
2368                                         if (sc->function)
2369                                             cstr = sc->function->GetName().AsCString (NULL);
2370                                         else if (sc->symbol)
2371                                             cstr = sc->symbol->GetName().AsCString (NULL);
2372                                         if (cstr)
2373                                         {
2374                                             s.PutCString(cstr);
2375 
2376                                             if (sc->block)
2377                                             {
2378                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2379                                                 if (inline_block)
2380                                                 {
2381                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
2382                                                     if (inline_info)
2383                                                     {
2384                                                         s.PutCString(" [inlined] ");
2385                                                         inline_info->GetName().Dump(&s);
2386                                                     }
2387                                                 }
2388                                             }
2389                                             var_success = true;
2390                                         }
2391                                     }
2392                                     else if (IsToken (var_name_begin, "name-without-args}"))
2393                                     {
2394                                         ConstString name;
2395                                         if (sc->function)
2396                                             name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2397                                         else if (sc->symbol)
2398                                             name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2399                                         if (name)
2400                                         {
2401                                             s.PutCString(name.GetCString());
2402                                             var_success = true;
2403                                         }
2404                                     }
2405                                     else if (IsToken (var_name_begin, "name-with-args}"))
2406                                     {
2407                                         // Print the function name with arguments in it
2408 
2409                                         if (sc->function)
2410                                         {
2411                                             var_success = true;
2412                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
2413                                             cstr = sc->function->GetName().AsCString (NULL);
2414                                             if (cstr)
2415                                             {
2416                                                 const InlineFunctionInfo *inline_info = NULL;
2417                                                 VariableListSP variable_list_sp;
2418                                                 bool get_function_vars = true;
2419                                                 if (sc->block)
2420                                                 {
2421                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
2422 
2423                                                     if (inline_block)
2424                                                     {
2425                                                         get_function_vars = false;
2426                                                         inline_info = sc->block->GetInlinedFunctionInfo();
2427                                                         if (inline_info)
2428                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
2429                                                     }
2430                                                 }
2431 
2432                                                 if (get_function_vars)
2433                                                 {
2434                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
2435                                                 }
2436 
2437                                                 if (inline_info)
2438                                                 {
2439                                                     s.PutCString (cstr);
2440                                                     s.PutCString (" [inlined] ");
2441                                                     cstr = inline_info->GetName().GetCString();
2442                                                 }
2443 
2444                                                 VariableList args;
2445                                                 if (variable_list_sp)
2446                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
2447                                                 if (args.GetSize() > 0)
2448                                                 {
2449                                                     const char *open_paren = strchr (cstr, '(');
2450                                                     const char *close_paren = nullptr;
2451                                                     const char *generic = strchr(cstr, '<');
2452                                                     // if before the arguments list begins there is a template sign
2453                                                     // then scan to the end of the generic args before you try to find
2454                                                     // the arguments list
2455                                                     if (generic && open_paren && generic < open_paren)
2456                                                     {
2457                                                         int generic_depth = 1;
2458                                                         ++generic;
2459                                                         for (;
2460                                                              *generic && generic_depth > 0;
2461                                                              generic++)
2462                                                         {
2463                                                             if (*generic == '<')
2464                                                                 generic_depth++;
2465                                                             if (*generic == '>')
2466                                                                 generic_depth--;
2467                                                         }
2468                                                         if (*generic)
2469                                                             open_paren = strchr(generic, '(');
2470                                                         else
2471                                                             open_paren = nullptr;
2472                                                     }
2473                                                     if (open_paren)
2474                                                     {
2475                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2476                                                         {
2477                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2478                                                             if (open_paren)
2479                                                                 close_paren = strchr (open_paren, ')');
2480                                                         }
2481                                                         else
2482                                                             close_paren = strchr (open_paren, ')');
2483                                                     }
2484 
2485                                                     if (open_paren)
2486                                                         s.Write(cstr, open_paren - cstr + 1);
2487                                                     else
2488                                                     {
2489                                                         s.PutCString (cstr);
2490                                                         s.PutChar ('(');
2491                                                     }
2492                                                     const size_t num_args = args.GetSize();
2493                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
2494                                                     {
2495                                                         std::string buffer;
2496 
2497                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
2498                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2499                                                         const char *var_representation = nullptr;
2500                                                         const char *var_name = var_value_sp->GetName().GetCString();
2501                                                         if (var_value_sp->GetClangType().IsAggregateType() &&
2502                                                             DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
2503                                                         {
2504                                                             static StringSummaryFormat format(TypeSummaryImpl::Flags()
2505                                                                                               .SetHideItemNames(false)
2506                                                                                               .SetShowMembersOneLiner(true),
2507                                                                                               "");
2508                                                             format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
2509                                                             var_representation = buffer.c_str();
2510                                                         }
2511                                                         else
2512                                                             var_representation = var_value_sp->GetValueAsCString();
2513                                                         if (arg_idx > 0)
2514                                                             s.PutCString (", ");
2515                                                         if (var_value_sp->GetError().Success())
2516                                                         {
2517                                                             if (var_representation)
2518                                                                 s.Printf ("%s=%s", var_name, var_representation);
2519                                                             else
2520                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2521                                                         }
2522                                                         else
2523                                                             s.Printf ("%s=<unavailable>", var_name);
2524                                                     }
2525 
2526                                                     if (close_paren)
2527                                                         s.PutCString (close_paren);
2528                                                     else
2529                                                         s.PutChar(')');
2530 
2531                                                 }
2532                                                 else
2533                                                 {
2534                                                     s.PutCString(cstr);
2535                                                 }
2536                                             }
2537                                         }
2538                                         else if (sc->symbol)
2539                                         {
2540                                             cstr = sc->symbol->GetName().AsCString (NULL);
2541                                             if (cstr)
2542                                             {
2543                                                 s.PutCString(cstr);
2544                                                 var_success = true;
2545                                             }
2546                                         }
2547                                     }
2548                                     else if (IsToken (var_name_begin, "addr-offset}")
2549                                             || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
2550                                     {
2551                                         if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
2552                                         {
2553                                             addr_offset_print_with_no_padding = true;
2554                                             addr_offset_concrete_func_only = true;
2555                                         }
2556                                         var_success = addr != NULL;
2557                                         if (var_success)
2558                                         {
2559                                             format_addr = *addr;
2560                                             calculate_format_addr_function_offset = true;
2561                                         }
2562                                     }
2563                                     else if (IsToken (var_name_begin, "line-offset}"))
2564                                     {
2565                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
2566                                         if (var_success)
2567                                         {
2568                                             format_addr = sc->line_entry.range.GetBaseAddress();
2569                                             calculate_format_addr_function_offset = true;
2570                                         }
2571                                     }
2572                                     else if (IsToken (var_name_begin, "pc-offset}"))
2573                                     {
2574                                         StackFrame *frame = exe_ctx->GetFramePtr();
2575                                         var_success = frame != NULL;
2576                                         if (var_success)
2577                                         {
2578                                             format_addr = frame->GetFrameCodeAddress();
2579                                             calculate_format_addr_function_offset = true;
2580                                         }
2581                                     }
2582                                 }
2583                             }
2584                             break;
2585 
2586                         case 'l':
2587                             if (IsToken (var_name_begin, "line."))
2588                             {
2589                                 if (sc && sc->line_entry.IsValid())
2590                                 {
2591                                     var_name_begin += ::strlen ("line.");
2592                                     if (IsToken (var_name_begin, "file."))
2593                                     {
2594                                         var_name_begin += ::strlen ("file.");
2595 
2596                                         if (IsToken (var_name_begin, "basename}"))
2597                                         {
2598                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
2599                                             var_success = (bool)format_file_spec;
2600                                         }
2601                                         else if (IsToken (var_name_begin, "fullpath}"))
2602                                         {
2603                                             format_file_spec = sc->line_entry.file;
2604                                             var_success = (bool)format_file_spec;
2605                                         }
2606                                     }
2607                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
2608                                     {
2609                                         var_success = true;
2610                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
2611                                     }
2612                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
2613                                              (IsToken (var_name_begin, "end-addr}")))
2614                                     {
2615                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
2616                                         if (var_success)
2617                                         {
2618                                             format_addr = sc->line_entry.range.GetBaseAddress();
2619                                             if (var_name_begin[0] == 'e')
2620                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
2621                                         }
2622                                     }
2623                                 }
2624                             }
2625                             break;
2626                         case 'c':
2627                             if (IsToken (var_name_begin, "current-pc-arrow"))
2628                             {
2629                                 if (addr && exe_ctx && exe_ctx->GetFramePtr())
2630                                 {
2631                                     RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
2632                                     if (reg_ctx.get())
2633                                     {
2634                                         addr_t pc_loadaddr = reg_ctx->GetPC();
2635                                         if (pc_loadaddr != LLDB_INVALID_ADDRESS)
2636                                         {
2637                                             Address pc;
2638                                             pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
2639                                             if (pc == *addr)
2640                                             {
2641                                                 s.Printf ("-> ");
2642                                                 var_success = true;
2643                                             }
2644                                         }
2645                                     }
2646                                     if (var_success == false)
2647                                     {
2648                                         s.Printf("   ");
2649                                         var_success = true;
2650                                     }
2651                                 }
2652                                 var_success = true;
2653                             }
2654                             break;
2655                         }
2656 
2657                         if (var_success)
2658                         {
2659                             // If format addr is valid, then we need to print an address
2660                             if (reg_num != LLDB_INVALID_REGNUM)
2661                             {
2662                                 StackFrame *frame = exe_ctx->GetFramePtr();
2663                                 // We have a register value to display...
2664                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
2665                                 {
2666                                     format_addr = frame->GetFrameCodeAddress();
2667                                 }
2668                                 else
2669                                 {
2670                                     if (reg_ctx == NULL)
2671                                         reg_ctx = frame->GetRegisterContext().get();
2672 
2673                                     if (reg_ctx)
2674                                     {
2675                                         if (reg_kind != kNumRegisterKinds)
2676                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
2677                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
2678                                         var_success = reg_info != NULL;
2679                                     }
2680                                 }
2681                             }
2682 
2683                             if (reg_info != NULL)
2684                             {
2685                                 RegisterValue reg_value;
2686                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
2687                                 if (var_success)
2688                                 {
2689                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
2690                                 }
2691                             }
2692 
2693                             if (format_file_spec)
2694                             {
2695                                 s << format_file_spec;
2696                             }
2697 
2698                             // If format addr is valid, then we need to print an address
2699                             if (format_addr.IsValid())
2700                             {
2701                                 var_success = false;
2702 
2703                                 if (calculate_format_addr_function_offset)
2704                                 {
2705                                     Address func_addr;
2706 
2707                                     if (sc)
2708                                     {
2709                                         if (sc->function)
2710                                         {
2711                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2712                                             if (sc->block && addr_offset_concrete_func_only == false)
2713                                             {
2714                                                 // Check to make sure we aren't in an inline
2715                                                 // function. If we are, use the inline block
2716                                                 // range that contains "format_addr" since
2717                                                 // blocks can be discontiguous.
2718                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2719                                                 AddressRange inline_range;
2720                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
2721                                                     func_addr = inline_range.GetBaseAddress();
2722                                             }
2723                                         }
2724                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2725                                             func_addr = sc->symbol->GetAddress();
2726                                     }
2727 
2728                                     if (func_addr.IsValid())
2729                                     {
2730                                         const char *addr_offset_padding  =  " ";
2731                                         if (addr_offset_print_with_no_padding)
2732                                         {
2733                                             addr_offset_padding = "";
2734                                         }
2735                                         if (func_addr.GetSection() == format_addr.GetSection())
2736                                         {
2737                                             addr_t func_file_addr = func_addr.GetFileAddress();
2738                                             addr_t addr_file_addr = format_addr.GetFileAddress();
2739                                             if (addr_file_addr > func_file_addr)
2740                                                 s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
2741                                             else if (addr_file_addr < func_file_addr)
2742                                                 s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
2743                                             var_success = true;
2744                                         }
2745                                         else
2746                                         {
2747                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2748                                             if (target)
2749                                             {
2750                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
2751                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
2752                                                 if (addr_load_addr > func_load_addr)
2753                                                     s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
2754                                                 else if (addr_load_addr < func_load_addr)
2755                                                     s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
2756                                                 var_success = true;
2757                                             }
2758                                         }
2759                                     }
2760                                 }
2761                                 else
2762                                 {
2763                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2764                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
2765                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
2766                                         vaddr = format_addr.GetLoadAddress (target);
2767                                     if (vaddr == LLDB_INVALID_ADDRESS)
2768                                         vaddr = format_addr.GetFileAddress ();
2769 
2770                                     if (vaddr != LLDB_INVALID_ADDRESS)
2771                                     {
2772                                         int addr_width = 0;
2773                                         if (exe_ctx && target)
2774                                         {
2775                                             addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2776                                         }
2777                                         if (addr_width == 0)
2778                                             addr_width = 16;
2779                                         if (print_file_addr_or_load_addr)
2780                                         {
2781                                             format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
2782                                         }
2783                                         else
2784                                         {
2785                                             s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
2786                                         }
2787                                         var_success = true;
2788                                     }
2789                                 }
2790                             }
2791                         }
2792 
2793                         if (var_success == false)
2794                             success = false;
2795                     }
2796                     p = var_name_end;
2797                 }
2798                 else
2799                     break;
2800             }
2801             else
2802             {
2803                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
2804                 s.PutChar(*p);
2805             }
2806         }
2807         else if (*p == '\\')
2808         {
2809             ++p; // skip the slash
2810             switch (*p)
2811             {
2812             case 'a': s.PutChar ('\a'); break;
2813             case 'b': s.PutChar ('\b'); break;
2814             case 'f': s.PutChar ('\f'); break;
2815             case 'n': s.PutChar ('\n'); break;
2816             case 'r': s.PutChar ('\r'); break;
2817             case 't': s.PutChar ('\t'); break;
2818             case 'v': s.PutChar ('\v'); break;
2819             case '\'': s.PutChar ('\''); break;
2820             case '\\': s.PutChar ('\\'); break;
2821             case '0':
2822                 // 1 to 3 octal chars
2823                 {
2824                     // Make a string that can hold onto the initial zero char,
2825                     // up to 3 octal digits, and a terminating NULL.
2826                     char oct_str[5] = { 0, 0, 0, 0, 0 };
2827 
2828                     int i;
2829                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2830                         oct_str[i] = p[i];
2831 
2832                     // We don't want to consume the last octal character since
2833                     // the main for loop will do this for us, so we advance p by
2834                     // one less than i (even if i is zero)
2835                     p += i - 1;
2836                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2837                     if (octal_value <= UINT8_MAX)
2838                     {
2839                         s.PutChar((char)octal_value);
2840                     }
2841                 }
2842                 break;
2843 
2844             case 'x':
2845                 // hex number in the format
2846                 if (isxdigit(p[1]))
2847                 {
2848                     ++p;    // Skip the 'x'
2849 
2850                     // Make a string that can hold onto two hex chars plus a
2851                     // NULL terminator
2852                     char hex_str[3] = { 0,0,0 };
2853                     hex_str[0] = *p;
2854                     if (isxdigit(p[1]))
2855                     {
2856                         ++p; // Skip the first of the two hex chars
2857                         hex_str[1] = *p;
2858                     }
2859 
2860                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
2861                     if (hex_value <= UINT8_MAX)
2862                         s.PutChar ((char)hex_value);
2863                 }
2864                 else
2865                 {
2866                     s.PutChar('x');
2867                 }
2868                 break;
2869 
2870             default:
2871                 // Just desensitize any other character by just printing what
2872                 // came after the '\'
2873                 s << *p;
2874                 break;
2875 
2876             }
2877 
2878         }
2879     }
2880     if (end)
2881         *end = p;
2882     return success;
2883 }
2884 
2885 bool
2886 Debugger::FormatPrompt
2887 (
2888     const char *format,
2889     const SymbolContext *sc,
2890     const ExecutionContext *exe_ctx,
2891     const Address *addr,
2892     Stream &s,
2893     ValueObject* valobj
2894 )
2895 {
2896     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2897     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2898     if (format_str.length())
2899         format = format_str.c_str();
2900     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false);
2901 }
2902 
2903 bool
2904 Debugger::FormatDisassemblerAddress (const char *format,
2905                                      const SymbolContext *sc,
2906                                      const SymbolContext *prev_sc,
2907                                      const ExecutionContext *exe_ctx,
2908                                      const Address *addr,
2909                                      Stream &s)
2910 {
2911     if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope())
2912     {
2913         format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
2914     }
2915     bool function_changed = false;
2916     bool initial_function = false;
2917     if (prev_sc && (prev_sc->function || prev_sc->symbol))
2918     {
2919         if (sc && (sc->function || sc->symbol))
2920         {
2921             if (prev_sc->symbol && sc->symbol)
2922             {
2923                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
2924                 {
2925                     function_changed = true;
2926                 }
2927             }
2928             else if (prev_sc->function && sc->function)
2929             {
2930                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
2931                 {
2932                     function_changed = true;
2933                 }
2934             }
2935         }
2936     }
2937     // The first context on a list of instructions will have a prev_sc that
2938     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
2939     // would return false.  But we do get a prev_sc pointer.
2940     if ((sc && (sc->function || sc->symbol))
2941         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
2942     {
2943         initial_function = true;
2944     }
2945     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function);
2946 }
2947 
2948 
2949 void
2950 Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2951 {
2952     // For simplicity's sake, I am not going to deal with how to close down any
2953     // open logging streams, I just redirect everything from here on out to the
2954     // callback.
2955     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2956 }
2957 
2958 bool
2959 Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2960 {
2961     Log::Callbacks log_callbacks;
2962 
2963     StreamSP log_stream_sp;
2964     if (m_log_callback_stream_sp)
2965     {
2966         log_stream_sp = m_log_callback_stream_sp;
2967         // For now when using the callback mode you always get thread & timestamp.
2968         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2969     }
2970     else if (log_file == NULL || *log_file == '\0')
2971     {
2972         log_stream_sp = GetOutputFile();
2973     }
2974     else
2975     {
2976         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2977         if (pos != m_log_streams.end())
2978             log_stream_sp = pos->second.lock();
2979         if (!log_stream_sp)
2980         {
2981             log_stream_sp.reset (new StreamFile (log_file));
2982             m_log_streams[log_file] = log_stream_sp;
2983         }
2984     }
2985     assert (log_stream_sp.get());
2986 
2987     if (log_options == 0)
2988         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2989 
2990     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2991     {
2992         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2993         return true;
2994     }
2995     else
2996     {
2997         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2998         if (log_channel_sp)
2999         {
3000             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
3001             {
3002                 return true;
3003             }
3004             else
3005             {
3006                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
3007                 return false;
3008             }
3009         }
3010         else
3011         {
3012             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
3013             return false;
3014         }
3015     }
3016     return false;
3017 }
3018 
3019 SourceManager &
3020 Debugger::GetSourceManager ()
3021 {
3022     if (m_source_manager_ap.get() == NULL)
3023         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
3024     return *m_source_manager_ap;
3025 }
3026 
3027 
3028 
3029 // This function handles events that were broadcast by the process.
3030 void
3031 Debugger::HandleBreakpointEvent (const EventSP &event_sp)
3032 {
3033     using namespace lldb;
3034     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
3035 
3036 //    if (event_type & eBreakpointEventTypeAdded
3037 //        || event_type & eBreakpointEventTypeRemoved
3038 //        || event_type & eBreakpointEventTypeEnabled
3039 //        || event_type & eBreakpointEventTypeDisabled
3040 //        || event_type & eBreakpointEventTypeCommandChanged
3041 //        || event_type & eBreakpointEventTypeConditionChanged
3042 //        || event_type & eBreakpointEventTypeIgnoreChanged
3043 //        || event_type & eBreakpointEventTypeLocationsResolved)
3044 //    {
3045 //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
3046 //    }
3047 //
3048     if (event_type & eBreakpointEventTypeLocationsAdded)
3049     {
3050         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
3051         if (num_new_locations > 0)
3052         {
3053             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
3054             StreamFileSP output_sp (GetOutputFile());
3055             if (output_sp)
3056             {
3057                 output_sp->Printf("%d location%s added to breakpoint %d\n",
3058                                   num_new_locations,
3059                                   num_new_locations == 1 ? "" : "s",
3060                                   breakpoint->GetID());
3061                 RefreshTopIOHandler();
3062             }
3063         }
3064     }
3065 //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
3066 //    {
3067 //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
3068 //    }
3069 //    else if (event_type & eBreakpointEventTypeLocationsResolved)
3070 //    {
3071 //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
3072 //    }
3073 }
3074 
3075 size_t
3076 Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
3077 {
3078     size_t total_bytes = 0;
3079     if (stream == NULL)
3080         stream = GetOutputFile().get();
3081 
3082     if (stream)
3083     {
3084         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
3085         if (process == NULL)
3086         {
3087             TargetSP target_sp = GetTargetList().GetSelectedTarget();
3088             if (target_sp)
3089                 process = target_sp->GetProcessSP().get();
3090         }
3091         if (process)
3092         {
3093             Error error;
3094             size_t len;
3095             char stdio_buffer[1024];
3096             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
3097             {
3098                 stream->Write(stdio_buffer, len);
3099                 total_bytes += len;
3100             }
3101         }
3102         stream->Flush();
3103     }
3104     return total_bytes;
3105 }
3106 
3107 size_t
3108 Debugger::GetProcessSTDERR (Process *process, Stream *stream)
3109 {
3110     size_t total_bytes = 0;
3111     if (stream == NULL)
3112         stream = GetOutputFile().get();
3113 
3114     if (stream)
3115     {
3116         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
3117         if (process == NULL)
3118         {
3119             TargetSP target_sp = GetTargetList().GetSelectedTarget();
3120             if (target_sp)
3121                 process = target_sp->GetProcessSP().get();
3122         }
3123         if (process)
3124         {
3125             Error error;
3126             size_t len;
3127             char stdio_buffer[1024];
3128             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
3129             {
3130                 stream->Write(stdio_buffer, len);
3131                 total_bytes += len;
3132             }
3133         }
3134         stream->Flush();
3135     }
3136     return total_bytes;
3137 }
3138 
3139 
3140 // This function handles events that were broadcast by the process.
3141 void
3142 Debugger::HandleProcessEvent (const EventSP &event_sp)
3143 {
3144     using namespace lldb;
3145     const uint32_t event_type = event_sp->GetType();
3146     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
3147 
3148     StreamString output_stream;
3149     StreamString error_stream;
3150     const bool gui_enabled = IsForwardingEvents();
3151 
3152     if (!gui_enabled)
3153     {
3154         bool pop_process_io_handler = false;
3155         assert (process_sp);
3156 
3157         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
3158         {
3159             GetProcessSTDOUT (process_sp.get(), &output_stream);
3160         }
3161 
3162         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
3163         {
3164             GetProcessSTDERR (process_sp.get(), &error_stream);
3165         }
3166 
3167         if (event_type & Process::eBroadcastBitStateChanged)
3168         {
3169             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
3170         }
3171 
3172         if (output_stream.GetSize() || error_stream.GetSize())
3173         {
3174             StreamFileSP error_stream_sp (GetOutputFile());
3175             bool top_io_handler_hid = false;
3176 
3177             if (process_sp->ProcessIOHandlerIsActive() == false)
3178                 top_io_handler_hid = HideTopIOHandler();
3179 
3180             if (output_stream.GetSize())
3181             {
3182                 StreamFileSP output_stream_sp (GetOutputFile());
3183                 if (output_stream_sp)
3184                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
3185             }
3186 
3187             if (error_stream.GetSize())
3188             {
3189                 StreamFileSP error_stream_sp (GetErrorFile());
3190                 if (error_stream_sp)
3191                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
3192             }
3193 
3194             if (top_io_handler_hid)
3195                 RefreshTopIOHandler();
3196         }
3197 
3198         if (pop_process_io_handler)
3199             process_sp->PopProcessIOHandler();
3200     }
3201 }
3202 
3203 void
3204 Debugger::HandleThreadEvent (const EventSP &event_sp)
3205 {
3206     // At present the only thread event we handle is the Frame Changed event,
3207     // and all we do for that is just reprint the thread status for that thread.
3208     using namespace lldb;
3209     const uint32_t event_type = event_sp->GetType();
3210     if (event_type == Thread::eBroadcastBitStackChanged   ||
3211         event_type == Thread::eBroadcastBitThreadSelected )
3212     {
3213         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
3214         if (thread_sp)
3215         {
3216             HideTopIOHandler();
3217             StreamFileSP stream_sp (GetOutputFile());
3218             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
3219             RefreshTopIOHandler();
3220         }
3221     }
3222 }
3223 
3224 bool
3225 Debugger::IsForwardingEvents ()
3226 {
3227     return (bool)m_forward_listener_sp;
3228 }
3229 
3230 void
3231 Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
3232 {
3233     m_forward_listener_sp = listener_sp;
3234 }
3235 
3236 void
3237 Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
3238 {
3239     m_forward_listener_sp.reset();
3240 }
3241 
3242 
3243 void
3244 Debugger::DefaultEventHandler()
3245 {
3246     Listener& listener(GetListener());
3247     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
3248     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
3249     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
3250     BroadcastEventSpec target_event_spec (broadcaster_class_target,
3251                                           Target::eBroadcastBitBreakpointChanged);
3252 
3253     BroadcastEventSpec process_event_spec (broadcaster_class_process,
3254                                            Process::eBroadcastBitStateChanged   |
3255                                            Process::eBroadcastBitSTDOUT         |
3256                                            Process::eBroadcastBitSTDERR);
3257 
3258     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
3259                                           Thread::eBroadcastBitStackChanged     |
3260                                           Thread::eBroadcastBitThreadSelected   );
3261 
3262     listener.StartListeningForEventSpec (*this, target_event_spec);
3263     listener.StartListeningForEventSpec (*this, process_event_spec);
3264     listener.StartListeningForEventSpec (*this, thread_event_spec);
3265     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
3266                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
3267                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
3268                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
3269 
3270     // Let the thread that spawned us know that we have started up and
3271     // that we are now listening to all required events so no events get missed
3272     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
3273 
3274     bool done = false;
3275     while (!done)
3276     {
3277         EventSP event_sp;
3278         if (listener.WaitForEvent(NULL, event_sp))
3279         {
3280             if (event_sp)
3281             {
3282                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
3283                 if (broadcaster)
3284                 {
3285                     uint32_t event_type = event_sp->GetType();
3286                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
3287                     if (broadcaster_class == broadcaster_class_process)
3288                     {
3289                         HandleProcessEvent (event_sp);
3290                     }
3291                     else if (broadcaster_class == broadcaster_class_target)
3292                     {
3293                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
3294                         {
3295                             HandleBreakpointEvent (event_sp);
3296                         }
3297                     }
3298                     else if (broadcaster_class == broadcaster_class_thread)
3299                     {
3300                         HandleThreadEvent (event_sp);
3301                     }
3302                     else if (broadcaster == m_command_interpreter_ap.get())
3303                     {
3304                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
3305                         {
3306                             done = true;
3307                         }
3308                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
3309                         {
3310                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
3311                             if (data && data[0])
3312                             {
3313                                 StreamFileSP error_sp (GetErrorFile());
3314                                 if (error_sp)
3315                                 {
3316                                     HideTopIOHandler();
3317                                     error_sp->PutCString(data);
3318                                     error_sp->Flush();
3319                                     RefreshTopIOHandler();
3320                                 }
3321                             }
3322                         }
3323                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
3324                         {
3325                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
3326                             if (data && data[0])
3327                             {
3328                                 StreamFileSP output_sp (GetOutputFile());
3329                                 if (output_sp)
3330                                 {
3331                                     HideTopIOHandler();
3332                                     output_sp->PutCString(data);
3333                                     output_sp->Flush();
3334                                     RefreshTopIOHandler();
3335                                 }
3336                             }
3337                         }
3338                     }
3339                 }
3340 
3341                 if (m_forward_listener_sp)
3342                     m_forward_listener_sp->AddEvent(event_sp);
3343             }
3344         }
3345     }
3346 }
3347 
3348 lldb::thread_result_t
3349 Debugger::EventHandlerThread (lldb::thread_arg_t arg)
3350 {
3351     ((Debugger *)arg)->DefaultEventHandler();
3352     return NULL;
3353 }
3354 
3355 bool
3356 Debugger::StartEventHandlerThread()
3357 {
3358     if (!m_event_handler_thread.IsJoinable())
3359     {
3360         // We must synchronize with the DefaultEventHandler() thread to ensure
3361         // it is up and running and listening to events before we return from
3362         // this function. We do this by listening to events for the
3363         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
3364         Listener listener("lldb.debugger.event-handler");
3365         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
3366 
3367         // Use larger 8MB stack for this thread
3368         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
3369                                                               this,
3370                                                               NULL,
3371                                                               g_debugger_event_thread_stack_bytes);
3372 
3373         // Make sure DefaultEventHandler() is running and listening to events before we return
3374         // from this function. We are only listening for events of type
3375         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
3376         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
3377         lldb::EventSP event_sp;
3378         listener.WaitForEvent(NULL, event_sp);
3379     }
3380     return m_event_handler_thread.IsJoinable();
3381 }
3382 
3383 void
3384 Debugger::StopEventHandlerThread()
3385 {
3386     if (m_event_handler_thread.IsJoinable())
3387     {
3388         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
3389         m_event_handler_thread.Join(nullptr);
3390     }
3391 }
3392 
3393 
3394 lldb::thread_result_t
3395 Debugger::IOHandlerThread (lldb::thread_arg_t arg)
3396 {
3397     Debugger *debugger = (Debugger *)arg;
3398     debugger->ExecuteIOHanders();
3399     debugger->StopEventHandlerThread();
3400     return NULL;
3401 }
3402 
3403 bool
3404 Debugger::StartIOHandlerThread()
3405 {
3406     if (!m_io_handler_thread.IsJoinable())
3407         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
3408                                                             IOHandlerThread,
3409                                                             this,
3410                                                             NULL,
3411                                                             8*1024*1024); // Use larger 8MB stack for this thread
3412     return m_io_handler_thread.IsJoinable();
3413 }
3414 
3415 void
3416 Debugger::StopIOHandlerThread()
3417 {
3418     if (m_io_handler_thread.IsJoinable())
3419     {
3420         if (m_input_file_sp)
3421             m_input_file_sp->GetFile().Close();
3422         m_io_handler_thread.Join(nullptr);
3423     }
3424 }
3425 
3426 Target *
3427 Debugger::GetDummyTarget()
3428 {
3429     return m_target_list.GetDummyTarget (*this).get();
3430 }
3431 
3432 Target *
3433 Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
3434 {
3435     Target *target = nullptr;
3436     if (!prefer_dummy)
3437     {
3438         target = m_target_list.GetSelectedTarget().get();
3439         if (target)
3440             return target;
3441     }
3442 
3443     return GetDummyTarget();
3444 }
3445 
3446