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/Core/Debugger.h"
11 
12 #include <map>
13 
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/Type.h"
16 
17 #include "lldb/lldb-private.h"
18 #include "lldb/Core/ConnectionFileDescriptor.h"
19 #include "lldb/Core/DataVisualization.h"
20 #include "lldb/Core/FormatManager.h"
21 #include "lldb/Core/InputReader.h"
22 #include "lldb/Core/RegisterValue.h"
23 #include "lldb/Core/State.h"
24 #include "lldb/Core/StreamAsynchronousIO.h"
25 #include "lldb/Core/StreamCallback.h"
26 #include "lldb/Core/StreamString.h"
27 #include "lldb/Core/Timer.h"
28 #include "lldb/Core/ValueObject.h"
29 #include "lldb/Core/ValueObjectVariable.h"
30 #include "lldb/Host/Terminal.h"
31 #include "lldb/Interpreter/CommandInterpreter.h"
32 #include "lldb/Interpreter/OptionValueSInt64.h"
33 #include "lldb/Interpreter/OptionValueString.h"
34 #include "lldb/Symbol/VariableList.h"
35 #include "lldb/Target/TargetList.h"
36 #include "lldb/Target/Process.h"
37 #include "lldb/Target/RegisterContext.h"
38 #include "lldb/Target/StopInfo.h"
39 #include "lldb/Target/Thread.h"
40 #include "lldb/Utility/AnsiTerminal.h"
41 
42 using namespace lldb;
43 using namespace lldb_private;
44 
45 
46 static uint32_t g_shared_debugger_refcount = 0;
47 static lldb::user_id_t g_unique_id = 1;
48 
49 #pragma mark Static Functions
50 
51 static Mutex &
52 GetDebuggerListMutex ()
53 {
54     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
55     return g_mutex;
56 }
57 
58 typedef std::vector<DebuggerSP> DebuggerList;
59 
60 static DebuggerList &
61 GetDebuggerList()
62 {
63     // hide the static debugger list inside a singleton accessor to avoid
64     // global init contructors
65     static DebuggerList g_list;
66     return g_list;
67 }
68 
69 OptionEnumValueElement
70 g_show_disassembly_enum_values[] =
71 {
72     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
73     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
74     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
75     { 0, NULL, NULL }
76 };
77 
78 OptionEnumValueElement
79 g_language_enumerators[] =
80 {
81     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
82     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
83     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
84 };
85 
86 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
87 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
88 
89 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
90     "{, ${frame.pc}}"\
91     MODULE_WITH_FUNC\
92     FILE_AND_LINE\
93     "{, stop reason = ${thread.stop-reason}}"\
94     "{\\nReturn value: ${thread.return-value}}"\
95     "\\n"
96 
97 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
98     MODULE_WITH_FUNC\
99     FILE_AND_LINE\
100     "\\n"
101 
102 
103 
104 PropertyDefinition
105 g_instance_settings_table[] =
106 {
107 {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
108 {   "frame-format",             OptionValue::eTypeString , true, 0    , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
109 {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
110 {   "prompt",                   OptionValue::eTypeString , true, 0    , "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
111 {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
112 {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
113 {   "stop-disassembly-display", OptionValue::eTypeEnum   , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
114 {   "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." },
115 {   "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." },
116 {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
117 {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
118 {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
119 {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
120 };
121 
122 enum
123 {
124     ePropertyAutoConfirm = 0,
125     ePropertyFrameFormat,
126     ePropertyNotiftVoid,
127     ePropertyPrompt,
128     ePropertyScriptLanguage,
129     ePropertyStopDisassemblyCount,
130     ePropertyStopDisassemblyDisplay,
131     ePropertyStopLineCountAfter,
132     ePropertyStopLineCountBefore,
133     ePropertyTerminalWidth,
134     ePropertyThreadFormat,
135     ePropertyUseExternalEditor
136 };
137 
138 //
139 //const char *
140 //Debugger::GetFrameFormat() const
141 //{
142 //    return m_properties_sp->GetFrameFormat();
143 //}
144 //const char *
145 //Debugger::GetThreadFormat() const
146 //{
147 //    return m_properties_sp->GetThreadFormat();
148 //}
149 //
150 bool
151 Debugger::GetAutoConfirm () const
152 {
153     const uint32_t idx = ePropertyAutoConfirm;
154     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_instance_settings_table[idx].default_uint_value != 0);
155 }
156 
157 const char *
158 Debugger::GetFrameFormat() const
159 {
160     const uint32_t idx = ePropertyFrameFormat;
161     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_instance_settings_table[idx].default_cstr_value);
162 }
163 
164 bool
165 Debugger::GetNotifyVoid () const
166 {
167     const uint32_t idx = ePropertyNotiftVoid;
168     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_instance_settings_table[idx].default_uint_value != 0);
169 }
170 
171 const char *
172 Debugger::GetPrompt() const
173 {
174     const uint32_t idx = ePropertyPrompt;
175     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_instance_settings_table[idx].default_cstr_value);
176 }
177 
178 void
179 Debugger::SetPrompt(const char *p)
180 {
181     const uint32_t idx = ePropertyPrompt;
182     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
183     const char *new_prompt = GetPrompt();
184     EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
185     GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
186 }
187 
188 const char *
189 Debugger::GetThreadFormat() const
190 {
191     const uint32_t idx = ePropertyThreadFormat;
192     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_instance_settings_table[idx].default_cstr_value);
193 }
194 
195 lldb::ScriptLanguage
196 Debugger::GetScriptLanguage() const
197 {
198     const uint32_t idx = ePropertyScriptLanguage;
199     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_instance_settings_table[idx].default_uint_value);
200 }
201 
202 bool
203 Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
204 {
205     const uint32_t idx = ePropertyScriptLanguage;
206     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
207 }
208 
209 uint32_t
210 Debugger::GetTerminalWidth () const
211 {
212     const uint32_t idx = ePropertyTerminalWidth;
213     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_instance_settings_table[idx].default_uint_value);
214 }
215 
216 bool
217 Debugger::SetTerminalWidth (uint32_t term_width)
218 {
219     const uint32_t idx = ePropertyTerminalWidth;
220     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
221 }
222 
223 bool
224 Debugger::GetUseExternalEditor () const
225 {
226     const uint32_t idx = ePropertyUseExternalEditor;
227     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_instance_settings_table[idx].default_uint_value != 0);
228 }
229 
230 bool
231 Debugger::SetUseExternalEditor (bool b)
232 {
233     const uint32_t idx = ePropertyUseExternalEditor;
234     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
235 }
236 
237 uint32_t
238 Debugger::GetStopSourceLineCount (bool before) const
239 {
240     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
241     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_instance_settings_table[idx].default_uint_value);
242 }
243 
244 Debugger::StopDisassemblyType
245 Debugger::GetStopDisassemblyDisplay () const
246 {
247     const uint32_t idx = ePropertyStopDisassemblyDisplay;
248     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_instance_settings_table[idx].default_uint_value);
249 }
250 
251 uint32_t
252 Debugger::GetDisassemblyLineCount () const
253 {
254     const uint32_t idx = ePropertyStopDisassemblyCount;
255     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_instance_settings_table[idx].default_uint_value);
256 }
257 
258 #pragma mark Debugger
259 
260 //const DebuggerPropertiesSP &
261 //Debugger::GetSettings() const
262 //{
263 //    return m_properties_sp;
264 //}
265 //
266 
267 int
268 Debugger::TestDebuggerRefCount ()
269 {
270     return g_shared_debugger_refcount;
271 }
272 
273 void
274 Debugger::Initialize ()
275 {
276     if (g_shared_debugger_refcount++ == 0)
277         lldb_private::Initialize();
278 }
279 
280 void
281 Debugger::Terminate ()
282 {
283     if (g_shared_debugger_refcount > 0)
284     {
285         g_shared_debugger_refcount--;
286         if (g_shared_debugger_refcount == 0)
287         {
288             lldb_private::WillTerminate();
289             lldb_private::Terminate();
290 
291             // Clear our master list of debugger objects
292             Mutex::Locker locker (GetDebuggerListMutex ());
293             GetDebuggerList().clear();
294         }
295     }
296 }
297 
298 void
299 Debugger::SettingsInitialize ()
300 {
301     Target::SettingsInitialize ();
302 }
303 
304 void
305 Debugger::SettingsTerminate ()
306 {
307     Target::SettingsTerminate ();
308 }
309 
310 DebuggerSP
311 Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
312 {
313     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
314     if (g_shared_debugger_refcount > 0)
315     {
316         Mutex::Locker locker (GetDebuggerListMutex ());
317         GetDebuggerList().push_back(debugger_sp);
318     }
319     return debugger_sp;
320 }
321 
322 void
323 Debugger::Destroy (DebuggerSP &debugger_sp)
324 {
325     if (debugger_sp.get() == NULL)
326         return;
327 
328     debugger_sp->Clear();
329 
330     if (g_shared_debugger_refcount > 0)
331     {
332         Mutex::Locker locker (GetDebuggerListMutex ());
333         DebuggerList &debugger_list = GetDebuggerList ();
334         DebuggerList::iterator pos, end = debugger_list.end();
335         for (pos = debugger_list.begin (); pos != end; ++pos)
336         {
337             if ((*pos).get() == debugger_sp.get())
338             {
339                 debugger_list.erase (pos);
340                 return;
341             }
342         }
343     }
344 }
345 
346 DebuggerSP
347 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
348 {
349     DebuggerSP debugger_sp;
350     if (g_shared_debugger_refcount > 0)
351     {
352         Mutex::Locker locker (GetDebuggerListMutex ());
353         DebuggerList &debugger_list = GetDebuggerList();
354         DebuggerList::iterator pos, end = debugger_list.end();
355 
356         for (pos = debugger_list.begin(); pos != end; ++pos)
357         {
358             if ((*pos).get()->m_instance_name == instance_name)
359             {
360                 debugger_sp = *pos;
361                 break;
362             }
363         }
364     }
365     return debugger_sp;
366 }
367 
368 TargetSP
369 Debugger::FindTargetWithProcessID (lldb::pid_t pid)
370 {
371     TargetSP target_sp;
372     if (g_shared_debugger_refcount > 0)
373     {
374         Mutex::Locker locker (GetDebuggerListMutex ());
375         DebuggerList &debugger_list = GetDebuggerList();
376         DebuggerList::iterator pos, end = debugger_list.end();
377         for (pos = debugger_list.begin(); pos != end; ++pos)
378         {
379             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
380             if (target_sp)
381                 break;
382         }
383     }
384     return target_sp;
385 }
386 
387 TargetSP
388 Debugger::FindTargetWithProcess (Process *process)
389 {
390     TargetSP target_sp;
391     if (g_shared_debugger_refcount > 0)
392     {
393         Mutex::Locker locker (GetDebuggerListMutex ());
394         DebuggerList &debugger_list = GetDebuggerList();
395         DebuggerList::iterator pos, end = debugger_list.end();
396         for (pos = debugger_list.begin(); pos != end; ++pos)
397         {
398             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
399             if (target_sp)
400                 break;
401         }
402     }
403     return target_sp;
404 }
405 
406 Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
407     UserID (g_unique_id++),
408     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
409     m_input_comm("debugger.input"),
410     m_input_file (),
411     m_output_file (),
412     m_error_file (),
413     m_target_list (*this),
414     m_platform_list (),
415     m_listener ("lldb.Debugger"),
416     m_source_manager(*this),
417     m_source_file_cache(),
418     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
419     m_input_reader_stack (),
420     m_input_reader_data (),
421     m_instance_name()
422 {
423     char instance_cstr[256];
424     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
425     m_instance_name.SetCString(instance_cstr);
426     if (log_callback)
427         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
428     m_command_interpreter_ap->Initialize ();
429     // Always add our default platform to the platform list
430     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
431     assert (default_platform_sp.get());
432     m_platform_list.Append (default_platform_sp, true);
433 
434     m_collection_sp->Initialize (g_instance_settings_table);
435     m_collection_sp->AppendProperty (ConstString("target"),
436                                      ConstString("Settings specify to debugging targets."),
437                                      true,
438                                      Target::GetGlobalProperties()->GetValueProperties());
439     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
440     term_width->SetMinimumValue(10);
441     term_width->SetMaximumValue(1024);
442 }
443 
444 Debugger::~Debugger ()
445 {
446     Clear();
447 }
448 
449 void
450 Debugger::Clear()
451 {
452     CleanUpInputReaders();
453     m_listener.Clear();
454     int num_targets = m_target_list.GetNumTargets();
455     for (int i = 0; i < num_targets; i++)
456     {
457         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
458         if (target_sp)
459         {
460             ProcessSP process_sp (target_sp->GetProcessSP());
461             if (process_sp)
462             {
463                 if (process_sp->GetShouldDetach())
464                     process_sp->Detach();
465             }
466             target_sp->Destroy();
467         }
468     }
469     BroadcasterManager::Clear ();
470 
471     // Close the input file _before_ we close the input read communications class
472     // as it does NOT own the input file, our m_input_file does.
473     GetInputFile().Close ();
474     // Now that we have closed m_input_file, we can now tell our input communication
475     // class to close down. Its read thread should quickly exit after we close
476     // the input file handle above.
477     m_input_comm.Clear ();
478 }
479 
480 bool
481 Debugger::GetCloseInputOnEOF () const
482 {
483     return m_input_comm.GetCloseOnEOF();
484 }
485 
486 void
487 Debugger::SetCloseInputOnEOF (bool b)
488 {
489     m_input_comm.SetCloseOnEOF(b);
490 }
491 
492 bool
493 Debugger::GetAsyncExecution ()
494 {
495     return !m_command_interpreter_ap->GetSynchronous();
496 }
497 
498 void
499 Debugger::SetAsyncExecution (bool async_execution)
500 {
501     m_command_interpreter_ap->SetSynchronous (!async_execution);
502 }
503 
504 
505 void
506 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
507 {
508     File &in_file = GetInputFile();
509     in_file.SetStream (fh, tranfer_ownership);
510     if (in_file.IsValid() == false)
511         in_file.SetStream (stdin, true);
512 
513     // Disconnect from any old connection if we had one
514     m_input_comm.Disconnect ();
515     // Pass false as the second argument to ConnectionFileDescriptor below because
516     // our "in_file" above will already take ownership if requested and we don't
517     // want to objects trying to own and close a file descriptor.
518     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
519     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
520 
521     Error error;
522     if (m_input_comm.StartReadThread (&error) == false)
523     {
524         File &err_file = GetErrorFile();
525 
526         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
527         exit(1);
528     }
529 }
530 
531 void
532 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
533 {
534     File &out_file = GetOutputFile();
535     out_file.SetStream (fh, tranfer_ownership);
536     if (out_file.IsValid() == false)
537         out_file.SetStream (stdout, false);
538 
539     GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
540 }
541 
542 void
543 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
544 {
545     File &err_file = GetErrorFile();
546     err_file.SetStream (fh, tranfer_ownership);
547     if (err_file.IsValid() == false)
548         err_file.SetStream (stderr, false);
549 }
550 
551 ExecutionContext
552 Debugger::GetSelectedExecutionContext ()
553 {
554     ExecutionContext exe_ctx;
555     TargetSP target_sp(GetSelectedTarget());
556     exe_ctx.SetTargetSP (target_sp);
557 
558     if (target_sp)
559     {
560         ProcessSP process_sp (target_sp->GetProcessSP());
561         exe_ctx.SetProcessSP (process_sp);
562         if (process_sp && process_sp->IsRunning() == false)
563         {
564             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
565             if (thread_sp)
566             {
567                 exe_ctx.SetThreadSP (thread_sp);
568                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
569                 if (exe_ctx.GetFramePtr() == NULL)
570                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
571             }
572         }
573     }
574     return exe_ctx;
575 
576 }
577 
578 InputReaderSP
579 Debugger::GetCurrentInputReader ()
580 {
581     InputReaderSP reader_sp;
582 
583     if (!m_input_reader_stack.IsEmpty())
584     {
585         // Clear any finished readers from the stack
586         while (CheckIfTopInputReaderIsDone()) ;
587 
588         if (!m_input_reader_stack.IsEmpty())
589             reader_sp = m_input_reader_stack.Top();
590     }
591 
592     return reader_sp;
593 }
594 
595 void
596 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
597 {
598     if (bytes_len > 0)
599         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
600     else
601         ((Debugger *)baton)->DispatchInputEndOfFile ();
602 }
603 
604 
605 void
606 Debugger::DispatchInput (const char *bytes, size_t bytes_len)
607 {
608     if (bytes == NULL || bytes_len == 0)
609         return;
610 
611     WriteToDefaultReader (bytes, bytes_len);
612 }
613 
614 void
615 Debugger::DispatchInputInterrupt ()
616 {
617     m_input_reader_data.clear();
618 
619     InputReaderSP reader_sp (GetCurrentInputReader ());
620     if (reader_sp)
621     {
622         reader_sp->Notify (eInputReaderInterrupt);
623 
624         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
625         while (CheckIfTopInputReaderIsDone ()) ;
626     }
627 }
628 
629 void
630 Debugger::DispatchInputEndOfFile ()
631 {
632     m_input_reader_data.clear();
633 
634     InputReaderSP reader_sp (GetCurrentInputReader ());
635     if (reader_sp)
636     {
637         reader_sp->Notify (eInputReaderEndOfFile);
638 
639         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
640         while (CheckIfTopInputReaderIsDone ()) ;
641     }
642 }
643 
644 void
645 Debugger::CleanUpInputReaders ()
646 {
647     m_input_reader_data.clear();
648 
649     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
650     while (m_input_reader_stack.GetSize() > 1)
651     {
652         InputReaderSP reader_sp (GetCurrentInputReader ());
653         if (reader_sp)
654         {
655             reader_sp->Notify (eInputReaderEndOfFile);
656             reader_sp->SetIsDone (true);
657         }
658     }
659 }
660 
661 void
662 Debugger::NotifyTopInputReader (InputReaderAction notification)
663 {
664     InputReaderSP reader_sp (GetCurrentInputReader());
665     if (reader_sp)
666 	{
667         reader_sp->Notify (notification);
668 
669         // Flush out any input readers that are done.
670         while (CheckIfTopInputReaderIsDone ())
671             /* Do nothing. */;
672     }
673 }
674 
675 bool
676 Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
677 {
678     InputReaderSP top_reader_sp (GetCurrentInputReader());
679 
680     return (reader_sp.get() == top_reader_sp.get());
681 }
682 
683 
684 void
685 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
686 {
687     if (bytes && bytes_len)
688         m_input_reader_data.append (bytes, bytes_len);
689 
690     if (m_input_reader_data.empty())
691         return;
692 
693     while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
694     {
695         // Get the input reader from the top of the stack
696         InputReaderSP reader_sp (GetCurrentInputReader ());
697         if (!reader_sp)
698             break;
699 
700         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
701                                                           m_input_reader_data.size());
702         if (bytes_handled)
703         {
704             m_input_reader_data.erase (0, bytes_handled);
705         }
706         else
707         {
708             // No bytes were handled, we might not have reached our
709             // granularity, just return and wait for more data
710             break;
711         }
712     }
713 
714     // Flush out any input readers that are done.
715     while (CheckIfTopInputReaderIsDone ())
716         /* Do nothing. */;
717 
718 }
719 
720 void
721 Debugger::PushInputReader (const InputReaderSP& reader_sp)
722 {
723     if (!reader_sp)
724         return;
725 
726     // Deactivate the old top reader
727     InputReaderSP top_reader_sp (GetCurrentInputReader ());
728 
729     if (top_reader_sp)
730         top_reader_sp->Notify (eInputReaderDeactivate);
731 
732     m_input_reader_stack.Push (reader_sp);
733     reader_sp->Notify (eInputReaderActivate);
734     ActivateInputReader (reader_sp);
735 }
736 
737 bool
738 Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
739 {
740     bool result = false;
741 
742     // The reader on the stop of the stack is done, so let the next
743     // read on the stack referesh its prompt and if there is one...
744     if (!m_input_reader_stack.IsEmpty())
745     {
746         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
747         InputReaderSP reader_sp(m_input_reader_stack.Top());
748 
749         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
750         {
751             m_input_reader_stack.Pop ();
752             reader_sp->Notify (eInputReaderDeactivate);
753             reader_sp->Notify (eInputReaderDone);
754             result = true;
755 
756             if (!m_input_reader_stack.IsEmpty())
757             {
758                 reader_sp = m_input_reader_stack.Top();
759                 if (reader_sp)
760                 {
761                     ActivateInputReader (reader_sp);
762                     reader_sp->Notify (eInputReaderReactivate);
763                 }
764             }
765         }
766     }
767     return result;
768 }
769 
770 bool
771 Debugger::CheckIfTopInputReaderIsDone ()
772 {
773     bool result = false;
774     if (!m_input_reader_stack.IsEmpty())
775     {
776         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
777         InputReaderSP reader_sp(m_input_reader_stack.Top());
778 
779         if (reader_sp && reader_sp->IsDone())
780         {
781             result = true;
782             PopInputReader (reader_sp);
783         }
784     }
785     return result;
786 }
787 
788 void
789 Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
790 {
791     int input_fd = m_input_file.GetFile().GetDescriptor();
792 
793     if (input_fd >= 0)
794     {
795         Terminal tty(input_fd);
796 
797         tty.SetEcho(reader_sp->GetEcho());
798 
799         switch (reader_sp->GetGranularity())
800         {
801         case eInputReaderGranularityByte:
802         case eInputReaderGranularityWord:
803             tty.SetCanonical (false);
804             break;
805 
806         case eInputReaderGranularityLine:
807         case eInputReaderGranularityAll:
808             tty.SetCanonical (true);
809             break;
810 
811         default:
812             break;
813         }
814     }
815 }
816 
817 StreamSP
818 Debugger::GetAsyncOutputStream ()
819 {
820     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
821                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
822 }
823 
824 StreamSP
825 Debugger::GetAsyncErrorStream ()
826 {
827     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
828                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
829 }
830 
831 uint32_t
832 Debugger::GetNumDebuggers()
833 {
834     if (g_shared_debugger_refcount > 0)
835     {
836         Mutex::Locker locker (GetDebuggerListMutex ());
837         return GetDebuggerList().size();
838     }
839     return 0;
840 }
841 
842 lldb::DebuggerSP
843 Debugger::GetDebuggerAtIndex (uint32_t index)
844 {
845     DebuggerSP debugger_sp;
846 
847     if (g_shared_debugger_refcount > 0)
848     {
849         Mutex::Locker locker (GetDebuggerListMutex ());
850         DebuggerList &debugger_list = GetDebuggerList();
851 
852         if (index < debugger_list.size())
853             debugger_sp = debugger_list[index];
854     }
855 
856     return debugger_sp;
857 }
858 
859 DebuggerSP
860 Debugger::FindDebuggerWithID (lldb::user_id_t id)
861 {
862     DebuggerSP debugger_sp;
863 
864     if (g_shared_debugger_refcount > 0)
865     {
866         Mutex::Locker locker (GetDebuggerListMutex ());
867         DebuggerList &debugger_list = GetDebuggerList();
868         DebuggerList::iterator pos, end = debugger_list.end();
869         for (pos = debugger_list.begin(); pos != end; ++pos)
870         {
871             if ((*pos).get()->GetID() == id)
872             {
873                 debugger_sp = *pos;
874                 break;
875             }
876         }
877     }
878     return debugger_sp;
879 }
880 
881 static void
882 TestPromptFormats (StackFrame *frame)
883 {
884     if (frame == NULL)
885         return;
886 
887     StreamString s;
888     const char *prompt_format =
889     "{addr = '${addr}'\n}"
890     "{process.id = '${process.id}'\n}"
891     "{process.name = '${process.name}'\n}"
892     "{process.file.basename = '${process.file.basename}'\n}"
893     "{process.file.fullpath = '${process.file.fullpath}'\n}"
894     "{thread.id = '${thread.id}'\n}"
895     "{thread.index = '${thread.index}'\n}"
896     "{thread.name = '${thread.name}'\n}"
897     "{thread.queue = '${thread.queue}'\n}"
898     "{thread.stop-reason = '${thread.stop-reason}'\n}"
899     "{target.arch = '${target.arch}'\n}"
900     "{module.file.basename = '${module.file.basename}'\n}"
901     "{module.file.fullpath = '${module.file.fullpath}'\n}"
902     "{file.basename = '${file.basename}'\n}"
903     "{file.fullpath = '${file.fullpath}'\n}"
904     "{frame.index = '${frame.index}'\n}"
905     "{frame.pc = '${frame.pc}'\n}"
906     "{frame.sp = '${frame.sp}'\n}"
907     "{frame.fp = '${frame.fp}'\n}"
908     "{frame.flags = '${frame.flags}'\n}"
909     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
910     "{frame.reg.rip = '${frame.reg.rip}'\n}"
911     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
912     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
913     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
914     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
915     "{frame.reg.carp = '${frame.reg.carp}'\n}"
916     "{function.id = '${function.id}'\n}"
917     "{function.name = '${function.name}'\n}"
918     "{function.name-with-args = '${function.name-with-args}'\n}"
919     "{function.addr-offset = '${function.addr-offset}'\n}"
920     "{function.line-offset = '${function.line-offset}'\n}"
921     "{function.pc-offset = '${function.pc-offset}'\n}"
922     "{line.file.basename = '${line.file.basename}'\n}"
923     "{line.file.fullpath = '${line.file.fullpath}'\n}"
924     "{line.number = '${line.number}'\n}"
925     "{line.start-addr = '${line.start-addr}'\n}"
926     "{line.end-addr = '${line.end-addr}'\n}"
927 ;
928 
929     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
930     ExecutionContext exe_ctx;
931     frame->CalculateExecutionContext(exe_ctx);
932     const char *end = NULL;
933     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
934     {
935         printf("%s\n", s.GetData());
936     }
937     else
938     {
939         printf ("error: at '%s'\n", end);
940         printf ("what we got: %s\n", s.GetData());
941     }
942 }
943 
944 static bool
945 ScanFormatDescriptor (const char* var_name_begin,
946                       const char* var_name_end,
947                       const char** var_name_final,
948                       const char** percent_position,
949                       Format* custom_format,
950                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
951 {
952     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
953     *percent_position = ::strchr(var_name_begin,'%');
954     if (!*percent_position || *percent_position > var_name_end)
955     {
956         if (log)
957             log->Printf("no format descriptor in string, skipping");
958         *var_name_final = var_name_end;
959     }
960     else
961     {
962         *var_name_final = *percent_position;
963         char* format_name = new char[var_name_end-*var_name_final]; format_name[var_name_end-*var_name_final-1] = '\0';
964         memcpy(format_name, *var_name_final+1, var_name_end-*var_name_final-1);
965         if (log)
966             log->Printf("parsing %s as a format descriptor", format_name);
967         if ( !FormatManager::GetFormatFromCString(format_name,
968                                                   true,
969                                                   *custom_format) )
970         {
971             if (log)
972                 log->Printf("%s is an unknown format", format_name);
973             // if this is an @ sign, print ObjC description
974             if (*format_name == '@')
975                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
976             // if this is a V, print the value using the default format
977             else if (*format_name == 'V')
978                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
979             // if this is an L, print the location of the value
980             else if (*format_name == 'L')
981                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
982             // if this is an S, print the summary after all
983             else if (*format_name == 'S')
984                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
985             else if (*format_name == '#')
986                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
987             else if (*format_name == 'T')
988                 *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
989             else if (log)
990                 log->Printf("%s is an error, leaving the previous value alone", format_name);
991         }
992         // a good custom format tells us to print the value using it
993         else
994         {
995             if (log)
996                 log->Printf("will display value for this VO");
997             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
998         }
999         delete format_name;
1000     }
1001     if (log)
1002         log->Printf("final format description outcome: custom_format = %d, val_obj_display = %d",
1003                     *custom_format,
1004                     *val_obj_display);
1005     return true;
1006 }
1007 
1008 static bool
1009 ScanBracketedRange (const char* var_name_begin,
1010                     const char* var_name_end,
1011                     const char* var_name_final,
1012                     const char** open_bracket_position,
1013                     const char** separator_position,
1014                     const char** close_bracket_position,
1015                     const char** var_name_final_if_array_range,
1016                     int64_t* index_lower,
1017                     int64_t* index_higher)
1018 {
1019     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1020     *open_bracket_position = ::strchr(var_name_begin,'[');
1021     if (*open_bracket_position && *open_bracket_position < var_name_final)
1022     {
1023         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
1024         *close_bracket_position = ::strchr(*open_bracket_position,']');
1025         // as usual, we assume that [] will come before %
1026         //printf("trying to expand a []\n");
1027         *var_name_final_if_array_range = *open_bracket_position;
1028         if (*close_bracket_position - *open_bracket_position == 1)
1029         {
1030             if (log)
1031                 log->Printf("[] detected.. going from 0 to end of data");
1032             *index_lower = 0;
1033         }
1034         else if (*separator_position == NULL || *separator_position > var_name_end)
1035         {
1036             char *end = NULL;
1037             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1038             *index_higher = *index_lower;
1039             if (log)
1040                 log->Printf("[%lld] detected, high index is same", *index_lower);
1041         }
1042         else if (*close_bracket_position && *close_bracket_position < var_name_end)
1043         {
1044             char *end = NULL;
1045             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
1046             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1047             if (log)
1048                 log->Printf("[%lld-%lld] detected", *index_lower, *index_higher);
1049         }
1050         else
1051         {
1052             if (log)
1053                 log->Printf("expression is erroneous, cannot extract indices out of it");
1054             return false;
1055         }
1056         if (*index_lower > *index_higher && *index_higher > 0)
1057         {
1058             if (log)
1059                 log->Printf("swapping indices");
1060             int temp = *index_lower;
1061             *index_lower = *index_higher;
1062             *index_higher = temp;
1063         }
1064     }
1065     else if (log)
1066             log->Printf("no bracketed range, skipping entirely");
1067     return true;
1068 }
1069 
1070 static ValueObjectSP
1071 ExpandIndexedExpression (ValueObject* valobj,
1072                          uint32_t index,
1073                          StackFrame* frame,
1074                          bool deref_pointer)
1075 {
1076     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1077     const char* ptr_deref_format = "[%d]";
1078     std::auto_ptr<char> ptr_deref_buffer(new char[10]);
1079     ::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index);
1080     if (log)
1081         log->Printf("name to deref: %s",ptr_deref_buffer.get());
1082     const char* first_unparsed;
1083     ValueObject::GetValueForExpressionPathOptions options;
1084     ValueObject::ExpressionPathEndResultType final_value_type;
1085     ValueObject::ExpressionPathScanEndReason reason_to_stop;
1086     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1087     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.get(),
1088                                                           &first_unparsed,
1089                                                           &reason_to_stop,
1090                                                           &final_value_type,
1091                                                           options,
1092                                                           &what_next);
1093     if (!item)
1094     {
1095         if (log)
1096             log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
1097                " final_value_type %d",
1098                first_unparsed, reason_to_stop, final_value_type);
1099     }
1100     else
1101     {
1102         if (log)
1103             log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1104                " final_value_type %d",
1105                first_unparsed, reason_to_stop, final_value_type);
1106     }
1107     return item;
1108 }
1109 
1110 bool
1111 Debugger::FormatPrompt
1112 (
1113     const char *format,
1114     const SymbolContext *sc,
1115     const ExecutionContext *exe_ctx,
1116     const Address *addr,
1117     Stream &s,
1118     const char **end,
1119     ValueObject* valobj
1120 )
1121 {
1122     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
1123     bool success = true;
1124     const char *p;
1125     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1126     for (p = format; *p != '\0'; ++p)
1127     {
1128         if (realvalobj)
1129         {
1130             valobj = realvalobj;
1131             realvalobj = NULL;
1132         }
1133         size_t non_special_chars = ::strcspn (p, "${}\\");
1134         if (non_special_chars > 0)
1135         {
1136             if (success)
1137                 s.Write (p, non_special_chars);
1138             p += non_special_chars;
1139         }
1140 
1141         if (*p == '\0')
1142         {
1143             break;
1144         }
1145         else if (*p == '{')
1146         {
1147             // Start a new scope that must have everything it needs if it is to
1148             // to make it into the final output stream "s". If you want to make
1149             // a format that only prints out the function or symbol name if there
1150             // is one in the symbol context you can use:
1151             //      "{function =${function.name}}"
1152             // The first '{' starts a new scope that end with the matching '}' at
1153             // the end of the string. The contents "function =${function.name}"
1154             // will then be evaluated and only be output if there is a function
1155             // or symbol with a valid name.
1156             StreamString sub_strm;
1157 
1158             ++p;  // Skip the '{'
1159 
1160             if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
1161             {
1162                 // The stream had all it needed
1163                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
1164             }
1165             if (*p != '}')
1166             {
1167                 success = false;
1168                 break;
1169             }
1170         }
1171         else if (*p == '}')
1172         {
1173             // End of a enclosing scope
1174             break;
1175         }
1176         else if (*p == '$')
1177         {
1178             // We have a prompt variable to print
1179             ++p;
1180             if (*p == '{')
1181             {
1182                 ++p;
1183                 const char *var_name_begin = p;
1184                 const char *var_name_end = ::strchr (p, '}');
1185 
1186                 if (var_name_end && var_name_begin < var_name_end)
1187                 {
1188                     // if we have already failed to parse, skip this variable
1189                     if (success)
1190                     {
1191                         const char *cstr = NULL;
1192                         Address format_addr;
1193                         bool calculate_format_addr_function_offset = false;
1194                         // Set reg_kind and reg_num to invalid values
1195                         RegisterKind reg_kind = kNumRegisterKinds;
1196                         uint32_t reg_num = LLDB_INVALID_REGNUM;
1197                         FileSpec format_file_spec;
1198                         const RegisterInfo *reg_info = NULL;
1199                         RegisterContext *reg_ctx = NULL;
1200                         bool do_deref_pointer = false;
1201                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
1202                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
1203 
1204                         // Each variable must set success to true below...
1205                         bool var_success = false;
1206                         switch (var_name_begin[0])
1207                         {
1208                         case '*':
1209                         case 'v':
1210                         case 's':
1211                             {
1212                                 if (!valobj)
1213                                     break;
1214 
1215                                 if (log)
1216                                     log->Printf("initial string: %s",var_name_begin);
1217 
1218                                 // check for *var and *svar
1219                                 if (*var_name_begin == '*')
1220                                 {
1221                                     do_deref_pointer = true;
1222                                     var_name_begin++;
1223                                 }
1224 
1225                                 if (log)
1226                                     log->Printf("initial string: %s",var_name_begin);
1227 
1228                                 if (*var_name_begin == 's')
1229                                 {
1230                                     if (!valobj->IsSynthetic())
1231                                         valobj = valobj->GetSyntheticValue().get();
1232                                     if (!valobj)
1233                                         break;
1234                                     var_name_begin++;
1235                                 }
1236 
1237                                 if (log)
1238                                     log->Printf("initial string: %s",var_name_begin);
1239 
1240                                 // should be a 'v' by now
1241                                 if (*var_name_begin != 'v')
1242                                     break;
1243 
1244                                 if (log)
1245                                     log->Printf("initial string: %s",var_name_begin);
1246 
1247                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
1248                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1249                                 ValueObject::GetValueForExpressionPathOptions options;
1250                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
1251                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
1252                                 ValueObject* target = NULL;
1253                                 Format custom_format = eFormatInvalid;
1254                                 const char* var_name_final = NULL;
1255                                 const char* var_name_final_if_array_range = NULL;
1256                                 const char* close_bracket_position = NULL;
1257                                 int64_t index_lower = -1;
1258                                 int64_t index_higher = -1;
1259                                 bool is_array_range = false;
1260                                 const char* first_unparsed;
1261                                 bool was_plain_var = false;
1262                                 bool was_var_format = false;
1263                                 bool was_var_indexed = false;
1264 
1265                                 if (!valobj) break;
1266                                 // simplest case ${var}, just print valobj's value
1267                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
1268                                 {
1269                                     was_plain_var = true;
1270                                     target = valobj;
1271                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1272                                 }
1273                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
1274                                 {
1275                                     was_var_format = true;
1276                                     // this is a variable with some custom format applied to it
1277                                     const char* percent_position;
1278                                     target = valobj;
1279                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1280                                     ScanFormatDescriptor (var_name_begin,
1281                                                           var_name_end,
1282                                                           &var_name_final,
1283                                                           &percent_position,
1284                                                           &custom_format,
1285                                                           &val_obj_display);
1286                                 }
1287                                     // this is ${var.something} or multiple .something nested
1288                                 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
1289                                 {
1290                                     if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0)
1291                                         was_var_indexed = true;
1292                                     const char* percent_position;
1293                                     ScanFormatDescriptor (var_name_begin,
1294                                                           var_name_end,
1295                                                           &var_name_final,
1296                                                           &percent_position,
1297                                                           &custom_format,
1298                                                           &val_obj_display);
1299 
1300                                     const char* open_bracket_position;
1301                                     const char* separator_position;
1302                                     ScanBracketedRange (var_name_begin,
1303                                                         var_name_end,
1304                                                         var_name_final,
1305                                                         &open_bracket_position,
1306                                                         &separator_position,
1307                                                         &close_bracket_position,
1308                                                         &var_name_final_if_array_range,
1309                                                         &index_lower,
1310                                                         &index_higher);
1311 
1312                                     Error error;
1313 
1314                                     std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]);
1315                                     ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
1316                                     memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
1317 
1318                                     if (log)
1319                                         log->Printf("symbol to expand: %s",expr_path.get());
1320 
1321                                     target = valobj->GetValueForExpressionPath(expr_path.get(),
1322                                                                              &first_unparsed,
1323                                                                              &reason_to_stop,
1324                                                                              &final_value_type,
1325                                                                              options,
1326                                                                              &what_next).get();
1327 
1328                                     if (!target)
1329                                     {
1330                                         if (log)
1331                                             log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
1332                                                " final_value_type %d",
1333                                                first_unparsed, reason_to_stop, final_value_type);
1334                                         break;
1335                                     }
1336                                     else
1337                                     {
1338                                         if (log)
1339                                             log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1340                                                " final_value_type %d",
1341                                                first_unparsed, reason_to_stop, final_value_type);
1342                                     }
1343                                 }
1344                                 else
1345                                     break;
1346 
1347                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
1348                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1349 
1350                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1351 
1352                                 if (do_deref_pointer && !is_array_range)
1353                                 {
1354                                     // I have not deref-ed yet, let's do it
1355                                     // this happens when we are not going through GetValueForVariableExpressionPath
1356                                     // to get to the target ValueObject
1357                                     Error error;
1358                                     target = target->Dereference(error).get();
1359                                     if (error.Fail())
1360                                     {
1361                                         if (log)
1362                                             log->Printf("ERROR: %s\n", error.AsCString("unknown")); \
1363                                         break;
1364                                     }
1365                                     do_deref_pointer = false;
1366                                 }
1367 
1368                                 // <rdar://problem/11338654>
1369                                 // we do not want to use the summary for a bitfield of type T:n
1370                                 // if we were originally dealing with just a T - that would get
1371                                 // us into an endless recursion
1372                                 if (target->IsBitfield() && was_var_indexed)
1373                                 {
1374                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1375                                     StreamString bitfield_name;
1376                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1377                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1378                                     if (!DataVisualization::GetSummaryForType(type_sp))
1379                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1380                                 }
1381 
1382                                 // TODO use flags for these
1383                                 bool is_array = ClangASTContext::IsArrayType(target->GetClangType());
1384                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
1385                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
1386 
1387                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1388                                 {
1389                                     StreamString str_temp;
1390                                     if (log)
1391                                         log->Printf("I am into array || pointer && !range");
1392 
1393                                     if (target->HasSpecialPrintableRepresentation(val_obj_display,
1394                                                                                   custom_format))
1395                                     {
1396                                         // try to use the special cases
1397                                         var_success = target->DumpPrintableRepresentation(str_temp,
1398                                                                                           val_obj_display,
1399                                                                                           custom_format);
1400                                         if (log)
1401                                             log->Printf("special cases did%s match", var_success ? "" : "n't");
1402 
1403                                         // should not happen
1404                                         if (!var_success)
1405                                             s << "<invalid usage of pointer value as object>";
1406                                         else
1407                                             s << str_temp.GetData();
1408                                         var_success = true;
1409                                         break;
1410                                     }
1411                                     else
1412                                     {
1413                                         if (was_plain_var) // if ${var}
1414                                         {
1415                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1416                                         }
1417                                         else if (is_pointer) // if pointer, value is the address stored
1418                                         {
1419                                             target->DumpPrintableRepresentation (s,
1420                                                                                  val_obj_display,
1421                                                                                  custom_format,
1422                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
1423                                         }
1424                                         else
1425                                         {
1426                                             s << "<invalid usage of pointer value as object>";
1427                                         }
1428                                         var_success = true;
1429                                         break;
1430                                     }
1431                                 }
1432 
1433                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1434                                 // type @ location message
1435                                 if (is_aggregate && was_plain_var)
1436                                 {
1437                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1438                                     var_success = true;
1439                                     break;
1440                                 }
1441 
1442                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
1443                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
1444                                 {
1445                                     s << "<invalid use of aggregate type>";
1446                                     var_success = true;
1447                                     break;
1448                                 }
1449 
1450                                 if (!is_array_range)
1451                                 {
1452                                     if (log)
1453                                         log->Printf("dumping ordinary printable output");
1454                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1455                                 }
1456                                 else
1457                                 {
1458                                     if (log)
1459                                         log->Printf("checking if I can handle as array");
1460                                     if (!is_array && !is_pointer)
1461                                         break;
1462                                     if (log)
1463                                         log->Printf("handle as array");
1464                                     const char* special_directions = NULL;
1465                                     StreamString special_directions_writer;
1466                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1467                                     {
1468                                         ConstString additional_data;
1469                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1470                                         special_directions_writer.Printf("${%svar%s}",
1471                                                                          do_deref_pointer ? "*" : "",
1472                                                                          additional_data.GetCString());
1473                                         special_directions = special_directions_writer.GetData();
1474                                     }
1475 
1476                                     // let us display items index_lower thru index_higher of this array
1477                                     s.PutChar('[');
1478                                     var_success = true;
1479 
1480                                     if (index_higher < 0)
1481                                         index_higher = valobj->GetNumChildren() - 1;
1482 
1483                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1484 
1485                                     for (;index_lower<=index_higher;index_lower++)
1486                                     {
1487                                         ValueObject* item = ExpandIndexedExpression (target,
1488                                                                                      index_lower,
1489                                                                                      exe_ctx->GetFramePtr(),
1490                                                                                      false).get();
1491 
1492                                         if (!item)
1493                                         {
1494                                             if (log)
1495                                                 log->Printf("ERROR in getting child item at index %lld", index_lower);
1496                                         }
1497                                         else
1498                                         {
1499                                             if (log)
1500                                                 log->Printf("special_directions for child item: %s",special_directions);
1501                                         }
1502 
1503                                         if (!special_directions)
1504                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1505                                         else
1506                                             var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
1507 
1508                                         if (--max_num_children == 0)
1509                                         {
1510                                             s.PutCString(", ...");
1511                                             break;
1512                                         }
1513 
1514                                         if (index_lower < index_higher)
1515                                             s.PutChar(',');
1516                                     }
1517                                     s.PutChar(']');
1518                                 }
1519                             }
1520                             break;
1521                         case 'a':
1522                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
1523                             {
1524                                 if (addr && addr->IsValid())
1525                                 {
1526                                     var_success = true;
1527                                     format_addr = *addr;
1528                                 }
1529                             }
1530                             else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0)
1531                             {
1532                                 var_success = true;
1533                                 var_name_begin += strlen("ansi."); // Skip the "ansi."
1534                                 if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0)
1535                                 {
1536                                     var_name_begin += strlen("fg."); // Skip the "fg."
1537                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1538                                     {
1539                                         s.Printf ("%s%s%s",
1540                                                   lldb_utility::ansi::k_escape_start,
1541                                                   lldb_utility::ansi::k_fg_black,
1542                                                   lldb_utility::ansi::k_escape_end);
1543                                     }
1544                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1545                                     {
1546                                         s.Printf ("%s%s%s",
1547                                                   lldb_utility::ansi::k_escape_start,
1548                                                   lldb_utility::ansi::k_fg_red,
1549                                                   lldb_utility::ansi::k_escape_end);
1550                                     }
1551                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1552                                     {
1553                                         s.Printf ("%s%s%s",
1554                                                   lldb_utility::ansi::k_escape_start,
1555                                                   lldb_utility::ansi::k_fg_green,
1556                                                   lldb_utility::ansi::k_escape_end);
1557                                     }
1558                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1559                                     {
1560                                         s.Printf ("%s%s%s",
1561                                                   lldb_utility::ansi::k_escape_start,
1562                                                   lldb_utility::ansi::k_fg_yellow,
1563                                                   lldb_utility::ansi::k_escape_end);
1564                                     }
1565                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1566                                     {
1567                                         s.Printf ("%s%s%s",
1568                                                   lldb_utility::ansi::k_escape_start,
1569                                                   lldb_utility::ansi::k_fg_blue,
1570                                                   lldb_utility::ansi::k_escape_end);
1571                                     }
1572                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1573                                     {
1574                                         s.Printf ("%s%s%s",
1575                                                   lldb_utility::ansi::k_escape_start,
1576                                                   lldb_utility::ansi::k_fg_purple,
1577                                                   lldb_utility::ansi::k_escape_end);
1578                                     }
1579                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1580                                     {
1581                                         s.Printf ("%s%s%s",
1582                                                   lldb_utility::ansi::k_escape_start,
1583                                                   lldb_utility::ansi::k_fg_cyan,
1584                                                   lldb_utility::ansi::k_escape_end);
1585                                     }
1586                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1587                                     {
1588                                         s.Printf ("%s%s%s",
1589                                                   lldb_utility::ansi::k_escape_start,
1590                                                   lldb_utility::ansi::k_fg_white,
1591                                                   lldb_utility::ansi::k_escape_end);
1592                                     }
1593                                     else
1594                                     {
1595                                         var_success = false;
1596                                     }
1597                                 }
1598                                 else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0)
1599                                 {
1600                                     var_name_begin += strlen("bg."); // Skip the "bg."
1601                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1602                                     {
1603                                         s.Printf ("%s%s%s",
1604                                                   lldb_utility::ansi::k_escape_start,
1605                                                   lldb_utility::ansi::k_bg_black,
1606                                                   lldb_utility::ansi::k_escape_end);
1607                                     }
1608                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1609                                     {
1610                                         s.Printf ("%s%s%s",
1611                                                   lldb_utility::ansi::k_escape_start,
1612                                                   lldb_utility::ansi::k_bg_red,
1613                                                   lldb_utility::ansi::k_escape_end);
1614                                     }
1615                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1616                                     {
1617                                         s.Printf ("%s%s%s",
1618                                                   lldb_utility::ansi::k_escape_start,
1619                                                   lldb_utility::ansi::k_bg_green,
1620                                                   lldb_utility::ansi::k_escape_end);
1621                                     }
1622                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1623                                     {
1624                                         s.Printf ("%s%s%s",
1625                                                   lldb_utility::ansi::k_escape_start,
1626                                                   lldb_utility::ansi::k_bg_yellow,
1627                                                   lldb_utility::ansi::k_escape_end);
1628                                     }
1629                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1630                                     {
1631                                         s.Printf ("%s%s%s",
1632                                                   lldb_utility::ansi::k_escape_start,
1633                                                   lldb_utility::ansi::k_bg_blue,
1634                                                   lldb_utility::ansi::k_escape_end);
1635                                     }
1636                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1637                                     {
1638                                         s.Printf ("%s%s%s",
1639                                                   lldb_utility::ansi::k_escape_start,
1640                                                   lldb_utility::ansi::k_bg_purple,
1641                                                   lldb_utility::ansi::k_escape_end);
1642                                     }
1643                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1644                                     {
1645                                         s.Printf ("%s%s%s",
1646                                                   lldb_utility::ansi::k_escape_start,
1647                                                   lldb_utility::ansi::k_bg_cyan,
1648                                                   lldb_utility::ansi::k_escape_end);
1649                                     }
1650                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1651                                     {
1652                                         s.Printf ("%s%s%s",
1653                                                   lldb_utility::ansi::k_escape_start,
1654                                                   lldb_utility::ansi::k_bg_white,
1655                                                   lldb_utility::ansi::k_escape_end);
1656                                     }
1657                                     else
1658                                     {
1659                                         var_success = false;
1660                                     }
1661                                 }
1662                                 else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0)
1663                                 {
1664                                     s.Printf ("%s%s%s",
1665                                               lldb_utility::ansi::k_escape_start,
1666                                               lldb_utility::ansi::k_ctrl_normal,
1667                                               lldb_utility::ansi::k_escape_end);
1668                                 }
1669                                 else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0)
1670                                 {
1671                                     s.Printf ("%s%s%s",
1672                                               lldb_utility::ansi::k_escape_start,
1673                                               lldb_utility::ansi::k_ctrl_bold,
1674                                               lldb_utility::ansi::k_escape_end);
1675                                 }
1676                                 else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0)
1677                                 {
1678                                     s.Printf ("%s%s%s",
1679                                               lldb_utility::ansi::k_escape_start,
1680                                               lldb_utility::ansi::k_ctrl_faint,
1681                                               lldb_utility::ansi::k_escape_end);
1682                                 }
1683                                 else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0)
1684                                 {
1685                                     s.Printf ("%s%s%s",
1686                                               lldb_utility::ansi::k_escape_start,
1687                                               lldb_utility::ansi::k_ctrl_italic,
1688                                               lldb_utility::ansi::k_escape_end);
1689                                 }
1690                                 else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0)
1691                                 {
1692                                     s.Printf ("%s%s%s",
1693                                               lldb_utility::ansi::k_escape_start,
1694                                               lldb_utility::ansi::k_ctrl_underline,
1695                                               lldb_utility::ansi::k_escape_end);
1696                                 }
1697                                 else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0)
1698                                 {
1699                                     s.Printf ("%s%s%s",
1700                                               lldb_utility::ansi::k_escape_start,
1701                                               lldb_utility::ansi::k_ctrl_slow_blink,
1702                                               lldb_utility::ansi::k_escape_end);
1703                                 }
1704                                 else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0)
1705                                 {
1706                                     s.Printf ("%s%s%s",
1707                                               lldb_utility::ansi::k_escape_start,
1708                                               lldb_utility::ansi::k_ctrl_fast_blink,
1709                                               lldb_utility::ansi::k_escape_end);
1710                                 }
1711                                 else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0)
1712                                 {
1713                                     s.Printf ("%s%s%s",
1714                                               lldb_utility::ansi::k_escape_start,
1715                                               lldb_utility::ansi::k_ctrl_negative,
1716                                               lldb_utility::ansi::k_escape_end);
1717                                 }
1718                                 else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0)
1719                                 {
1720                                     s.Printf ("%s%s%s",
1721                                               lldb_utility::ansi::k_escape_start,
1722                                               lldb_utility::ansi::k_ctrl_conceal,
1723                                               lldb_utility::ansi::k_escape_end);
1724 
1725                                 }
1726                                 else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0)
1727                                 {
1728                                     s.Printf ("%s%s%s",
1729                                               lldb_utility::ansi::k_escape_start,
1730                                               lldb_utility::ansi::k_ctrl_crossed_out,
1731                                               lldb_utility::ansi::k_escape_end);
1732                                 }
1733                                 else
1734                                 {
1735                                     var_success = false;
1736                                 }
1737                             }
1738                             break;
1739 
1740                         case 'p':
1741                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
1742                             {
1743                                 if (exe_ctx)
1744                                 {
1745                                     Process *process = exe_ctx->GetProcessPtr();
1746                                     if (process)
1747                                     {
1748                                         var_name_begin += ::strlen ("process.");
1749                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1750                                         {
1751                                             s.Printf("%llu", process->GetID());
1752                                             var_success = true;
1753                                         }
1754                                         else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
1755                                                  (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
1756                                                  (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
1757                                         {
1758                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1759                                             if (exe_module)
1760                                             {
1761                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
1762                                                 {
1763                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
1764                                                     var_success = format_file_spec;
1765                                                 }
1766                                                 else
1767                                                 {
1768                                                     format_file_spec = exe_module->GetFileSpec();
1769                                                     var_success = format_file_spec;
1770                                                 }
1771                                             }
1772                                         }
1773                                     }
1774                                 }
1775                             }
1776                             break;
1777 
1778                         case 't':
1779                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
1780                             {
1781                                 if (exe_ctx)
1782                                 {
1783                                     Thread *thread = exe_ctx->GetThreadPtr();
1784                                     if (thread)
1785                                     {
1786                                         var_name_begin += ::strlen ("thread.");
1787                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1788                                         {
1789                                             s.Printf("0x%4.4llx", thread->GetID());
1790                                             var_success = true;
1791                                         }
1792                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
1793                                         {
1794                                             s.Printf("%u", thread->GetIndexID());
1795                                             var_success = true;
1796                                         }
1797                                         else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1798                                         {
1799                                             cstr = thread->GetName();
1800                                             var_success = cstr && cstr[0];
1801                                             if (var_success)
1802                                                 s.PutCString(cstr);
1803                                         }
1804                                         else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
1805                                         {
1806                                             cstr = thread->GetQueueName();
1807                                             var_success = cstr && cstr[0];
1808                                             if (var_success)
1809                                                 s.PutCString(cstr);
1810                                         }
1811                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
1812                                         {
1813                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1814                                             if (stop_info_sp)
1815                                             {
1816                                                 cstr = stop_info_sp->GetDescription();
1817                                                 if (cstr && cstr[0])
1818                                                 {
1819                                                     s.PutCString(cstr);
1820                                                     var_success = true;
1821                                                 }
1822                                             }
1823                                         }
1824                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
1825                                         {
1826                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1827                                             if (stop_info_sp)
1828                                             {
1829                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
1830                                                 if (return_valobj_sp)
1831                                                 {
1832                                                     ValueObject::DumpValueObjectOptions dump_options;
1833                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get(), dump_options);
1834                                                     var_success = true;
1835                                                 }
1836                                             }
1837                                         }
1838                                     }
1839                                 }
1840                             }
1841                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
1842                             {
1843                                 // TODO: hookup properties
1844 //                                if (!target_properties_sp)
1845 //                                {
1846 //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1847 //                                    if (target)
1848 //                                        target_properties_sp = target->GetProperties();
1849 //                                }
1850 //
1851 //                                if (target_properties_sp)
1852 //                                {
1853 //                                    var_name_begin += ::strlen ("target.");
1854 //                                    const char *end_property = strchr(var_name_begin, '}');
1855 //                                    if (end_property)
1856 //                                    {
1857 //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
1858 //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
1859 //                                        if (!property_value.empty())
1860 //                                        {
1861 //                                            s.PutCString (property_value.c_str());
1862 //                                            var_success = true;
1863 //                                        }
1864 //                                    }
1865 //                                }
1866                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1867                                 if (target)
1868                                 {
1869                                     var_name_begin += ::strlen ("target.");
1870                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
1871                                     {
1872                                         ArchSpec arch (target->GetArchitecture ());
1873                                         if (arch.IsValid())
1874                                         {
1875                                             s.PutCString (arch.GetArchitectureName());
1876                                             var_success = true;
1877                                         }
1878                                     }
1879                                 }
1880                             }
1881                             break;
1882 
1883 
1884                         case 'm':
1885                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
1886                             {
1887                                 if (sc && sc->module_sp.get())
1888                                 {
1889                                     Module *module = sc->module_sp.get();
1890                                     var_name_begin += ::strlen ("module.");
1891 
1892                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1893                                     {
1894                                         if (module->GetFileSpec())
1895                                         {
1896                                             var_name_begin += ::strlen ("file.");
1897 
1898                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1899                                             {
1900                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
1901                                                 var_success = format_file_spec;
1902                                             }
1903                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1904                                             {
1905                                                 format_file_spec = module->GetFileSpec();
1906                                                 var_success = format_file_spec;
1907                                             }
1908                                         }
1909                                     }
1910                                 }
1911                             }
1912                             break;
1913 
1914 
1915                         case 'f':
1916                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1917                             {
1918                                 if (sc && sc->comp_unit != NULL)
1919                                 {
1920                                     var_name_begin += ::strlen ("file.");
1921 
1922                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1923                                     {
1924                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
1925                                         var_success = format_file_spec;
1926                                     }
1927                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1928                                     {
1929                                         format_file_spec = *sc->comp_unit;
1930                                         var_success = format_file_spec;
1931                                     }
1932                                 }
1933                             }
1934                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
1935                             {
1936                                 if (exe_ctx)
1937                                 {
1938                                     StackFrame *frame = exe_ctx->GetFramePtr();
1939                                     if (frame)
1940                                     {
1941                                         var_name_begin += ::strlen ("frame.");
1942                                         if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
1943                                         {
1944                                             s.Printf("%u", frame->GetFrameIndex());
1945                                             var_success = true;
1946                                         }
1947                                         else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
1948                                         {
1949                                             reg_kind = eRegisterKindGeneric;
1950                                             reg_num = LLDB_REGNUM_GENERIC_PC;
1951                                             var_success = true;
1952                                         }
1953                                         else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
1954                                         {
1955                                             reg_kind = eRegisterKindGeneric;
1956                                             reg_num = LLDB_REGNUM_GENERIC_SP;
1957                                             var_success = true;
1958                                         }
1959                                         else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
1960                                         {
1961                                             reg_kind = eRegisterKindGeneric;
1962                                             reg_num = LLDB_REGNUM_GENERIC_FP;
1963                                             var_success = true;
1964                                         }
1965                                         else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
1966                                         {
1967                                             reg_kind = eRegisterKindGeneric;
1968                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
1969                                             var_success = true;
1970                                         }
1971                                         else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
1972                                         {
1973                                             reg_ctx = frame->GetRegisterContext().get();
1974                                             if (reg_ctx)
1975                                             {
1976                                                 var_name_begin += ::strlen ("reg.");
1977                                                 if (var_name_begin < var_name_end)
1978                                                 {
1979                                                     std::string reg_name (var_name_begin, var_name_end);
1980                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
1981                                                     if (reg_info)
1982                                                         var_success = true;
1983                                                 }
1984                                             }
1985                                         }
1986                                     }
1987                                 }
1988                             }
1989                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
1990                             {
1991                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
1992                                 {
1993                                     var_name_begin += ::strlen ("function.");
1994                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1995                                     {
1996                                         if (sc->function)
1997                                             s.Printf("function{0x%8.8llx}", sc->function->GetID());
1998                                         else
1999                                             s.Printf("symbol[%u]", sc->symbol->GetID());
2000 
2001                                         var_success = true;
2002                                     }
2003                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
2004                                     {
2005                                         if (sc->function)
2006                                             cstr = sc->function->GetName().AsCString (NULL);
2007                                         else if (sc->symbol)
2008                                             cstr = sc->symbol->GetName().AsCString (NULL);
2009                                         if (cstr)
2010                                         {
2011                                             s.PutCString(cstr);
2012 
2013                                             if (sc->block)
2014                                             {
2015                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2016                                                 if (inline_block)
2017                                                 {
2018                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
2019                                                     if (inline_info)
2020                                                     {
2021                                                         s.PutCString(" [inlined] ");
2022                                                         inline_info->GetName().Dump(&s);
2023                                                     }
2024                                                 }
2025                                             }
2026                                             var_success = true;
2027                                         }
2028                                     }
2029                                     else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0)
2030                                     {
2031                                         // Print the function name with arguments in it
2032 
2033                                         if (sc->function)
2034                                         {
2035                                             var_success = true;
2036                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
2037                                             cstr = sc->function->GetName().AsCString (NULL);
2038                                             if (cstr)
2039                                             {
2040                                                 const InlineFunctionInfo *inline_info = NULL;
2041                                                 VariableListSP variable_list_sp;
2042                                                 bool get_function_vars = true;
2043                                                 if (sc->block)
2044                                                 {
2045                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
2046 
2047                                                     if (inline_block)
2048                                                     {
2049                                                         get_function_vars = false;
2050                                                         inline_info = sc->block->GetInlinedFunctionInfo();
2051                                                         if (inline_info)
2052                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
2053                                                     }
2054                                                 }
2055 
2056                                                 if (get_function_vars)
2057                                                 {
2058                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
2059                                                 }
2060 
2061                                                 if (inline_info)
2062                                                 {
2063                                                     s.PutCString (cstr);
2064                                                     s.PutCString (" [inlined] ");
2065                                                     cstr = inline_info->GetName().GetCString();
2066                                                 }
2067 
2068                                                 VariableList args;
2069                                                 if (variable_list_sp)
2070                                                 {
2071                                                     const size_t num_variables = variable_list_sp->GetSize();
2072                                                     for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
2073                                                     {
2074                                                         VariableSP var_sp (variable_list_sp->GetVariableAtIndex(var_idx));
2075                                                         if (var_sp->GetScope() == eValueTypeVariableArgument)
2076                                                             args.AddVariable (var_sp);
2077                                                     }
2078 
2079                                                 }
2080                                                 if (args.GetSize() > 0)
2081                                                 {
2082                                                     const char *open_paren = strchr (cstr, '(');
2083                                                     const char *close_paren = NULL;
2084                                                     if (open_paren)
2085                                                         close_paren = strchr (open_paren, ')');
2086 
2087                                                     if (open_paren)
2088                                                         s.Write(cstr, open_paren - cstr + 1);
2089                                                     else
2090                                                     {
2091                                                         s.PutCString (cstr);
2092                                                         s.PutChar ('(');
2093                                                     }
2094                                                     const size_t num_args = args.GetSize();
2095                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
2096                                                     {
2097                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
2098                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2099                                                         const char *var_name = var_value_sp->GetName().GetCString();
2100                                                         const char *var_value = var_value_sp->GetValueAsCString();
2101                                                         if (var_value_sp->GetError().Success())
2102                                                         {
2103                                                             if (arg_idx > 0)
2104                                                                 s.PutCString (", ");
2105                                                             s.Printf ("%s=%s", var_name, var_value);
2106                                                         }
2107                                                     }
2108 
2109                                                     if (close_paren)
2110                                                         s.PutCString (close_paren);
2111                                                     else
2112                                                         s.PutChar(')');
2113 
2114                                                 }
2115                                                 else
2116                                                 {
2117                                                     s.PutCString(cstr);
2118                                                 }
2119                                             }
2120                                         }
2121                                         else if (sc->symbol)
2122                                         {
2123                                             cstr = sc->symbol->GetName().AsCString (NULL);
2124                                             if (cstr)
2125                                             {
2126                                                 s.PutCString(cstr);
2127                                                 var_success = true;
2128                                             }
2129                                         }
2130                                     }
2131                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
2132                                     {
2133                                         var_success = addr != NULL;
2134                                         if (var_success)
2135                                         {
2136                                             format_addr = *addr;
2137                                             calculate_format_addr_function_offset = true;
2138                                         }
2139                                     }
2140                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
2141                                     {
2142                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
2143                                         if (var_success)
2144                                         {
2145                                             format_addr = sc->line_entry.range.GetBaseAddress();
2146                                             calculate_format_addr_function_offset = true;
2147                                         }
2148                                     }
2149                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
2150                                     {
2151                                         StackFrame *frame = exe_ctx->GetFramePtr();
2152                                         var_success = frame != NULL;
2153                                         if (var_success)
2154                                         {
2155                                             format_addr = frame->GetFrameCodeAddress();
2156                                             calculate_format_addr_function_offset = true;
2157                                         }
2158                                     }
2159                                 }
2160                             }
2161                             break;
2162 
2163                         case 'l':
2164                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
2165                             {
2166                                 if (sc && sc->line_entry.IsValid())
2167                                 {
2168                                     var_name_begin += ::strlen ("line.");
2169                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
2170                                     {
2171                                         var_name_begin += ::strlen ("file.");
2172 
2173                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
2174                                         {
2175                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
2176                                             var_success = format_file_spec;
2177                                         }
2178                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
2179                                         {
2180                                             format_file_spec = sc->line_entry.file;
2181                                             var_success = format_file_spec;
2182                                         }
2183                                     }
2184                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
2185                                     {
2186                                         var_success = true;
2187                                         s.Printf("%u", sc->line_entry.line);
2188                                     }
2189                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
2190                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
2191                                     {
2192                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
2193                                         if (var_success)
2194                                         {
2195                                             format_addr = sc->line_entry.range.GetBaseAddress();
2196                                             if (var_name_begin[0] == 'e')
2197                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
2198                                         }
2199                                     }
2200                                 }
2201                             }
2202                             break;
2203                         }
2204 
2205                         if (var_success)
2206                         {
2207                             // If format addr is valid, then we need to print an address
2208                             if (reg_num != LLDB_INVALID_REGNUM)
2209                             {
2210                                 StackFrame *frame = exe_ctx->GetFramePtr();
2211                                 // We have a register value to display...
2212                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
2213                                 {
2214                                     format_addr = frame->GetFrameCodeAddress();
2215                                 }
2216                                 else
2217                                 {
2218                                     if (reg_ctx == NULL)
2219                                         reg_ctx = frame->GetRegisterContext().get();
2220 
2221                                     if (reg_ctx)
2222                                     {
2223                                         if (reg_kind != kNumRegisterKinds)
2224                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
2225                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
2226                                         var_success = reg_info != NULL;
2227                                     }
2228                                 }
2229                             }
2230 
2231                             if (reg_info != NULL)
2232                             {
2233                                 RegisterValue reg_value;
2234                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
2235                                 if (var_success)
2236                                 {
2237                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
2238                                 }
2239                             }
2240 
2241                             if (format_file_spec)
2242                             {
2243                                 s << format_file_spec;
2244                             }
2245 
2246                             // If format addr is valid, then we need to print an address
2247                             if (format_addr.IsValid())
2248                             {
2249                                 var_success = false;
2250 
2251                                 if (calculate_format_addr_function_offset)
2252                                 {
2253                                     Address func_addr;
2254 
2255                                     if (sc)
2256                                     {
2257                                         if (sc->function)
2258                                         {
2259                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2260                                             if (sc->block)
2261                                             {
2262                                                 // Check to make sure we aren't in an inline
2263                                                 // function. If we are, use the inline block
2264                                                 // range that contains "format_addr" since
2265                                                 // blocks can be discontiguous.
2266                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
2267                                                 AddressRange inline_range;
2268                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
2269                                                     func_addr = inline_range.GetBaseAddress();
2270                                             }
2271                                         }
2272                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2273                                             func_addr = sc->symbol->GetAddress();
2274                                     }
2275 
2276                                     if (func_addr.IsValid())
2277                                     {
2278                                         if (func_addr.GetSection() == format_addr.GetSection())
2279                                         {
2280                                             addr_t func_file_addr = func_addr.GetFileAddress();
2281                                             addr_t addr_file_addr = format_addr.GetFileAddress();
2282                                             if (addr_file_addr > func_file_addr)
2283                                                 s.Printf(" + %llu", addr_file_addr - func_file_addr);
2284                                             else if (addr_file_addr < func_file_addr)
2285                                                 s.Printf(" - %llu", func_file_addr - addr_file_addr);
2286                                             var_success = true;
2287                                         }
2288                                         else
2289                                         {
2290                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2291                                             if (target)
2292                                             {
2293                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
2294                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
2295                                                 if (addr_load_addr > func_load_addr)
2296                                                     s.Printf(" + %llu", addr_load_addr - func_load_addr);
2297                                                 else if (addr_load_addr < func_load_addr)
2298                                                     s.Printf(" - %llu", func_load_addr - addr_load_addr);
2299                                                 var_success = true;
2300                                             }
2301                                         }
2302                                     }
2303                                 }
2304                                 else
2305                                 {
2306                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
2307                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
2308                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
2309                                         vaddr = format_addr.GetLoadAddress (target);
2310                                     if (vaddr == LLDB_INVALID_ADDRESS)
2311                                         vaddr = format_addr.GetFileAddress ();
2312 
2313                                     if (vaddr != LLDB_INVALID_ADDRESS)
2314                                     {
2315                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2316                                         if (addr_width == 0)
2317                                             addr_width = 16;
2318                                         s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
2319                                         var_success = true;
2320                                     }
2321                                 }
2322                             }
2323                         }
2324 
2325                         if (var_success == false)
2326                             success = false;
2327                     }
2328                     p = var_name_end;
2329                 }
2330                 else
2331                     break;
2332             }
2333             else
2334             {
2335                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
2336                 s.PutChar(*p);
2337             }
2338         }
2339         else if (*p == '\\')
2340         {
2341             ++p; // skip the slash
2342             switch (*p)
2343             {
2344             case 'a': s.PutChar ('\a'); break;
2345             case 'b': s.PutChar ('\b'); break;
2346             case 'f': s.PutChar ('\f'); break;
2347             case 'n': s.PutChar ('\n'); break;
2348             case 'r': s.PutChar ('\r'); break;
2349             case 't': s.PutChar ('\t'); break;
2350             case 'v': s.PutChar ('\v'); break;
2351             case '\'': s.PutChar ('\''); break;
2352             case '\\': s.PutChar ('\\'); break;
2353             case '0':
2354                 // 1 to 3 octal chars
2355                 {
2356                     // Make a string that can hold onto the initial zero char,
2357                     // up to 3 octal digits, and a terminating NULL.
2358                     char oct_str[5] = { 0, 0, 0, 0, 0 };
2359 
2360                     int i;
2361                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2362                         oct_str[i] = p[i];
2363 
2364                     // We don't want to consume the last octal character since
2365                     // the main for loop will do this for us, so we advance p by
2366                     // one less than i (even if i is zero)
2367                     p += i - 1;
2368                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2369                     if (octal_value <= UINT8_MAX)
2370                     {
2371                         char octal_char = octal_value;
2372                         s.Write (&octal_char, 1);
2373                     }
2374                 }
2375                 break;
2376 
2377             case 'x':
2378                 // hex number in the format
2379                 if (isxdigit(p[1]))
2380                 {
2381                     ++p;    // Skip the 'x'
2382 
2383                     // Make a string that can hold onto two hex chars plus a
2384                     // NULL terminator
2385                     char hex_str[3] = { 0,0,0 };
2386                     hex_str[0] = *p;
2387                     if (isxdigit(p[1]))
2388                     {
2389                         ++p; // Skip the first of the two hex chars
2390                         hex_str[1] = *p;
2391                     }
2392 
2393                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
2394                     if (hex_value <= UINT8_MAX)
2395                         s.PutChar (hex_value);
2396                 }
2397                 else
2398                 {
2399                     s.PutChar('x');
2400                 }
2401                 break;
2402 
2403             default:
2404                 // Just desensitize any other character by just printing what
2405                 // came after the '\'
2406                 s << *p;
2407                 break;
2408 
2409             }
2410 
2411         }
2412     }
2413     if (end)
2414         *end = p;
2415     return success;
2416 }
2417 
2418 void
2419 Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2420 {
2421     // For simplicity's sake, I am not going to deal with how to close down any
2422     // open logging streams, I just redirect everything from here on out to the
2423     // callback.
2424     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2425 }
2426 
2427 bool
2428 Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2429 {
2430     Log::Callbacks log_callbacks;
2431 
2432     StreamSP log_stream_sp;
2433     if (m_log_callback_stream_sp)
2434     {
2435         log_stream_sp = m_log_callback_stream_sp;
2436         // For now when using the callback mode you always get thread & timestamp.
2437         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2438     }
2439     else if (log_file == NULL || *log_file == '\0')
2440     {
2441         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2442     }
2443     else
2444     {
2445         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2446         if (pos == m_log_streams.end())
2447         {
2448             log_stream_sp.reset (new StreamFile (log_file));
2449             m_log_streams[log_file] = log_stream_sp;
2450         }
2451         else
2452             log_stream_sp = pos->second;
2453     }
2454     assert (log_stream_sp.get());
2455 
2456     if (log_options == 0)
2457         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2458 
2459     if (Log::GetLogChannelCallbacks (channel, log_callbacks))
2460     {
2461         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2462         return true;
2463     }
2464     else
2465     {
2466         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2467         if (log_channel_sp)
2468         {
2469             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2470             {
2471                 return true;
2472             }
2473             else
2474             {
2475                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2476                 return false;
2477             }
2478         }
2479         else
2480         {
2481             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2482             return false;
2483         }
2484     }
2485     return false;
2486 }
2487 
2488