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