]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/Debugger.cpp
Upgrade to Unbound 1.5.4.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / Debugger.cpp
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 void
931 Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
932 {
933     PushIOHandler (reader_sp);
934     
935     IOHandlerSP top_reader_sp = reader_sp;
936     while (top_reader_sp)
937     {
938         top_reader_sp->Activate();
939         top_reader_sp->Run();
940         top_reader_sp->Deactivate();
941         
942         if (top_reader_sp.get() == reader_sp.get())
943         {
944             if (PopIOHandler (reader_sp))
945                 break;
946         }
947         
948         while (1)
949         {
950             top_reader_sp = m_input_reader_stack.Top();
951             if (top_reader_sp && top_reader_sp->GetIsDone())
952                 m_input_reader_stack.Pop();
953             else
954                 break;
955         }
956     }
957 }
958
959 void
960 Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
961 {
962     // Before an IOHandler runs, it must have in/out/err streams.
963     // This function is called when one ore more of the streams
964     // are NULL. We use the top input reader's in/out/err streams,
965     // or fall back to the debugger file handles, or we fall back
966     // onto stdin/stdout/stderr as a last resort.
967     
968     Mutex::Locker locker (m_input_reader_stack.GetMutex());
969     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
970     // If no STDIN has been set, then set it appropriately
971     if (!in)
972     {
973         if (top_reader_sp)
974             in = top_reader_sp->GetInputStreamFile();
975         else
976             in = GetInputFile();
977         
978         // If there is nothing, use stdin
979         if (!in)
980             in = StreamFileSP(new StreamFile(stdin, false));
981     }
982     // If no STDOUT has been set, then set it appropriately
983     if (!out)
984     {
985         if (top_reader_sp)
986             out = top_reader_sp->GetOutputStreamFile();
987         else
988             out = GetOutputFile();
989         
990         // If there is nothing, use stdout
991         if (!out)
992             out = StreamFileSP(new StreamFile(stdout, false));
993     }
994     // If no STDERR has been set, then set it appropriately
995     if (!err)
996     {
997         if (top_reader_sp)
998             err = top_reader_sp->GetErrorStreamFile();
999         else
1000             err = GetErrorFile();
1001         
1002         // If there is nothing, use stderr
1003         if (!err)
1004             err = StreamFileSP(new StreamFile(stdout, false));
1005         
1006     }
1007 }
1008
1009 void
1010 Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
1011 {
1012     if (!reader_sp)
1013         return;
1014  
1015     // Got the current top input reader...
1016     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1017     
1018     // Don't push the same IO handler twice...
1019     if (reader_sp.get() != top_reader_sp.get())
1020     {
1021         // Push our new input reader
1022         m_input_reader_stack.Push (reader_sp);
1023
1024         // Interrupt the top input reader to it will exit its Run() function
1025         // and let this new input reader take over
1026         if (top_reader_sp)
1027             top_reader_sp->Deactivate();
1028     }
1029 }
1030
1031 bool
1032 Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
1033 {
1034     bool result = false;
1035     
1036     Mutex::Locker locker (m_input_reader_stack.GetMutex());
1037
1038     // The reader on the stop of the stack is done, so let the next
1039     // read on the stack refresh its prompt and if there is one...
1040     if (!m_input_reader_stack.IsEmpty())
1041     {
1042         IOHandlerSP reader_sp(m_input_reader_stack.Top());
1043         
1044         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
1045         {
1046             reader_sp->Deactivate();
1047             reader_sp->Cancel();
1048             m_input_reader_stack.Pop ();
1049             
1050             reader_sp = m_input_reader_stack.Top();
1051             if (reader_sp)
1052                 reader_sp->Activate();
1053
1054             result = true;
1055         }
1056     }
1057     return result;
1058 }
1059
1060 bool
1061 Debugger::HideTopIOHandler()
1062 {
1063     Mutex::Locker locker;
1064     
1065     if (locker.TryLock(m_input_reader_stack.GetMutex()))
1066     {
1067         IOHandlerSP reader_sp(m_input_reader_stack.Top());
1068         if (reader_sp)
1069             reader_sp->Hide();
1070         return true;
1071     }
1072     return false;
1073 }
1074
1075 void
1076 Debugger::RefreshTopIOHandler()
1077 {
1078     IOHandlerSP reader_sp(m_input_reader_stack.Top());
1079     if (reader_sp)
1080         reader_sp->Refresh();
1081 }
1082
1083
1084 StreamSP
1085 Debugger::GetAsyncOutputStream ()
1086 {
1087     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1088                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
1089 }
1090
1091 StreamSP
1092 Debugger::GetAsyncErrorStream ()
1093 {
1094     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
1095                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
1096 }    
1097
1098 size_t
1099 Debugger::GetNumDebuggers()
1100 {
1101     if (g_shared_debugger_refcount > 0)
1102     {
1103         Mutex::Locker locker (GetDebuggerListMutex ());
1104         return GetDebuggerList().size();
1105     }
1106     return 0;
1107 }
1108
1109 lldb::DebuggerSP
1110 Debugger::GetDebuggerAtIndex (size_t index)
1111 {
1112     DebuggerSP debugger_sp;
1113     
1114     if (g_shared_debugger_refcount > 0)
1115     {
1116         Mutex::Locker locker (GetDebuggerListMutex ());
1117         DebuggerList &debugger_list = GetDebuggerList();
1118         
1119         if (index < debugger_list.size())
1120             debugger_sp = debugger_list[index];
1121     }
1122
1123     return debugger_sp;
1124 }
1125
1126 DebuggerSP
1127 Debugger::FindDebuggerWithID (lldb::user_id_t id)
1128 {
1129     DebuggerSP debugger_sp;
1130
1131     if (g_shared_debugger_refcount > 0)
1132     {
1133         Mutex::Locker locker (GetDebuggerListMutex ());
1134         DebuggerList &debugger_list = GetDebuggerList();
1135         DebuggerList::iterator pos, end = debugger_list.end();
1136         for (pos = debugger_list.begin(); pos != end; ++pos)
1137         {
1138             if ((*pos).get()->GetID() == id)
1139             {
1140                 debugger_sp = *pos;
1141                 break;
1142             }
1143         }
1144     }
1145     return debugger_sp;
1146 }
1147
1148 #if 0
1149 static void
1150 TestPromptFormats (StackFrame *frame)
1151 {
1152     if (frame == NULL)
1153         return;
1154
1155     StreamString s;
1156     const char *prompt_format =         
1157     "{addr = '${addr}'\n}"
1158     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1159     "{current-pc-arrow = '${current-pc-arrow}'\n}"
1160     "{process.id = '${process.id}'\n}"
1161     "{process.name = '${process.name}'\n}"
1162     "{process.file.basename = '${process.file.basename}'\n}"
1163     "{process.file.fullpath = '${process.file.fullpath}'\n}"
1164     "{thread.id = '${thread.id}'\n}"
1165     "{thread.index = '${thread.index}'\n}"
1166     "{thread.name = '${thread.name}'\n}"
1167     "{thread.queue = '${thread.queue}'\n}"
1168     "{thread.stop-reason = '${thread.stop-reason}'\n}"
1169     "{target.arch = '${target.arch}'\n}"
1170     "{module.file.basename = '${module.file.basename}'\n}"
1171     "{module.file.fullpath = '${module.file.fullpath}'\n}"
1172     "{file.basename = '${file.basename}'\n}"
1173     "{file.fullpath = '${file.fullpath}'\n}"
1174     "{frame.index = '${frame.index}'\n}"
1175     "{frame.pc = '${frame.pc}'\n}"
1176     "{frame.sp = '${frame.sp}'\n}"
1177     "{frame.fp = '${frame.fp}'\n}"
1178     "{frame.flags = '${frame.flags}'\n}"
1179     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
1180     "{frame.reg.rip = '${frame.reg.rip}'\n}"
1181     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
1182     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
1183     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
1184     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
1185     "{frame.reg.carp = '${frame.reg.carp}'\n}"
1186     "{function.id = '${function.id}'\n}"
1187     "{function.changed = '${function.changed}'\n}"
1188     "{function.initial-function = '${function.initial-function}'\n}"
1189     "{function.name = '${function.name}'\n}"
1190     "{function.name-without-args = '${function.name-without-args}'\n}"
1191     "{function.name-with-args = '${function.name-with-args}'\n}"
1192     "{function.addr-offset = '${function.addr-offset}'\n}"
1193     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
1194     "{function.line-offset = '${function.line-offset}'\n}"
1195     "{function.pc-offset = '${function.pc-offset}'\n}"
1196     "{line.file.basename = '${line.file.basename}'\n}"
1197     "{line.file.fullpath = '${line.file.fullpath}'\n}"
1198     "{line.number = '${line.number}'\n}"
1199     "{line.start-addr = '${line.start-addr}'\n}"
1200     "{line.end-addr = '${line.end-addr}'\n}"
1201 ;
1202
1203     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
1204     ExecutionContext exe_ctx;
1205     frame->CalculateExecutionContext(exe_ctx);
1206     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
1207     {
1208         printf("%s\n", s.GetData());
1209     }
1210     else
1211     {
1212         printf ("what we got: %s\n", s.GetData());
1213     }
1214 }
1215 #endif
1216
1217 static bool
1218 ScanFormatDescriptor (const char* var_name_begin,
1219                       const char* var_name_end,
1220                       const char** var_name_final,
1221                       const char** percent_position,
1222                       Format* custom_format,
1223                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
1224 {
1225     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1226     *percent_position = ::strchr(var_name_begin,'%');
1227     if (!*percent_position || *percent_position > var_name_end)
1228     {
1229         if (log)
1230             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
1231         *var_name_final = var_name_end;
1232     }
1233     else
1234     {
1235         *var_name_final = *percent_position;
1236         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1237         if (log)
1238             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
1239         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
1240                                                   true,
1241                                                   *custom_format) )
1242         {
1243             if (log)
1244                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
1245             
1246             switch (format_name.front())
1247             {
1248                 case '@':             // if this is an @ sign, print ObjC description
1249                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
1250                     break;
1251                 case 'V': // if this is a V, print the value using the default format
1252                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1253                     break;
1254                 case 'L': // if this is an L, print the location of the value
1255                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
1256                     break;
1257                 case 'S': // if this is an S, print the summary after all
1258                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1259                     break;
1260                 case '#': // if this is a '#', print the number of children
1261                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
1262                     break;
1263                 case 'T': // if this is a 'T', print the type
1264                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
1265                     break;
1266                 case 'N': // if this is a 'N', print the name
1267                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
1268                     break;
1269                 case '>': // if this is a '>', print the name
1270                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
1271                     break;
1272                 default:
1273                     if (log)
1274                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
1275                     break;
1276             }
1277         }
1278         // a good custom format tells us to print the value using it
1279         else
1280         {
1281             if (log)
1282                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
1283             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1284         }
1285     }
1286     if (log)
1287         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1288                     *custom_format,
1289                     *val_obj_display);
1290     return true;
1291 }
1292
1293 static bool
1294 ScanBracketedRange (const char* var_name_begin,
1295                     const char* var_name_end,
1296                     const char* var_name_final,
1297                     const char** open_bracket_position,
1298                     const char** separator_position,
1299                     const char** close_bracket_position,
1300                     const char** var_name_final_if_array_range,
1301                     int64_t* index_lower,
1302                     int64_t* index_higher)
1303 {
1304     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1305     *open_bracket_position = ::strchr(var_name_begin,'[');
1306     if (*open_bracket_position && *open_bracket_position < var_name_final)
1307     {
1308         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
1309         *close_bracket_position = ::strchr(*open_bracket_position,']');
1310         // as usual, we assume that [] will come before %
1311         //printf("trying to expand a []\n");
1312         *var_name_final_if_array_range = *open_bracket_position;
1313         if (*close_bracket_position - *open_bracket_position == 1)
1314         {
1315             if (log)
1316                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
1317             *index_lower = 0;
1318         }
1319         else if (*separator_position == NULL || *separator_position > var_name_end)
1320         {
1321             char *end = NULL;
1322             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1323             *index_higher = *index_lower;
1324             if (log)
1325                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
1326         }
1327         else if (*close_bracket_position && *close_bracket_position < var_name_end)
1328         {
1329             char *end = NULL;
1330             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1331             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1332             if (log)
1333                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
1334         }
1335         else
1336         {
1337             if (log)
1338                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
1339             return false;
1340         }
1341         if (*index_lower > *index_higher && *index_higher > 0)
1342         {
1343             if (log)
1344                 log->Printf("[ScanBracketedRange] swapping indices");
1345             int64_t temp = *index_lower;
1346             *index_lower = *index_higher;
1347             *index_higher = temp;
1348         }
1349     }
1350     else if (log)
1351             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
1352     return true;
1353 }
1354
1355 template <typename T>
1356 static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
1357 {
1358     if (script_interpreter)
1359     {
1360         Error script_error;
1361         std::string script_output;
1362
1363         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
1364         {
1365             s.Printf("%s", script_output.c_str());
1366             return true;
1367         }
1368         else
1369         {
1370             s.Printf("<error: %s>",script_error.AsCString());
1371         }
1372     }
1373     return false;
1374 }
1375
1376 static ValueObjectSP
1377 ExpandIndexedExpression (ValueObject* valobj,
1378                          size_t index,
1379                          StackFrame* frame,
1380                          bool deref_pointer)
1381 {
1382     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1383     const char* ptr_deref_format = "[%d]";
1384     std::string ptr_deref_buffer(10,0);
1385     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1386     if (log)
1387         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1388     const char* first_unparsed;
1389     ValueObject::GetValueForExpressionPathOptions options;
1390     ValueObject::ExpressionPathEndResultType final_value_type;
1391     ValueObject::ExpressionPathScanEndReason reason_to_stop;
1392     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1393     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1394                                                           &first_unparsed,
1395                                                           &reason_to_stop,
1396                                                           &final_value_type,
1397                                                           options,
1398                                                           &what_next);
1399     if (!item)
1400     {
1401         if (log)
1402             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1403                " final_value_type %d",
1404                first_unparsed, reason_to_stop, final_value_type);
1405     }
1406     else
1407     {
1408         if (log)
1409             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1410                " final_value_type %d",
1411                first_unparsed, reason_to_stop, final_value_type);
1412     }
1413     return item;
1414 }
1415
1416 static inline bool
1417 IsToken(const char *var_name_begin, const char *var)
1418 {
1419     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
1420 }
1421
1422 static bool
1423 IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
1424     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
1425 {
1426     int var_len = strlen(var);
1427     if (::strncmp (var_name_begin, var, var_len) == 0)
1428     {
1429         var_name_begin += var_len;
1430         if (*var_name_begin == '}')
1431         {
1432             format = default_format;
1433             return true;
1434         }
1435         else if (*var_name_begin == '%')
1436         {
1437             // Allow format specifiers: x|X|u with optional width specifiers.
1438             //   ${thread.id%x}    ; hex
1439             //   ${thread.id%X}    ; uppercase hex
1440             //   ${thread.id%u}    ; unsigned decimal
1441             //   ${thread.id%8.8X} ; width.precision + specifier
1442             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
1443             int dot_count = 0;
1444             const char *specifier = NULL;
1445             int width_precision_length = 0;
1446             const char *width_precision = ++var_name_begin;
1447             while (isdigit(*var_name_begin) || *var_name_begin == '.')
1448             {
1449                 dot_count += (*var_name_begin == '.');
1450                 if (dot_count > 1)
1451                     break;
1452                 var_name_begin++;
1453                 width_precision_length++;
1454             }
1455
1456             if (IsToken (var_name_begin, "tid}"))
1457             {
1458                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
1459                 if (target)
1460                 {
1461                     ArchSpec arch (target->GetArchitecture ());
1462                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
1463                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
1464                         specifier = PRIu64;
1465                 }
1466                 if (!specifier)
1467                 {
1468                     format = default_format;
1469                     return true;
1470                 }
1471             }
1472             else if (IsToken (var_name_begin, "x}"))
1473                 specifier = PRIx64;
1474             else if (IsToken (var_name_begin, "X}"))
1475                 specifier = PRIX64;
1476             else if (IsToken (var_name_begin, "u}"))
1477                 specifier = PRIu64;
1478
1479             if (specifier)
1480             {
1481                 format = "%";
1482                 if (width_precision_length)
1483                     format += std::string(width_precision, width_precision_length);
1484                 format += specifier;
1485                 return true;
1486             }
1487         }
1488     }
1489     return false;
1490 }
1491
1492 // Find information for the "thread.info.*" specifiers in a format string
1493 static bool
1494 FormatThreadExtendedInfoRecurse
1495 (
1496     const char *var_name_begin,
1497     StructuredData::ObjectSP thread_info_dictionary,
1498     const SymbolContext *sc,
1499     const ExecutionContext *exe_ctx,
1500     Stream &s
1501 )
1502 {
1503     bool var_success = false;
1504     std::string token_format;
1505
1506     llvm::StringRef var_name(var_name_begin);
1507     size_t percent_idx = var_name.find('%');
1508     size_t close_curly_idx = var_name.find('}');
1509     llvm::StringRef path = var_name;
1510     llvm::StringRef formatter = var_name;
1511
1512     // 'path' will be the dot separated list of objects to transverse up until we hit
1513     // a close curly brace, a percent sign, or an end of string.
1514     if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
1515     {
1516         if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
1517         {
1518             if (percent_idx < close_curly_idx)
1519             {
1520                 path = var_name.slice(0, percent_idx);
1521                 formatter = var_name.substr (percent_idx);
1522             }
1523             else
1524             {
1525                 path = var_name.slice(0, close_curly_idx);
1526                 formatter = var_name.substr (close_curly_idx);
1527             }
1528         }
1529         else if (percent_idx != llvm::StringRef::npos)
1530         {
1531             path = var_name.slice(0, percent_idx);
1532             formatter = var_name.substr (percent_idx);
1533         }
1534         else if (close_curly_idx != llvm::StringRef::npos)
1535         {
1536             path = var_name.slice(0, close_curly_idx);
1537             formatter = var_name.substr (close_curly_idx);
1538         }
1539     }
1540
1541     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1542
1543     if (value.get())
1544     {
1545         if (value->GetType() == StructuredData::Type::eTypeInteger)
1546         {
1547             if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1548             {
1549                 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
1550                 var_success = true;
1551             }
1552         }
1553         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1554         {
1555             s.Printf ("%f", value->GetAsFloat()->GetValue());
1556             var_success = true;
1557         }
1558         else if (value->GetType() == StructuredData::Type::eTypeString)
1559         {
1560             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1561             var_success = true;
1562         }
1563         else if (value->GetType() == StructuredData::Type::eTypeArray)
1564         {
1565             if (value->GetAsArray()->GetSize() > 0)
1566             {
1567                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1568                 var_success = true;
1569             }
1570         }
1571         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1572         {
1573             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1574             var_success = true;
1575         }
1576     }
1577
1578     return var_success;
1579 }
1580
1581
1582 static bool
1583 FormatPromptRecurse
1584 (
1585     const char *format,
1586     const SymbolContext *sc,
1587     const ExecutionContext *exe_ctx,
1588     const Address *addr,
1589     Stream &s,
1590     const char **end,
1591     ValueObject* valobj,
1592     bool function_changed,
1593     bool initial_function
1594 )
1595 {
1596     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
1597     bool success = true;
1598     const char *p;
1599     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1600
1601     for (p = format; *p != '\0'; ++p)
1602     {
1603         if (realvalobj)
1604         {
1605             valobj = realvalobj;
1606             realvalobj = NULL;
1607         }
1608         size_t non_special_chars = ::strcspn (p, "${}\\");
1609         if (non_special_chars > 0)
1610         {
1611             if (success)
1612                 s.Write (p, non_special_chars);
1613             p += non_special_chars;            
1614         }
1615
1616         if (*p == '\0')
1617         {
1618             break;
1619         }
1620         else if (*p == '{')
1621         {
1622             // Start a new scope that must have everything it needs if it is to
1623             // to make it into the final output stream "s". If you want to make
1624             // a format that only prints out the function or symbol name if there
1625             // is one in the symbol context you can use:
1626             //      "{function =${function.name}}"
1627             // The first '{' starts a new scope that end with the matching '}' at
1628             // the end of the string. The contents "function =${function.name}"
1629             // will then be evaluated and only be output if there is a function
1630             // or symbol with a valid name. 
1631             StreamString sub_strm;
1632
1633             ++p;  // Skip the '{'
1634
1635             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function))
1636             {
1637                 // The stream had all it needed
1638                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
1639             }
1640             if (*p != '}')
1641             {
1642                 success = false;
1643                 break;
1644             }
1645         }
1646         else if (*p == '}')
1647         {
1648             // End of a enclosing scope
1649             break;
1650         }
1651         else if (*p == '$')
1652         {
1653             // We have a prompt variable to print
1654             ++p;
1655             if (*p == '{')
1656             {
1657                 ++p;
1658                 const char *var_name_begin = p;
1659                 const char *var_name_end = ::strchr (p, '}');
1660
1661                 if (var_name_end && var_name_begin < var_name_end)
1662                 {
1663                     // if we have already failed to parse, skip this variable
1664                     if (success)
1665                     {
1666                         const char *cstr = NULL;
1667                         std::string token_format;
1668                         Address format_addr;
1669
1670                         // normally "addr" means print a raw address but 
1671                         // "file-addr-or-load-addr" means print a module + file addr if there's no load addr
1672                         bool print_file_addr_or_load_addr = false;
1673                         bool addr_offset_concrete_func_only = false;
1674                         bool addr_offset_print_with_no_padding = false;
1675                         bool calculate_format_addr_function_offset = false;
1676                         // Set reg_kind and reg_num to invalid values
1677                         RegisterKind reg_kind = kNumRegisterKinds; 
1678                         uint32_t reg_num = LLDB_INVALID_REGNUM;
1679                         FileSpec format_file_spec;
1680                         const RegisterInfo *reg_info = NULL;
1681                         RegisterContext *reg_ctx = NULL;
1682                         bool do_deref_pointer = false;
1683                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
1684                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
1685                         
1686                         // Each variable must set success to true below...
1687                         bool var_success = false;
1688                         switch (var_name_begin[0])
1689                         {
1690                         case '*':
1691                         case 'v':
1692                         case 's':
1693                             {
1694                                 if (!valobj)
1695                                     break;
1696                                 
1697                                 if (log)
1698                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1699                                 
1700                                 // check for *var and *svar
1701                                 if (*var_name_begin == '*')
1702                                 {
1703                                     do_deref_pointer = true;
1704                                     var_name_begin++;
1705                                     if (log)
1706                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
1707                                 }
1708                                 
1709                                 if (*var_name_begin == 's')
1710                                 {
1711                                     if (!valobj->IsSynthetic())
1712                                         valobj = valobj->GetSyntheticValue().get();
1713                                     if (!valobj)
1714                                         break;
1715                                     var_name_begin++;
1716                                     if (log)
1717                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
1718                                 }
1719                                 
1720                                 // should be a 'v' by now
1721                                 if (*var_name_begin != 'v')
1722                                     break;
1723                                 
1724                                 if (log)
1725                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1726                                                                 
1727                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
1728                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1729                                 ValueObject::GetValueForExpressionPathOptions options;
1730                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
1731                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1732                                 ValueObject* target = NULL;
1733                                 Format custom_format = eFormatInvalid;
1734                                 const char* var_name_final = NULL;
1735                                 const char* var_name_final_if_array_range = NULL;
1736                                 const char* close_bracket_position = NULL;
1737                                 int64_t index_lower = -1;
1738                                 int64_t index_higher = -1;
1739                                 bool is_array_range = false;
1740                                 const char* first_unparsed;
1741                                 bool was_plain_var = false;
1742                                 bool was_var_format = false;
1743                                 bool was_var_indexed = false;
1744
1745                                 if (!valobj) break;
1746                                 // simplest case ${var}, just print valobj's value
1747                                 if (IsToken (var_name_begin, "var}"))
1748                                 {
1749                                     was_plain_var = true;
1750                                     target = valobj;
1751                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1752                                 }
1753                                 else if (IsToken (var_name_begin, "var.script:"))
1754                                 {
1755                                     var_name_begin += ::strlen("var.script:");
1756                                     std::string script_name(var_name_begin,var_name_end);
1757                                     ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1758                                     if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name))
1759                                         var_success = true;
1760                                     break;
1761                                 }
1762                                 else if (IsToken (var_name_begin,"var%"))
1763                                 {
1764                                     was_var_format = true;
1765                                     // this is a variable with some custom format applied to it
1766                                     const char* percent_position;
1767                                     target = valobj;
1768                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1769                                     ScanFormatDescriptor (var_name_begin,
1770                                                           var_name_end,
1771                                                           &var_name_final,
1772                                                           &percent_position,
1773                                                           &custom_format,
1774                                                           &val_obj_display);
1775                                 }
1776                                     // this is ${var.something} or multiple .something nested
1777                                 else if (IsToken (var_name_begin, "var"))
1778                                 {
1779                                     if (IsToken (var_name_begin, "var["))
1780                                         was_var_indexed = true;
1781                                     const char* percent_position;
1782                                     ScanFormatDescriptor (var_name_begin,
1783                                                           var_name_end,
1784                                                           &var_name_final,
1785                                                           &percent_position,
1786                                                           &custom_format,
1787                                                           &val_obj_display);
1788                                     
1789                                     const char* open_bracket_position;
1790                                     const char* separator_position;
1791                                     ScanBracketedRange (var_name_begin,
1792                                                         var_name_end,
1793                                                         var_name_final,
1794                                                         &open_bracket_position,
1795                                                         &separator_position,
1796                                                         &close_bracket_position,
1797                                                         &var_name_final_if_array_range,
1798                                                         &index_lower,
1799                                                         &index_higher);
1800                                                                     
1801                                     Error error;
1802                                     
1803                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1804                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1805
1806                                     if (log)
1807                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1808                                     
1809                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1810                                                                              &first_unparsed,
1811                                                                              &reason_to_stop,
1812                                                                              &final_value_type,
1813                                                                              options,
1814                                                                              &what_next).get();
1815                                     
1816                                     if (!target)
1817                                     {
1818                                         if (log)
1819                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1820                                                " final_value_type %d",
1821                                                first_unparsed, reason_to_stop, final_value_type);
1822                                         break;
1823                                     }
1824                                     else
1825                                     {
1826                                         if (log)
1827                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1828                                                " final_value_type %d",
1829                                                first_unparsed, reason_to_stop, final_value_type);
1830                                         target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
1831                                     }
1832                                 }
1833                                 else
1834                                     break;
1835                                 
1836                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
1837                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1838                                 
1839                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1840
1841                                 if (do_deref_pointer && !is_array_range)
1842                                 {
1843                                     // I have not deref-ed yet, let's do it
1844                                     // this happens when we are not going through GetValueForVariableExpressionPath
1845                                     // to get to the target ValueObject
1846                                     Error error;
1847                                     target = target->Dereference(error).get();
1848                                     if (error.Fail())
1849                                     {
1850                                         if (log)
1851                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1852                                         break;
1853                                     }
1854                                     do_deref_pointer = false;
1855                                 }
1856                                 
1857                                 if (!target)
1858                                 {
1859                                     if (log)
1860                                         log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
1861                                     break;
1862                                 }
1863                                 
1864                                 // we do not want to use the summary for a bitfield of type T:n
1865                                 // if we were originally dealing with just a T - that would get
1866                                 // us into an endless recursion
1867                                 if (target->IsBitfield() && was_var_indexed)
1868                                 {
1869                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1870                                     StreamString bitfield_name;
1871                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1872                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1873                                     if (!DataVisualization::GetSummaryForType(type_sp))
1874                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1875                                 }
1876                                 
1877                                 // TODO use flags for these
1878                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
1879                                 bool is_array = (type_info_flags & eTypeIsArray) != 0;
1880                                 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
1881                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1882                                 
1883                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1884                                 {
1885                                     StreamString str_temp;
1886                                     if (log)
1887                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1888                                     
1889                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1890                                     {
1891                                         // try to use the special cases
1892                                         var_success = target->DumpPrintableRepresentation(str_temp,
1893                                                                                           val_obj_display,
1894                                                                                           custom_format);
1895                                         if (log)
1896                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1897                                         
1898                                         // should not happen
1899                                         if (var_success)
1900                                             s << str_temp.GetData();
1901                                         var_success = true;
1902                                         break;
1903                                     }
1904                                     else
1905                                     {
1906                                         if (was_plain_var) // if ${var}
1907                                         {
1908                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1909                                         }
1910                                         else if (is_pointer) // if pointer, value is the address stored
1911                                         {
1912                                             target->DumpPrintableRepresentation (s,
1913                                                                                  val_obj_display,
1914                                                                                  custom_format,
1915                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
1916                                         }
1917                                         var_success = true;
1918                                         break;
1919                                     }
1920                                 }
1921                                 
1922                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1923                                 // type @ location message
1924                                 if (is_aggregate && was_plain_var)
1925                                 {
1926                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1927                                     var_success = true;
1928                                     break;
1929                                 }
1930                                 
1931                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
1932                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
1933                                 {
1934                                     s << "<invalid use of aggregate type>";
1935                                     var_success = true;
1936                                     break;
1937                                 }
1938                                                                 
1939                                 if (!is_array_range)
1940                                 {
1941                                     if (log)
1942                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
1943                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1944                                 }
1945                                 else
1946                                 {   
1947                                     if (log)
1948                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
1949                                     if (!is_array && !is_pointer)
1950                                         break;
1951                                     if (log)
1952                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1953                                     const char* special_directions = NULL;
1954                                     StreamString special_directions_writer;
1955                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1956                                     {
1957                                         ConstString additional_data;
1958                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1959                                         special_directions_writer.Printf("${%svar%s}",
1960                                                                          do_deref_pointer ? "*" : "",
1961                                                                          additional_data.GetCString());
1962                                         special_directions = special_directions_writer.GetData();
1963                                     }
1964                                     
1965                                     // let us display items index_lower thru index_higher of this array
1966                                     s.PutChar('[');
1967                                     var_success = true;
1968
1969                                     if (index_higher < 0)
1970                                         index_higher = valobj->GetNumChildren() - 1;
1971                                     
1972                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1973                                     
1974                                     for (;index_lower<=index_higher;index_lower++)
1975                                     {
1976                                         ValueObject* item = ExpandIndexedExpression (target,
1977                                                                                      index_lower,
1978                                                                                      exe_ctx->GetFramePtr(),
1979                                                                                      false).get();
1980                                         
1981                                         if (!item)
1982                                         {
1983                                             if (log)
1984                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1985                                         }
1986                                         else
1987                                         {
1988                                             if (log)
1989                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1990                                         }
1991
1992                                         if (!special_directions)
1993                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1994                                         else
1995                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function);
1996                                         
1997                                         if (--max_num_children == 0)
1998                                         {
1999                                             s.PutCString(", ...");
2000                                             break;
2001                                         }
2002                                         
2003                                         if (index_lower < index_higher)
2004                                             s.PutChar(',');
2005                                     }
2006                                     s.PutChar(']');
2007                                 }
2008                             }
2009                             break;
2010                         case 'a':
2011                             if (IsToken (var_name_begin, "addr-file-or-load}"))
2012                             {
2013                                 print_file_addr_or_load_addr = true;
2014                             }
2015                             if (IsToken (var_name_begin, "addr}")
2016                                 || IsToken (var_name_begin, "addr-file-or-load}"))
2017                             {
2018                                 if (addr && addr->IsValid())
2019                                 {
2020                                     var_success = true;
2021                                     format_addr = *addr;
2022                                 }
2023                             }
2024                             break;
2025
2026                         case 'p':
2027                             if (IsToken (var_name_begin, "process."))
2028                             {
2029                                 if (exe_ctx)
2030                                 {
2031                                     Process *process = exe_ctx->GetProcessPtr();
2032                                     if (process)
2033                                     {
2034                                         var_name_begin += ::strlen ("process.");
2035                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
2036                                         {
2037                                             s.Printf(token_format.c_str(), process->GetID());
2038                                             var_success = true;
2039                                         }
2040                                         else if ((IsToken (var_name_begin, "name}")) ||
2041                                                 (IsToken (var_name_begin, "file.basename}")) ||
2042                                                 (IsToken (var_name_begin, "file.fullpath}")))
2043                                         {
2044                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
2045                                             if (exe_module)
2046                                             {
2047                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
2048                                                 {
2049                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
2050                                                     var_success = (bool)format_file_spec;
2051                                                 }
2052                                                 else
2053                                                 {
2054                                                     format_file_spec = exe_module->GetFileSpec();
2055                                                     var_success = (bool)format_file_spec;
2056                                                 }
2057                                             }
2058                                         }
2059                                         else if (IsToken (var_name_begin, "script:"))
2060                                         {
2061                                             var_name_begin += ::strlen("script:");
2062                                             std::string script_name(var_name_begin,var_name_end);
2063                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2064                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
2065                                                 var_success = true;
2066                                         }
2067                                     }
2068                                 }
2069                             }
2070                             break;
2071                         
2072                         case 't':
2073                            if (IsToken (var_name_begin, "thread."))
2074                             {
2075                                 if (exe_ctx)
2076                                 {
2077                                     Thread *thread = exe_ctx->GetThreadPtr();
2078                                     if (thread)
2079                                     {
2080                                         var_name_begin += ::strlen ("thread.");
2081                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2082                                         {
2083                                             s.Printf(token_format.c_str(), thread->GetID());
2084                                             var_success = true;
2085                                         }
2086                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2087                                         {
2088                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
2089                                             var_success = true;
2090                                         }
2091                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
2092                                         {
2093                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
2094                                             var_success = true;
2095                                         }
2096                                         else if (IsToken (var_name_begin, "name}"))
2097                                         {
2098                                             cstr = thread->GetName();
2099                                             var_success = cstr && cstr[0];
2100                                             if (var_success)
2101                                                 s.PutCString(cstr);
2102                                         }
2103                                         else if (IsToken (var_name_begin, "queue}"))
2104                                         {
2105                                             cstr = thread->GetQueueName();
2106                                             var_success = cstr && cstr[0];
2107                                             if (var_success)
2108                                                 s.PutCString(cstr);
2109                                         }
2110                                         else if (IsToken (var_name_begin, "stop-reason}"))
2111                                         {
2112                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2113                                             if (stop_info_sp && stop_info_sp->IsValid())
2114                                             {
2115                                                 cstr = stop_info_sp->GetDescription();
2116                                                 if (cstr && cstr[0])
2117                                                 {
2118                                                     s.PutCString(cstr);
2119                                                     var_success = true;
2120                                                 }
2121                                             }
2122                                         }
2123                                         else if (IsToken (var_name_begin, "return-value}"))
2124                                         {
2125                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2126                                             if (stop_info_sp && stop_info_sp->IsValid())
2127                                             {
2128                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
2129                                                 if (return_valobj_sp)
2130                                                 {
2131                                                     return_valobj_sp->Dump(s);
2132                                                     var_success = true;
2133                                                 }
2134                                             }
2135                                         }
2136                                         else if (IsToken (var_name_begin, "completed-expression}"))
2137                                         {
2138                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2139                                             if (stop_info_sp && stop_info_sp->IsValid())
2140                                             {
2141                                                 ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
2142                                                 if (expression_var_sp && expression_var_sp->GetValueObject())
2143                                                 {
2144                                                     expression_var_sp->GetValueObject()->Dump(s);
2145                                                     var_success = true;
2146                                                 }
2147                                             }
2148                                         }
2149                                         else if (IsToken (var_name_begin, "script:"))
2150                                         {
2151                                             var_name_begin += ::strlen("script:");
2152                                             std::string script_name(var_name_begin,var_name_end);
2153                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2154                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2155                                                 var_success = true;
2156                                         }
2157                                         else if (IsToken (var_name_begin, "info."))
2158                                         {
2159                                             var_name_begin += ::strlen("info.");
2160                                             StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
2161                                             if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
2162                                             {
2163                                                 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
2164                                             }
2165                                         }
2166                                     }
2167                                 }
2168                             }
2169                             else if (IsToken (var_name_begin, "target."))
2170                             {
2171                                 // TODO: hookup properties
2172 //                                if (!target_properties_sp)
2173 //                                {
2174 //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2175 //                                    if (target)
2176 //                                        target_properties_sp = target->GetProperties();
2177 //                                }
2178 //
2179 //                                if (target_properties_sp)
2180 //                                {
2181 //                                    var_name_begin += ::strlen ("target.");
2182 //                                    const char *end_property = strchr(var_name_begin, '}');
2183 //                                    if (end_property)
2184 //                                    {
2185 //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
2186 //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
2187 //                                        if (!property_value.empty())
2188 //                                        {
2189 //                                            s.PutCString (property_value.c_str());
2190 //                                            var_success = true;
2191 //                                        }
2192 //                                    }
2193 //                                }                                        
2194                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2195                                 if (target)
2196                                 {
2197                                     var_name_begin += ::strlen ("target.");
2198                                     if (IsToken (var_name_begin, "arch}"))
2199                                     {
2200                                         ArchSpec arch (target->GetArchitecture ());
2201                                         if (arch.IsValid())
2202                                         {
2203                                             s.PutCString (arch.GetArchitectureName());
2204                                             var_success = true;
2205                                         }
2206                                     }
2207                                     else if (IsToken (var_name_begin, "script:"))
2208                                     {
2209                                         var_name_begin += ::strlen("script:");
2210                                         std::string script_name(var_name_begin,var_name_end);
2211                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2212                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2213                                             var_success = true;
2214                                     }
2215                                 }
2216                             }
2217                             break;
2218
2219                         case 'm':
2220                            if (IsToken (var_name_begin, "module."))
2221                             {
2222                                 if (sc && sc->module_sp.get())
2223                                 {
2224                                     Module *module = sc->module_sp.get();
2225                                     var_name_begin += ::strlen ("module.");
2226                                     
2227                                     if (IsToken (var_name_begin, "file."))
2228                                     {
2229                                         if (module->GetFileSpec())
2230                                         {
2231                                             var_name_begin += ::strlen ("file.");
2232                                             
2233                                             if (IsToken (var_name_begin, "basename}"))
2234                                             {
2235                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
2236                                                 var_success = (bool)format_file_spec;
2237                                             }
2238                                             else if (IsToken (var_name_begin, "fullpath}"))
2239                                             {
2240                                                 format_file_spec = module->GetFileSpec();
2241                                                 var_success = (bool)format_file_spec;
2242                                             }
2243                                         }
2244                                     }
2245                                 }
2246                             }
2247                             break;
2248                             
2249                         
2250                         case 'f':
2251                            if (IsToken (var_name_begin, "file."))
2252                             {
2253                                 if (sc && sc->comp_unit != NULL)
2254                                 {
2255                                     var_name_begin += ::strlen ("file.");
2256                                     
2257                                     if (IsToken (var_name_begin, "basename}"))
2258                                     {
2259                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
2260                                         var_success = (bool)format_file_spec;
2261                                     }
2262                                     else if (IsToken (var_name_begin, "fullpath}"))
2263                                     {
2264                                         format_file_spec = *sc->comp_unit;
2265                                         var_success = (bool)format_file_spec;
2266                                     }
2267                                 }
2268                             }
2269                            else if (IsToken (var_name_begin, "frame."))
2270                             {
2271                                 if (exe_ctx)
2272                                 {
2273                                     StackFrame *frame = exe_ctx->GetFramePtr();
2274                                     if (frame)
2275                                     {
2276                                         var_name_begin += ::strlen ("frame.");
2277                                         if (IsToken (var_name_begin, "index}"))
2278                                         {
2279                                             s.Printf("%u", frame->GetFrameIndex());
2280                                             var_success = true;
2281                                         }
2282                                         else if (IsToken (var_name_begin, "pc}"))
2283                                         {
2284                                             reg_kind = eRegisterKindGeneric;
2285                                             reg_num = LLDB_REGNUM_GENERIC_PC;
2286                                             var_success = true;
2287                                         }
2288                                         else if (IsToken (var_name_begin, "sp}"))
2289                                         {
2290                                             reg_kind = eRegisterKindGeneric;
2291                                             reg_num = LLDB_REGNUM_GENERIC_SP;
2292                                             var_success = true;
2293                                         }
2294                                         else if (IsToken (var_name_begin, "fp}"))
2295                                         {
2296                                             reg_kind = eRegisterKindGeneric;
2297                                             reg_num = LLDB_REGNUM_GENERIC_FP;
2298                                             var_success = true;
2299                                         }
2300                                         else if (IsToken (var_name_begin, "flags}"))
2301                                         {
2302                                             reg_kind = eRegisterKindGeneric;
2303                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
2304                                             var_success = true;
2305                                         }
2306                                         else if (IsToken (var_name_begin, "reg."))
2307                                         {
2308                                             reg_ctx = frame->GetRegisterContext().get();
2309                                             if (reg_ctx)
2310                                             {
2311                                                 var_name_begin += ::strlen ("reg.");
2312                                                 if (var_name_begin < var_name_end)
2313                                                 {
2314                                                     std::string reg_name (var_name_begin, var_name_end);
2315                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
2316                                                     if (reg_info)
2317                                                         var_success = true;
2318                                                 }
2319                                             }
2320                                         }
2321                                         else if (IsToken (var_name_begin, "script:"))
2322                                         {
2323                                             var_name_begin += ::strlen("script:");
2324                                             std::string script_name(var_name_begin,var_name_end);
2325                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2326                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2327                                                 var_success = true;
2328                                         }
2329                                     }
2330                                 }
2331                             }
2332                             else if (IsToken (var_name_begin, "function."))
2333                             {
2334                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
2335                                 {
2336                                     var_name_begin += ::strlen ("function.");
2337                                     if (IsToken (var_name_begin, "id}"))
2338                                     {
2339                                         if (sc->function)
2340                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
2341                                         else
2342                                             s.Printf("symbol[%u]", sc->symbol->GetID());
2343
2344                                         var_success = true;
2345                                     }
2346                                     if (IsToken (var_name_begin, "changed}") && function_changed)
2347                                     {
2348                                         var_success = true;
2349                                     }
2350                                     if (IsToken (var_name_begin, "initial-function}") && initial_function)
2351                                     {
2352                                         var_success = true;
2353                                     }
2354                                     else if (IsToken (var_name_begin, "name}"))
2355                                     {
2356                                         if (sc->function)
2357                                             cstr = sc->function->GetName().AsCString (NULL);
2358                                         else if (sc->symbol)
2359                                             cstr = sc->symbol->GetName().AsCString (NULL);
2360                                         if (cstr)
2361                                         {
2362                                             s.PutCString(cstr);
2363                                             
2364                                             if (sc->block)
2365                                             {
2366                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2367                                                 if (inline_block)
2368                                                 {
2369                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
2370                                                     if (inline_info)
2371                                                     {
2372                                                         s.PutCString(" [inlined] ");
2373                                                         inline_info->GetName().Dump(&s);
2374                                                     }
2375                                                 }
2376                                             }
2377                                             var_success = true;
2378                                         }
2379                                     }
2380                                     else if (IsToken (var_name_begin, "name-without-args}"))
2381                                     {
2382                                         ConstString name;
2383                                         if (sc->function)
2384                                             name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2385                                         else if (sc->symbol)
2386                                             name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2387                                         if (name)
2388                                         {
2389                                             s.PutCString(name.GetCString());
2390                                             var_success = true;
2391                                         }
2392                                     }
2393                                     else if (IsToken (var_name_begin, "name-with-args}"))
2394                                     {
2395                                         // Print the function name with arguments in it
2396
2397                                         if (sc->function)
2398                                         {
2399                                             var_success = true;
2400                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
2401                                             cstr = sc->function->GetName().AsCString (NULL);
2402                                             if (cstr)
2403                                             {
2404                                                 const InlineFunctionInfo *inline_info = NULL;
2405                                                 VariableListSP variable_list_sp;
2406                                                 bool get_function_vars = true;
2407                                                 if (sc->block)
2408                                                 {
2409                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
2410
2411                                                     if (inline_block)
2412                                                     {
2413                                                         get_function_vars = false;
2414                                                         inline_info = sc->block->GetInlinedFunctionInfo();
2415                                                         if (inline_info)
2416                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
2417                                                     }
2418                                                 }
2419                                                 
2420                                                 if (get_function_vars)
2421                                                 {
2422                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
2423                                                 }
2424                                                 
2425                                                 if (inline_info)
2426                                                 {
2427                                                     s.PutCString (cstr);
2428                                                     s.PutCString (" [inlined] ");
2429                                                     cstr = inline_info->GetName().GetCString();
2430                                                 }
2431                                                 
2432                                                 VariableList args;
2433                                                 if (variable_list_sp)
2434                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
2435                                                 if (args.GetSize() > 0)
2436                                                 {
2437                                                     const char *open_paren = strchr (cstr, '(');
2438                                                     const char *close_paren = nullptr;
2439                                                     const char *generic = strchr(cstr, '<');
2440                                                     // if before the arguments list begins there is a template sign
2441                                                     // then scan to the end of the generic args before you try to find
2442                                                     // the arguments list
2443                                                     if (generic && open_paren && generic < open_paren)
2444                                                     {
2445                                                         int generic_depth = 1;
2446                                                         ++generic;
2447                                                         for (;
2448                                                              *generic && generic_depth > 0;
2449                                                              generic++)
2450                                                         {
2451                                                             if (*generic == '<')
2452                                                                 generic_depth++;
2453                                                             if (*generic == '>')
2454                                                                 generic_depth--;
2455                                                         }
2456                                                         if (*generic)
2457                                                             open_paren = strchr(generic, '(');
2458                                                         else
2459                                                             open_paren = nullptr;
2460                                                     }
2461                                                     if (open_paren)
2462                                                     {
2463                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2464                                                         {
2465                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2466                                                             if (open_paren)
2467                                                                 close_paren = strchr (open_paren, ')');
2468                                                         }
2469                                                         else
2470                                                             close_paren = strchr (open_paren, ')');
2471                                                     }
2472                                                     
2473                                                     if (open_paren)
2474                                                         s.Write(cstr, open_paren - cstr + 1);
2475                                                     else
2476                                                     {
2477                                                         s.PutCString (cstr);
2478                                                         s.PutChar ('(');
2479                                                     }
2480                                                     const size_t num_args = args.GetSize();
2481                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
2482                                                     {
2483                                                         std::string buffer;
2484                                                         
2485                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
2486                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2487                                                         const char *var_representation = nullptr;
2488                                                         const char *var_name = var_value_sp->GetName().GetCString();
2489                                                         if (var_value_sp->GetClangType().IsAggregateType() &&
2490                                                             DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
2491                                                         {
2492                                                             static StringSummaryFormat format(TypeSummaryImpl::Flags()
2493                                                                                               .SetHideItemNames(false)
2494                                                                                               .SetShowMembersOneLiner(true),
2495                                                                                               "");
2496                                                             format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
2497                                                             var_representation = buffer.c_str();
2498                                                         }
2499                                                         else
2500                                                             var_representation = var_value_sp->GetValueAsCString();
2501                                                         if (arg_idx > 0)
2502                                                             s.PutCString (", ");
2503                                                         if (var_value_sp->GetError().Success())
2504                                                         {
2505                                                             if (var_representation)
2506                                                                 s.Printf ("%s=%s", var_name, var_representation);
2507                                                             else
2508                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2509                                                         }
2510                                                         else
2511                                                             s.Printf ("%s=<unavailable>", var_name);
2512                                                     }
2513                                                     
2514                                                     if (close_paren)
2515                                                         s.PutCString (close_paren);
2516                                                     else
2517                                                         s.PutChar(')');
2518
2519                                                 }
2520                                                 else
2521                                                 {
2522                                                     s.PutCString(cstr);
2523                                                 }
2524                                             }
2525                                         }
2526                                         else if (sc->symbol)
2527                                         {
2528                                             cstr = sc->symbol->GetName().AsCString (NULL);
2529                                             if (cstr)
2530                                             {
2531                                                 s.PutCString(cstr);
2532                                                 var_success = true;
2533                                             }
2534                                         }
2535                                     }
2536                                     else if (IsToken (var_name_begin, "addr-offset}")
2537                                             || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
2538                                     {
2539                                         if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
2540                                         {
2541                                             addr_offset_print_with_no_padding = true;
2542                                             addr_offset_concrete_func_only = true;
2543                                         }
2544                                         var_success = addr != NULL;
2545                                         if (var_success)
2546                                         {
2547                                             format_addr = *addr;
2548                                             calculate_format_addr_function_offset = true;
2549                                         }
2550                                     }
2551                                     else if (IsToken (var_name_begin, "line-offset}"))
2552                                     {
2553                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
2554                                         if (var_success)
2555                                         {
2556                                             format_addr = sc->line_entry.range.GetBaseAddress();
2557                                             calculate_format_addr_function_offset = true;
2558                                         }
2559                                     }
2560                                     else if (IsToken (var_name_begin, "pc-offset}"))
2561                                     {
2562                                         StackFrame *frame = exe_ctx->GetFramePtr();
2563                                         var_success = frame != NULL;
2564                                         if (var_success)
2565                                         {
2566                                             format_addr = frame->GetFrameCodeAddress();
2567                                             calculate_format_addr_function_offset = true;
2568                                         }
2569                                     }
2570                                 }
2571                             }
2572                             break;
2573
2574                         case 'l':
2575                             if (IsToken (var_name_begin, "line."))
2576                             {
2577                                 if (sc && sc->line_entry.IsValid())
2578                                 {
2579                                     var_name_begin += ::strlen ("line.");
2580                                     if (IsToken (var_name_begin, "file."))
2581                                     {
2582                                         var_name_begin += ::strlen ("file.");
2583                                         
2584                                         if (IsToken (var_name_begin, "basename}"))
2585                                         {
2586                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
2587                                             var_success = (bool)format_file_spec;
2588                                         }
2589                                         else if (IsToken (var_name_begin, "fullpath}"))
2590                                         {
2591                                             format_file_spec = sc->line_entry.file;
2592                                             var_success = (bool)format_file_spec;
2593                                         }
2594                                     }
2595                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
2596                                     {
2597                                         var_success = true;
2598                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
2599                                     }
2600                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
2601                                              (IsToken (var_name_begin, "end-addr}")))
2602                                     {
2603                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
2604                                         if (var_success)
2605                                         {
2606                                             format_addr = sc->line_entry.range.GetBaseAddress();
2607                                             if (var_name_begin[0] == 'e')
2608                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
2609                                         }
2610                                     }
2611                                 }
2612                             }
2613                             break;
2614                         case 'c':
2615                             if (IsToken (var_name_begin, "current-pc-arrow"))
2616                             {
2617                                 if (addr && exe_ctx && exe_ctx->GetFramePtr())
2618                                 {
2619                                     RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
2620                                     if (reg_ctx.get())
2621                                     {
2622                                         addr_t pc_loadaddr = reg_ctx->GetPC();
2623                                         if (pc_loadaddr != LLDB_INVALID_ADDRESS)
2624                                         {
2625                                             Address pc;
2626                                             pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
2627                                             if (pc == *addr)
2628                                             {
2629                                                 s.Printf ("-> ");
2630                                                 var_success = true;
2631                                             }
2632                                         }
2633                                     }
2634                                     if (var_success == false)
2635                                     {
2636                                         s.Printf("   ");
2637                                         var_success = true;
2638                                     }
2639                                 }
2640                                 var_success = true;
2641                             }
2642                             break;
2643                         }
2644                         
2645                         if (var_success)
2646                         {
2647                             // If format addr is valid, then we need to print an address
2648                             if (reg_num != LLDB_INVALID_REGNUM)
2649                             {
2650                                 StackFrame *frame = exe_ctx->GetFramePtr();
2651                                 // We have a register value to display...
2652                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
2653                                 {
2654                                     format_addr = frame->GetFrameCodeAddress();
2655                                 }
2656                                 else
2657                                 {
2658                                     if (reg_ctx == NULL)
2659                                         reg_ctx = frame->GetRegisterContext().get();
2660
2661                                     if (reg_ctx)
2662                                     {
2663                                         if (reg_kind != kNumRegisterKinds)
2664                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
2665                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
2666                                         var_success = reg_info != NULL;
2667                                     }
2668                                 }
2669                             }
2670                             
2671                             if (reg_info != NULL)
2672                             {
2673                                 RegisterValue reg_value;
2674                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
2675                                 if (var_success)
2676                                 {
2677                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
2678                                 }
2679                             }                            
2680                             
2681                             if (format_file_spec)
2682                             {
2683                                 s << format_file_spec;
2684                             }
2685
2686                             // If format addr is valid, then we need to print an address
2687                             if (format_addr.IsValid())
2688                             {
2689                                 var_success = false;
2690
2691                                 if (calculate_format_addr_function_offset)
2692                                 {
2693                                     Address func_addr;
2694                                     
2695                                     if (sc)
2696                                     {
2697                                         if (sc->function)
2698                                         {
2699                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2700                                             if (sc->block && addr_offset_concrete_func_only == false)
2701                                             {
2702                                                 // Check to make sure we aren't in an inline
2703                                                 // function. If we are, use the inline block
2704                                                 // range that contains "format_addr" since
2705                                                 // blocks can be discontiguous.
2706                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2707                                                 AddressRange inline_range;
2708                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
2709                                                     func_addr = inline_range.GetBaseAddress();
2710                                             }
2711                                         }
2712                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2713                                             func_addr = sc->symbol->GetAddress();
2714                                     }
2715                                     
2716                                     if (func_addr.IsValid())
2717                                     {
2718                                         const char *addr_offset_padding  =  " ";
2719                                         if (addr_offset_print_with_no_padding)
2720                                         {
2721                                             addr_offset_padding = "";
2722                                         }
2723                                         if (func_addr.GetSection() == format_addr.GetSection())
2724                                         {
2725                                             addr_t func_file_addr = func_addr.GetFileAddress();
2726                                             addr_t addr_file_addr = format_addr.GetFileAddress();
2727                                             if (addr_file_addr > func_file_addr)
2728                                                 s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
2729                                             else if (addr_file_addr < func_file_addr)
2730                                                 s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
2731                                             var_success = true;
2732                                         }
2733                                         else
2734                                         {
2735                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2736                                             if (target)
2737                                             {
2738                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
2739                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
2740                                                 if (addr_load_addr > func_load_addr)
2741                                                     s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
2742                                                 else if (addr_load_addr < func_load_addr)
2743                                                     s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
2744                                                 var_success = true;
2745                                             }
2746                                         }
2747                                     }
2748                                 }
2749                                 else
2750                                 {
2751                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2752                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
2753                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
2754                                         vaddr = format_addr.GetLoadAddress (target);
2755                                     if (vaddr == LLDB_INVALID_ADDRESS)
2756                                         vaddr = format_addr.GetFileAddress ();
2757
2758                                     if (vaddr != LLDB_INVALID_ADDRESS)
2759                                     {
2760                                         int addr_width = 0;
2761                                         if (exe_ctx && target)
2762                                         {
2763                                             addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2764                                         }
2765                                         if (addr_width == 0)
2766                                             addr_width = 16;
2767                                         if (print_file_addr_or_load_addr)
2768                                         {
2769                                             format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
2770                                         }
2771                                         else
2772                                         {
2773                                             s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
2774                                         }
2775                                         var_success = true;
2776                                     }
2777                                 }
2778                             }
2779                         }
2780
2781                         if (var_success == false)
2782                             success = false;
2783                     }
2784                     p = var_name_end;
2785                 }
2786                 else
2787                     break;
2788             }
2789             else
2790             {
2791                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
2792                 s.PutChar(*p);
2793             }
2794         }
2795         else if (*p == '\\')
2796         {
2797             ++p; // skip the slash
2798             switch (*p)
2799             {
2800             case 'a': s.PutChar ('\a'); break;
2801             case 'b': s.PutChar ('\b'); break;
2802             case 'f': s.PutChar ('\f'); break;
2803             case 'n': s.PutChar ('\n'); break;
2804             case 'r': s.PutChar ('\r'); break;
2805             case 't': s.PutChar ('\t'); break;
2806             case 'v': s.PutChar ('\v'); break;
2807             case '\'': s.PutChar ('\''); break; 
2808             case '\\': s.PutChar ('\\'); break; 
2809             case '0':
2810                 // 1 to 3 octal chars
2811                 {
2812                     // Make a string that can hold onto the initial zero char,
2813                     // up to 3 octal digits, and a terminating NULL.
2814                     char oct_str[5] = { 0, 0, 0, 0, 0 };
2815
2816                     int i;
2817                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2818                         oct_str[i] = p[i];
2819
2820                     // We don't want to consume the last octal character since
2821                     // the main for loop will do this for us, so we advance p by
2822                     // one less than i (even if i is zero)
2823                     p += i - 1;
2824                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2825                     if (octal_value <= UINT8_MAX)
2826                     {
2827                         s.PutChar((char)octal_value);
2828                     }
2829                 }
2830                 break;
2831
2832             case 'x':
2833                 // hex number in the format 
2834                 if (isxdigit(p[1]))
2835                 {
2836                     ++p;    // Skip the 'x'
2837
2838                     // Make a string that can hold onto two hex chars plus a
2839                     // NULL terminator
2840                     char hex_str[3] = { 0,0,0 };
2841                     hex_str[0] = *p;
2842                     if (isxdigit(p[1]))
2843                     {
2844                         ++p; // Skip the first of the two hex chars
2845                         hex_str[1] = *p;
2846                     }
2847
2848                     unsigned long hex_value = strtoul (hex_str, NULL, 16);                    
2849                     if (hex_value <= UINT8_MAX)
2850                         s.PutChar ((char)hex_value);
2851                 }
2852                 else
2853                 {
2854                     s.PutChar('x');
2855                 }
2856                 break;
2857                 
2858             default:
2859                 // Just desensitize any other character by just printing what
2860                 // came after the '\'
2861                 s << *p;
2862                 break;
2863             
2864             }
2865
2866         }
2867     }
2868     if (end) 
2869         *end = p;
2870     return success;
2871 }
2872
2873 bool
2874 Debugger::FormatPrompt
2875 (
2876     const char *format,
2877     const SymbolContext *sc,
2878     const ExecutionContext *exe_ctx,
2879     const Address *addr,
2880     Stream &s,
2881     ValueObject* valobj
2882 )
2883 {
2884     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2885     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2886     if (format_str.length())
2887         format = format_str.c_str();
2888     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false);
2889 }
2890
2891 bool
2892 Debugger::FormatDisassemblerAddress (const char *format,
2893                                      const SymbolContext *sc,
2894                                      const SymbolContext *prev_sc,
2895                                      const ExecutionContext *exe_ctx,
2896                                      const Address *addr,
2897                                      Stream &s)
2898 {
2899     if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope())
2900     {
2901         format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
2902     }
2903     bool function_changed = false;
2904     bool initial_function = false;
2905     if (prev_sc && (prev_sc->function || prev_sc->symbol))
2906     {
2907         if (sc && (sc->function || sc->symbol))
2908         {
2909             if (prev_sc->symbol && sc->symbol)
2910             {
2911                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
2912                 {
2913                     function_changed = true;
2914                 }
2915             }
2916             else if (prev_sc->function && sc->function)
2917             {
2918                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
2919                 {
2920                     function_changed = true;
2921                 }
2922             }
2923         }
2924     }
2925     // The first context on a list of instructions will have a prev_sc that
2926     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
2927     // would return false.  But we do get a prev_sc pointer.
2928     if ((sc && (sc->function || sc->symbol))
2929         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
2930     {
2931         initial_function = true;
2932     }
2933     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function);
2934 }
2935
2936
2937 void
2938 Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2939 {
2940     // For simplicity's sake, I am not going to deal with how to close down any
2941     // open logging streams, I just redirect everything from here on out to the
2942     // callback.
2943     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2944 }
2945
2946 bool
2947 Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2948 {
2949     Log::Callbacks log_callbacks;
2950
2951     StreamSP log_stream_sp;
2952     if (m_log_callback_stream_sp)
2953     {
2954         log_stream_sp = m_log_callback_stream_sp;
2955         // For now when using the callback mode you always get thread & timestamp.
2956         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2957     }
2958     else if (log_file == NULL || *log_file == '\0')
2959     {
2960         log_stream_sp = GetOutputFile();
2961     }
2962     else
2963     {
2964         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2965         if (pos != m_log_streams.end())
2966             log_stream_sp = pos->second.lock();
2967         if (!log_stream_sp)
2968         {
2969             log_stream_sp.reset (new StreamFile (log_file));
2970             m_log_streams[log_file] = log_stream_sp;
2971         }
2972     }
2973     assert (log_stream_sp.get());
2974     
2975     if (log_options == 0)
2976         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2977         
2978     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2979     {
2980         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2981         return true;
2982     }
2983     else
2984     {
2985         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2986         if (log_channel_sp)
2987         {
2988             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2989             {
2990                 return true;
2991             }
2992             else
2993             {
2994                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2995                 return false;
2996             }
2997         }
2998         else
2999         {
3000             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
3001             return false;
3002         }
3003     }
3004     return false;
3005 }
3006
3007 SourceManager &
3008 Debugger::GetSourceManager ()
3009 {
3010     if (m_source_manager_ap.get() == NULL)
3011         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
3012     return *m_source_manager_ap;
3013 }
3014
3015
3016
3017 // This function handles events that were broadcast by the process.
3018 void
3019 Debugger::HandleBreakpointEvent (const EventSP &event_sp)
3020 {
3021     using namespace lldb;
3022     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
3023     
3024 //    if (event_type & eBreakpointEventTypeAdded
3025 //        || event_type & eBreakpointEventTypeRemoved
3026 //        || event_type & eBreakpointEventTypeEnabled
3027 //        || event_type & eBreakpointEventTypeDisabled
3028 //        || event_type & eBreakpointEventTypeCommandChanged
3029 //        || event_type & eBreakpointEventTypeConditionChanged
3030 //        || event_type & eBreakpointEventTypeIgnoreChanged
3031 //        || event_type & eBreakpointEventTypeLocationsResolved)
3032 //    {
3033 //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
3034 //    }
3035 //    
3036     if (event_type & eBreakpointEventTypeLocationsAdded)
3037     {
3038         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
3039         if (num_new_locations > 0)
3040         {
3041             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
3042             StreamFileSP output_sp (GetOutputFile());
3043             if (output_sp)
3044             {
3045                 output_sp->Printf("%d location%s added to breakpoint %d\n",
3046                                   num_new_locations,
3047                                   num_new_locations == 1 ? "" : "s",
3048                                   breakpoint->GetID());
3049                 RefreshTopIOHandler();
3050             }
3051         }
3052     }
3053 //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
3054 //    {
3055 //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
3056 //    }
3057 //    else if (event_type & eBreakpointEventTypeLocationsResolved)
3058 //    {
3059 //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
3060 //    }
3061 }
3062
3063 size_t
3064 Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
3065 {
3066     size_t total_bytes = 0;
3067     if (stream == NULL)
3068         stream = GetOutputFile().get();
3069
3070     if (stream)
3071     {
3072         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
3073         if (process == NULL)
3074         {
3075             TargetSP target_sp = GetTargetList().GetSelectedTarget();
3076             if (target_sp)
3077                 process = target_sp->GetProcessSP().get();
3078         }
3079         if (process)
3080         {
3081             Error error;
3082             size_t len;
3083             char stdio_buffer[1024];
3084             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
3085             {
3086                 stream->Write(stdio_buffer, len);
3087                 total_bytes += len;
3088             }
3089         }
3090         stream->Flush();
3091     }
3092     return total_bytes;
3093 }
3094
3095 size_t
3096 Debugger::GetProcessSTDERR (Process *process, Stream *stream)
3097 {
3098     size_t total_bytes = 0;
3099     if (stream == NULL)
3100         stream = GetOutputFile().get();
3101     
3102     if (stream)
3103     {
3104         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
3105         if (process == NULL)
3106         {
3107             TargetSP target_sp = GetTargetList().GetSelectedTarget();
3108             if (target_sp)
3109                 process = target_sp->GetProcessSP().get();
3110         }
3111         if (process)
3112         {
3113             Error error;
3114             size_t len;
3115             char stdio_buffer[1024];
3116             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
3117             {
3118                 stream->Write(stdio_buffer, len);
3119                 total_bytes += len;
3120             }
3121         }
3122         stream->Flush();
3123     }
3124     return total_bytes;
3125 }
3126
3127
3128 // This function handles events that were broadcast by the process.
3129 void
3130 Debugger::HandleProcessEvent (const EventSP &event_sp)
3131 {
3132     using namespace lldb;
3133     const uint32_t event_type = event_sp->GetType();
3134     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
3135
3136     StreamString output_stream;
3137     StreamString error_stream;
3138     const bool gui_enabled = IsForwardingEvents();
3139
3140     if (!gui_enabled)
3141     {
3142         bool pop_process_io_handler = false;
3143         assert (process_sp);
3144
3145         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
3146         {
3147             GetProcessSTDOUT (process_sp.get(), &output_stream);
3148         }
3149
3150         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
3151         {
3152             GetProcessSTDERR (process_sp.get(), &error_stream);
3153         }
3154
3155         if (event_type & Process::eBroadcastBitStateChanged)
3156         {
3157             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
3158         }
3159
3160         if (output_stream.GetSize() || error_stream.GetSize())
3161         {
3162             StreamFileSP error_stream_sp (GetOutputFile());
3163             bool top_io_handler_hid = false;
3164
3165             if (process_sp->ProcessIOHandlerIsActive() == false)
3166                 top_io_handler_hid = HideTopIOHandler();
3167
3168             if (output_stream.GetSize())
3169             {
3170                 StreamFileSP output_stream_sp (GetOutputFile());
3171                 if (output_stream_sp)
3172                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
3173             }
3174
3175             if (error_stream.GetSize())
3176             {
3177                 StreamFileSP error_stream_sp (GetErrorFile());
3178                 if (error_stream_sp)
3179                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
3180             }
3181
3182             if (top_io_handler_hid)
3183                 RefreshTopIOHandler();
3184         }
3185
3186         if (pop_process_io_handler)
3187             process_sp->PopProcessIOHandler();
3188     }
3189 }
3190
3191 void
3192 Debugger::HandleThreadEvent (const EventSP &event_sp)
3193 {
3194     // At present the only thread event we handle is the Frame Changed event,
3195     // and all we do for that is just reprint the thread status for that thread.
3196     using namespace lldb;
3197     const uint32_t event_type = event_sp->GetType();
3198     if (event_type == Thread::eBroadcastBitStackChanged   ||
3199         event_type == Thread::eBroadcastBitThreadSelected )
3200     {
3201         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
3202         if (thread_sp)
3203         {
3204             HideTopIOHandler();
3205             StreamFileSP stream_sp (GetOutputFile());
3206             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
3207             RefreshTopIOHandler();
3208         }
3209     }
3210 }
3211
3212 bool
3213 Debugger::IsForwardingEvents ()
3214 {
3215     return (bool)m_forward_listener_sp;
3216 }
3217
3218 void
3219 Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
3220 {
3221     m_forward_listener_sp = listener_sp;
3222 }
3223
3224 void
3225 Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
3226 {
3227     m_forward_listener_sp.reset();
3228 }
3229
3230
3231 void
3232 Debugger::DefaultEventHandler()
3233 {
3234     Listener& listener(GetListener());
3235     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
3236     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
3237     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
3238     BroadcastEventSpec target_event_spec (broadcaster_class_target,
3239                                           Target::eBroadcastBitBreakpointChanged);
3240
3241     BroadcastEventSpec process_event_spec (broadcaster_class_process,
3242                                            Process::eBroadcastBitStateChanged   |
3243                                            Process::eBroadcastBitSTDOUT         |
3244                                            Process::eBroadcastBitSTDERR);
3245
3246     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
3247                                           Thread::eBroadcastBitStackChanged     |
3248                                           Thread::eBroadcastBitThreadSelected   );
3249     
3250     listener.StartListeningForEventSpec (*this, target_event_spec);
3251     listener.StartListeningForEventSpec (*this, process_event_spec);
3252     listener.StartListeningForEventSpec (*this, thread_event_spec);
3253     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
3254                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
3255                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
3256                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
3257
3258     // Let the thread that spawned us know that we have started up and
3259     // that we are now listening to all required events so no events get missed
3260     m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
3261
3262     bool done = false;
3263     while (!done)
3264     {
3265         EventSP event_sp;
3266         if (listener.WaitForEvent(NULL, event_sp))
3267         {
3268             if (event_sp)
3269             {
3270                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
3271                 if (broadcaster)
3272                 {
3273                     uint32_t event_type = event_sp->GetType();
3274                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
3275                     if (broadcaster_class == broadcaster_class_process)
3276                     {
3277                         HandleProcessEvent (event_sp);
3278                     }
3279                     else if (broadcaster_class == broadcaster_class_target)
3280                     {
3281                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
3282                         {
3283                             HandleBreakpointEvent (event_sp);
3284                         }
3285                     }
3286                     else if (broadcaster_class == broadcaster_class_thread)
3287                     {
3288                         HandleThreadEvent (event_sp);
3289                     }
3290                     else if (broadcaster == m_command_interpreter_ap.get())
3291                     {
3292                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
3293                         {
3294                             done = true;
3295                         }
3296                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
3297                         {
3298                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
3299                             if (data && data[0])
3300                             {
3301                                 StreamFileSP error_sp (GetErrorFile());
3302                                 if (error_sp)
3303                                 {
3304                                     HideTopIOHandler();
3305                                     error_sp->PutCString(data);
3306                                     error_sp->Flush();
3307                                     RefreshTopIOHandler();
3308                                 }
3309                             }
3310                         }
3311                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
3312                         {
3313                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
3314                             if (data && data[0])
3315                             {
3316                                 StreamFileSP output_sp (GetOutputFile());
3317                                 if (output_sp)
3318                                 {
3319                                     HideTopIOHandler();
3320                                     output_sp->PutCString(data);
3321                                     output_sp->Flush();
3322                                     RefreshTopIOHandler();
3323                                 }
3324                             }
3325                         }
3326                     }
3327                 }
3328                 
3329                 if (m_forward_listener_sp)
3330                     m_forward_listener_sp->AddEvent(event_sp);
3331             }
3332         }
3333     }
3334 }
3335
3336 lldb::thread_result_t
3337 Debugger::EventHandlerThread (lldb::thread_arg_t arg)
3338 {
3339     ((Debugger *)arg)->DefaultEventHandler();
3340     return NULL;
3341 }
3342
3343 bool
3344 Debugger::StartEventHandlerThread()
3345 {
3346     if (!m_event_handler_thread.IsJoinable())
3347     {
3348         // We must synchronize with the DefaultEventHandler() thread to ensure
3349         // it is up and running and listening to events before we return from
3350         // this function. We do this by listening to events for the
3351         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
3352         Listener listener("lldb.debugger.event-handler");
3353         listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
3354
3355         // Use larger 8MB stack for this thread
3356         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
3357                                                               this,
3358                                                               NULL,
3359                                                               g_debugger_event_thread_stack_bytes);
3360
3361         // Make sure DefaultEventHandler() is running and listening to events before we return
3362         // from this function. We are only listening for events of type
3363         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
3364         // to wait an infinite amount of time for it (NULL timeout as the first parameter)
3365         lldb::EventSP event_sp;
3366         listener.WaitForEvent(NULL, event_sp);
3367     }
3368     return m_event_handler_thread.IsJoinable();
3369 }
3370
3371 void
3372 Debugger::StopEventHandlerThread()
3373 {
3374     if (m_event_handler_thread.IsJoinable())
3375     {
3376         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
3377         m_event_handler_thread.Join(nullptr);
3378     }
3379 }
3380
3381
3382 lldb::thread_result_t
3383 Debugger::IOHandlerThread (lldb::thread_arg_t arg)
3384 {
3385     Debugger *debugger = (Debugger *)arg;
3386     debugger->ExecuteIOHanders();
3387     debugger->StopEventHandlerThread();
3388     return NULL;
3389 }
3390
3391 bool
3392 Debugger::StartIOHandlerThread()
3393 {
3394     if (!m_io_handler_thread.IsJoinable())
3395         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
3396                                                             IOHandlerThread,
3397                                                             this,
3398                                                             NULL,
3399                                                             8*1024*1024); // Use larger 8MB stack for this thread
3400     return m_io_handler_thread.IsJoinable();
3401 }
3402
3403 void
3404 Debugger::StopIOHandlerThread()
3405 {
3406     if (m_io_handler_thread.IsJoinable())
3407     {
3408         if (m_input_file_sp)
3409             m_input_file_sp->GetFile().Close();
3410         m_io_handler_thread.Join(nullptr);
3411     }
3412 }
3413
3414 Target *
3415 Debugger::GetDummyTarget()
3416 {
3417     return m_target_list.GetDummyTarget (*this).get();
3418 }
3419
3420 Target *
3421 Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
3422 {
3423     Target *target = nullptr;
3424     if (!prefer_dummy)
3425     {
3426         target = m_target_list.GetSelectedTarget().get();
3427         if (target)
3428             return target;
3429     }
3430     
3431     return GetDummyTarget();
3432 }
3433