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