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