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