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