130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 104a33d318SGreg Clayton #include "lldb/Core/Debugger.h" 114a33d318SGreg Clayton 124a33d318SGreg Clayton #include <map> 134a33d318SGreg Clayton 144becb37eSEnrico Granata #include "clang/AST/DeclCXX.h" 154becb37eSEnrico Granata #include "clang/AST/Type.h" 164becb37eSEnrico Granata 1730fdc8d8SChris Lattner #include "lldb/lldb-private.h" 1830fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h" 194a33d318SGreg Clayton #include "lldb/Core/FormatManager.h" 2030fdc8d8SChris Lattner #include "lldb/Core/InputReader.h" 217349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 2230fdc8d8SChris Lattner #include "lldb/Core/State.h" 235b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h" 24228063cdSJim Ingham #include "lldb/Core/StreamCallback.h" 251b654882SGreg Clayton #include "lldb/Core/StreamString.h" 2630fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 274becb37eSEnrico Granata #include "lldb/Core/ValueObject.h" 286d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h" 29a3406614SGreg Clayton #include "lldb/Host/Terminal.h" 306611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 316d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h" 3230fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 3330fdc8d8SChris Lattner #include "lldb/Target/Process.h" 341b654882SGreg Clayton #include "lldb/Target/RegisterContext.h" 351b654882SGreg Clayton #include "lldb/Target/StopInfo.h" 3630fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 375a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h" 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner using namespace lldb; 4030fdc8d8SChris Lattner using namespace lldb_private; 4130fdc8d8SChris Lattner 4230fdc8d8SChris Lattner 431b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0; 44ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1; 45ebc1bb27SCaroline Tice 461b654882SGreg Clayton #pragma mark Static Functions 471b654882SGreg Clayton 481b654882SGreg Clayton static Mutex & 491b654882SGreg Clayton GetDebuggerListMutex () 501b654882SGreg Clayton { 511b654882SGreg Clayton static Mutex g_mutex(Mutex::eMutexTypeRecursive); 521b654882SGreg Clayton return g_mutex; 531b654882SGreg Clayton } 541b654882SGreg Clayton 551b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList; 561b654882SGreg Clayton 571b654882SGreg Clayton static DebuggerList & 581b654882SGreg Clayton GetDebuggerList() 591b654882SGreg Clayton { 601b654882SGreg Clayton // hide the static debugger list inside a singleton accessor to avoid 611b654882SGreg Clayton // global init contructors 621b654882SGreg Clayton static DebuggerList g_list; 631b654882SGreg Clayton return g_list; 641b654882SGreg Clayton } 651b654882SGreg Clayton 661b654882SGreg Clayton 67e372b98dSGreg Clayton static const ConstString & 68e372b98dSGreg Clayton PromptVarName () 69e372b98dSGreg Clayton { 70e372b98dSGreg Clayton static ConstString g_const_string ("prompt"); 71e372b98dSGreg Clayton return g_const_string; 72e372b98dSGreg Clayton } 73e372b98dSGreg Clayton 74e372b98dSGreg Clayton static const ConstString & 75e372b98dSGreg Clayton GetFrameFormatName () 76e372b98dSGreg Clayton { 77e372b98dSGreg Clayton static ConstString g_const_string ("frame-format"); 78e372b98dSGreg Clayton return g_const_string; 79e372b98dSGreg Clayton } 80e372b98dSGreg Clayton 81e372b98dSGreg Clayton static const ConstString & 82e372b98dSGreg Clayton GetThreadFormatName () 83e372b98dSGreg Clayton { 84e372b98dSGreg Clayton static ConstString g_const_string ("thread-format"); 85e372b98dSGreg Clayton return g_const_string; 86e372b98dSGreg Clayton } 87e372b98dSGreg Clayton 88e372b98dSGreg Clayton static const ConstString & 89e372b98dSGreg Clayton ScriptLangVarName () 90e372b98dSGreg Clayton { 91e372b98dSGreg Clayton static ConstString g_const_string ("script-lang"); 92e372b98dSGreg Clayton return g_const_string; 93e372b98dSGreg Clayton } 94e372b98dSGreg Clayton 95e372b98dSGreg Clayton static const ConstString & 96e372b98dSGreg Clayton TermWidthVarName () 97e372b98dSGreg Clayton { 98e372b98dSGreg Clayton static ConstString g_const_string ("term-width"); 99e372b98dSGreg Clayton return g_const_string; 100e372b98dSGreg Clayton } 101e372b98dSGreg Clayton 102e372b98dSGreg Clayton static const ConstString & 103e372b98dSGreg Clayton UseExternalEditorVarName () 104e372b98dSGreg Clayton { 105e372b98dSGreg Clayton static ConstString g_const_string ("use-external-editor"); 106e372b98dSGreg Clayton return g_const_string; 107e372b98dSGreg Clayton } 108e372b98dSGreg Clayton 109e372b98dSGreg Clayton static const ConstString & 110e372b98dSGreg Clayton AutoConfirmName () 111e372b98dSGreg Clayton { 112e372b98dSGreg Clayton static ConstString g_const_string ("auto-confirm"); 113e372b98dSGreg Clayton return g_const_string; 114e372b98dSGreg Clayton } 115e372b98dSGreg Clayton 116e372b98dSGreg Clayton static const ConstString & 117e372b98dSGreg Clayton StopSourceContextBeforeName () 118e372b98dSGreg Clayton { 119e372b98dSGreg Clayton static ConstString g_const_string ("stop-line-count-before"); 120e372b98dSGreg Clayton return g_const_string; 121e372b98dSGreg Clayton } 122e372b98dSGreg Clayton 123e372b98dSGreg Clayton static const ConstString & 124e372b98dSGreg Clayton StopSourceContextAfterName () 125e372b98dSGreg Clayton { 126e372b98dSGreg Clayton static ConstString g_const_string ("stop-line-count-after"); 127e372b98dSGreg Clayton return g_const_string; 128e372b98dSGreg Clayton } 129e372b98dSGreg Clayton 130e372b98dSGreg Clayton static const ConstString & 131e372b98dSGreg Clayton StopDisassemblyCountName () 132e372b98dSGreg Clayton { 133e372b98dSGreg Clayton static ConstString g_const_string ("stop-disassembly-count"); 134e372b98dSGreg Clayton return g_const_string; 135e372b98dSGreg Clayton } 136e372b98dSGreg Clayton 137e372b98dSGreg Clayton static const ConstString & 138e372b98dSGreg Clayton StopDisassemblyDisplayName () 139e372b98dSGreg Clayton { 140e372b98dSGreg Clayton static ConstString g_const_string ("stop-disassembly-display"); 141e372b98dSGreg Clayton return g_const_string; 142e372b98dSGreg Clayton } 143e372b98dSGreg Clayton 144e372b98dSGreg Clayton OptionEnumValueElement 145e372b98dSGreg Clayton DebuggerInstanceSettings::g_show_disassembly_enum_values[] = 146e372b98dSGreg Clayton { 147e372b98dSGreg Clayton { eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, 148e372b98dSGreg Clayton { eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, 149e372b98dSGreg Clayton { eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, 150e372b98dSGreg Clayton { 0, NULL, NULL } 151e372b98dSGreg Clayton }; 152e372b98dSGreg Clayton 153e372b98dSGreg Clayton 154e372b98dSGreg Clayton 1551b654882SGreg Clayton #pragma mark Debugger 1561b654882SGreg Clayton 15799d0faf2SGreg Clayton UserSettingsControllerSP & 15899d0faf2SGreg Clayton Debugger::GetSettingsController () 15999d0faf2SGreg Clayton { 160b9556accSGreg Clayton static UserSettingsControllerSP g_settings_controller_sp; 161b9556accSGreg Clayton if (!g_settings_controller_sp) 162b9556accSGreg Clayton { 163b9556accSGreg Clayton g_settings_controller_sp.reset (new Debugger::SettingsController); 164b9556accSGreg Clayton 165b9556accSGreg Clayton // The first shared pointer to Debugger::SettingsController in 166b9556accSGreg Clayton // g_settings_controller_sp must be fully created above so that 167b9556accSGreg Clayton // the DebuggerInstanceSettings can use a weak_ptr to refer back 168b9556accSGreg Clayton // to the master setttings controller 169b9556accSGreg Clayton InstanceSettingsSP default_instance_settings_sp (new DebuggerInstanceSettings (g_settings_controller_sp, 170b9556accSGreg Clayton false, 171b9556accSGreg Clayton InstanceSettings::GetDefaultName().AsCString())); 172b9556accSGreg Clayton g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp); 173b9556accSGreg Clayton } 174b9556accSGreg Clayton return g_settings_controller_sp; 17599d0faf2SGreg Clayton } 17699d0faf2SGreg Clayton 1772f88aadfSCaroline Tice int 1782f88aadfSCaroline Tice Debugger::TestDebuggerRefCount () 1792f88aadfSCaroline Tice { 1802f88aadfSCaroline Tice return g_shared_debugger_refcount; 1812f88aadfSCaroline Tice } 1822f88aadfSCaroline Tice 18330fdc8d8SChris Lattner void 18430fdc8d8SChris Lattner Debugger::Initialize () 18530fdc8d8SChris Lattner { 1866611103cSGreg Clayton if (g_shared_debugger_refcount == 0) 18799d0faf2SGreg Clayton { 188dbe54508SGreg Clayton lldb_private::Initialize(); 18999d0faf2SGreg Clayton } 1906611103cSGreg Clayton g_shared_debugger_refcount++; 19199d0faf2SGreg Clayton 19230fdc8d8SChris Lattner } 19330fdc8d8SChris Lattner 19430fdc8d8SChris Lattner void 19530fdc8d8SChris Lattner Debugger::Terminate () 19630fdc8d8SChris Lattner { 1976611103cSGreg Clayton if (g_shared_debugger_refcount > 0) 1986611103cSGreg Clayton { 19930fdc8d8SChris Lattner g_shared_debugger_refcount--; 20030fdc8d8SChris Lattner if (g_shared_debugger_refcount == 0) 20130fdc8d8SChris Lattner { 202dbe54508SGreg Clayton lldb_private::WillTerminate(); 203dbe54508SGreg Clayton lldb_private::Terminate(); 2046760a517SCaroline Tice 20599d0faf2SGreg Clayton // Clear our master list of debugger objects 20699d0faf2SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 20799d0faf2SGreg Clayton GetDebuggerList().clear(); 20830fdc8d8SChris Lattner } 2096760a517SCaroline Tice } 2106760a517SCaroline Tice } 21130fdc8d8SChris Lattner 21220bd37f7SCaroline Tice void 21320bd37f7SCaroline Tice Debugger::SettingsInitialize () 21420bd37f7SCaroline Tice { 21520bd37f7SCaroline Tice static bool g_initialized = false; 21620bd37f7SCaroline Tice 21720bd37f7SCaroline Tice if (!g_initialized) 21820bd37f7SCaroline Tice { 21920bd37f7SCaroline Tice g_initialized = true; 220b9556accSGreg Clayton UserSettingsController::InitializeSettingsController (GetSettingsController(), 22120bd37f7SCaroline Tice SettingsController::global_settings_table, 22220bd37f7SCaroline Tice SettingsController::instance_settings_table); 22320bd37f7SCaroline Tice // Now call SettingsInitialize for each settings 'child' of Debugger 22420bd37f7SCaroline Tice Target::SettingsInitialize (); 22520bd37f7SCaroline Tice } 22620bd37f7SCaroline Tice } 22720bd37f7SCaroline Tice 22820bd37f7SCaroline Tice void 22920bd37f7SCaroline Tice Debugger::SettingsTerminate () 23020bd37f7SCaroline Tice { 23120bd37f7SCaroline Tice 23220bd37f7SCaroline Tice // Must call SettingsTerminate() for each settings 'child' of Debugger, before terminating the Debugger's 23320bd37f7SCaroline Tice // Settings. 23420bd37f7SCaroline Tice 23520bd37f7SCaroline Tice Target::SettingsTerminate (); 23620bd37f7SCaroline Tice 23720bd37f7SCaroline Tice // Now terminate the Debugger Settings. 23820bd37f7SCaroline Tice 23920bd37f7SCaroline Tice UserSettingsControllerSP &usc = GetSettingsController(); 24020bd37f7SCaroline Tice UserSettingsController::FinalizeSettingsController (usc); 24120bd37f7SCaroline Tice usc.reset(); 24220bd37f7SCaroline Tice } 24320bd37f7SCaroline Tice 2446611103cSGreg Clayton DebuggerSP 245228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton) 2466611103cSGreg Clayton { 247228063cdSJim Ingham DebuggerSP debugger_sp (new Debugger(log_callback, baton)); 2486611103cSGreg Clayton // Scope for locker 2496611103cSGreg Clayton { 2506611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 2516611103cSGreg Clayton GetDebuggerList().push_back(debugger_sp); 2526611103cSGreg Clayton } 2536611103cSGreg Clayton return debugger_sp; 2546611103cSGreg Clayton } 2556611103cSGreg Clayton 256e02657b1SCaroline Tice void 2574d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp) 258e02657b1SCaroline Tice { 259e02657b1SCaroline Tice if (debugger_sp.get() == NULL) 260e02657b1SCaroline Tice return; 261e02657b1SCaroline Tice 2628314c525SJim Ingham debugger_sp->Clear(); 2638314c525SJim Ingham 264e02657b1SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 265e02657b1SCaroline Tice DebuggerList &debugger_list = GetDebuggerList (); 266e02657b1SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 267e02657b1SCaroline Tice for (pos = debugger_list.begin (); pos != end; ++pos) 268e02657b1SCaroline Tice { 269e02657b1SCaroline Tice if ((*pos).get() == debugger_sp.get()) 270e02657b1SCaroline Tice { 271e02657b1SCaroline Tice debugger_list.erase (pos); 272e02657b1SCaroline Tice return; 273e02657b1SCaroline Tice } 274e02657b1SCaroline Tice } 275e02657b1SCaroline Tice } 276e02657b1SCaroline Tice 2774d122c40SGreg Clayton DebuggerSP 2783df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name) 2793df9a8dfSCaroline Tice { 2804d122c40SGreg Clayton DebuggerSP debugger_sp; 2813df9a8dfSCaroline Tice 2823df9a8dfSCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 2833df9a8dfSCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 2843df9a8dfSCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 2853df9a8dfSCaroline Tice 2863df9a8dfSCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 2873df9a8dfSCaroline Tice { 2883df9a8dfSCaroline Tice if ((*pos).get()->m_instance_name == instance_name) 2893df9a8dfSCaroline Tice { 2903df9a8dfSCaroline Tice debugger_sp = *pos; 2913df9a8dfSCaroline Tice break; 2923df9a8dfSCaroline Tice } 2933df9a8dfSCaroline Tice } 2943df9a8dfSCaroline Tice return debugger_sp; 2953df9a8dfSCaroline Tice } 2966611103cSGreg Clayton 2976611103cSGreg Clayton TargetSP 2986611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid) 2996611103cSGreg Clayton { 3004d122c40SGreg Clayton TargetSP target_sp; 3016611103cSGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 3026611103cSGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 3036611103cSGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 3046611103cSGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 3056611103cSGreg Clayton { 3066611103cSGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid); 3076611103cSGreg Clayton if (target_sp) 3086611103cSGreg Clayton break; 3096611103cSGreg Clayton } 3106611103cSGreg Clayton return target_sp; 3116611103cSGreg Clayton } 3126611103cSGreg Clayton 313e4e45924SGreg Clayton TargetSP 314e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process) 315e4e45924SGreg Clayton { 316e4e45924SGreg Clayton TargetSP target_sp; 317e4e45924SGreg Clayton Mutex::Locker locker (GetDebuggerListMutex ()); 318e4e45924SGreg Clayton DebuggerList &debugger_list = GetDebuggerList(); 319e4e45924SGreg Clayton DebuggerList::iterator pos, end = debugger_list.end(); 320e4e45924SGreg Clayton for (pos = debugger_list.begin(); pos != end; ++pos) 321e4e45924SGreg Clayton { 322e4e45924SGreg Clayton target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process); 323e4e45924SGreg Clayton if (target_sp) 324e4e45924SGreg Clayton break; 325e4e45924SGreg Clayton } 326e4e45924SGreg Clayton return target_sp; 327e4e45924SGreg Clayton } 328e4e45924SGreg Clayton 3296611103cSGreg Clayton 330228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : 331ebc1bb27SCaroline Tice UserID (g_unique_id++), 332b9556accSGreg Clayton DebuggerInstanceSettings (GetSettingsController()), 333d46c87a1SGreg Clayton m_input_comm("debugger.input"), 33430fdc8d8SChris Lattner m_input_file (), 33530fdc8d8SChris Lattner m_output_file (), 33630fdc8d8SChris Lattner m_error_file (), 3374bddaeb5SJim Ingham m_target_list (*this), 338ded470d3SGreg Clayton m_platform_list (), 33930fdc8d8SChris Lattner m_listener ("lldb.Debugger"), 340e37d605eSJim Ingham m_source_manager(*this), 341e37d605eSJim Ingham m_source_file_cache(), 3426611103cSGreg Clayton m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), 343d5a0a01bSCaroline Tice m_input_reader_stack (), 3444957bf69SGreg Clayton m_input_reader_data () 34530fdc8d8SChris Lattner { 346228063cdSJim Ingham if (log_callback) 347228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 3486611103cSGreg Clayton m_command_interpreter_ap->Initialize (); 349ded470d3SGreg Clayton // Always add our default platform to the platform list 350ded470d3SGreg Clayton PlatformSP default_platform_sp (Platform::GetDefaultPlatform()); 351ded470d3SGreg Clayton assert (default_platform_sp.get()); 352ded470d3SGreg Clayton m_platform_list.Append (default_platform_sp, true); 35330fdc8d8SChris Lattner } 35430fdc8d8SChris Lattner 35530fdc8d8SChris Lattner Debugger::~Debugger () 35630fdc8d8SChris Lattner { 3578314c525SJim Ingham Clear(); 3588314c525SJim Ingham } 3598314c525SJim Ingham 3608314c525SJim Ingham void 3618314c525SJim Ingham Debugger::Clear() 3628314c525SJim Ingham { 3633d6086f6SCaroline Tice CleanUpInputReaders(); 3641ed54f50SGreg Clayton m_listener.Clear(); 3656611103cSGreg Clayton int num_targets = m_target_list.GetNumTargets(); 3666611103cSGreg Clayton for (int i = 0; i < num_targets; i++) 3676611103cSGreg Clayton { 368ccbc08e6SGreg Clayton TargetSP target_sp (m_target_list.GetTargetAtIndex (i)); 369ccbc08e6SGreg Clayton if (target_sp) 370ccbc08e6SGreg Clayton { 371ccbc08e6SGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 3726611103cSGreg Clayton if (process_sp) 3738314c525SJim Ingham { 374e24c4acfSGreg Clayton if (process_sp->GetShouldDetach()) 3758314c525SJim Ingham process_sp->Detach(); 376ccbc08e6SGreg Clayton } 377ccbc08e6SGreg Clayton target_sp->Destroy(); 3786611103cSGreg Clayton } 37930fdc8d8SChris Lattner } 3804bddaeb5SJim Ingham BroadcasterManager::Clear (); 3818314c525SJim Ingham DisconnectInput(); 38230fdc8d8SChris Lattner 3838314c525SJim Ingham } 38430fdc8d8SChris Lattner 38530fdc8d8SChris Lattner bool 386fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const 387fc3f027dSGreg Clayton { 388fc3f027dSGreg Clayton return m_input_comm.GetCloseOnEOF(); 389fc3f027dSGreg Clayton } 390fc3f027dSGreg Clayton 391fc3f027dSGreg Clayton void 392fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b) 393fc3f027dSGreg Clayton { 394fc3f027dSGreg Clayton m_input_comm.SetCloseOnEOF(b); 395fc3f027dSGreg Clayton } 396fc3f027dSGreg Clayton 397fc3f027dSGreg Clayton bool 39830fdc8d8SChris Lattner Debugger::GetAsyncExecution () 39930fdc8d8SChris Lattner { 4006611103cSGreg Clayton return !m_command_interpreter_ap->GetSynchronous(); 40130fdc8d8SChris Lattner } 40230fdc8d8SChris Lattner 40330fdc8d8SChris Lattner void 40430fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution) 40530fdc8d8SChris Lattner { 4066611103cSGreg Clayton m_command_interpreter_ap->SetSynchronous (!async_execution); 40730fdc8d8SChris Lattner } 40830fdc8d8SChris Lattner 40930fdc8d8SChris Lattner 41030fdc8d8SChris Lattner void 41130fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership) 41230fdc8d8SChris Lattner { 41351b1e2d2SGreg Clayton File &in_file = GetInputFile(); 41451b1e2d2SGreg Clayton in_file.SetStream (fh, tranfer_ownership); 41551b1e2d2SGreg Clayton if (in_file.IsValid() == false) 41651b1e2d2SGreg Clayton in_file.SetStream (stdin, true); 41730fdc8d8SChris Lattner 41830fdc8d8SChris Lattner // Disconnect from any old connection if we had one 41930fdc8d8SChris Lattner m_input_comm.Disconnect (); 42032720b51SGreg Clayton // Pass false as the second argument to ConnectionFileDescriptor below because 42132720b51SGreg Clayton // our "in_file" above will already take ownership if requested and we don't 42232720b51SGreg Clayton // want to objects trying to own and close a file descriptor. 42332720b51SGreg Clayton m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false)); 42430fdc8d8SChris Lattner m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this); 42530fdc8d8SChris Lattner 42630fdc8d8SChris Lattner Error error; 42730fdc8d8SChris Lattner if (m_input_comm.StartReadThread (&error) == false) 42830fdc8d8SChris Lattner { 42951b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 43051b1e2d2SGreg Clayton 43151b1e2d2SGreg Clayton err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error"); 43230fdc8d8SChris Lattner exit(1); 43330fdc8d8SChris Lattner } 43430fdc8d8SChris Lattner } 43530fdc8d8SChris Lattner 43630fdc8d8SChris Lattner void 43730fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership) 43830fdc8d8SChris Lattner { 43951b1e2d2SGreg Clayton File &out_file = GetOutputFile(); 44051b1e2d2SGreg Clayton out_file.SetStream (fh, tranfer_ownership); 44151b1e2d2SGreg Clayton if (out_file.IsValid() == false) 44251b1e2d2SGreg Clayton out_file.SetStream (stdout, false); 4432f88aadfSCaroline Tice 4442f88aadfSCaroline Tice GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh); 44530fdc8d8SChris Lattner } 44630fdc8d8SChris Lattner 44730fdc8d8SChris Lattner void 44830fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership) 44930fdc8d8SChris Lattner { 45051b1e2d2SGreg Clayton File &err_file = GetErrorFile(); 45151b1e2d2SGreg Clayton err_file.SetStream (fh, tranfer_ownership); 45251b1e2d2SGreg Clayton if (err_file.IsValid() == false) 45351b1e2d2SGreg Clayton err_file.SetStream (stderr, false); 45430fdc8d8SChris Lattner } 45530fdc8d8SChris Lattner 45630fdc8d8SChris Lattner ExecutionContext 4572976d00aSJim Ingham Debugger::GetSelectedExecutionContext () 45830fdc8d8SChris Lattner { 45930fdc8d8SChris Lattner ExecutionContext exe_ctx; 460c14ee32dSGreg Clayton TargetSP target_sp(GetSelectedTarget()); 461c14ee32dSGreg Clayton exe_ctx.SetTargetSP (target_sp); 46230fdc8d8SChris Lattner 46330fdc8d8SChris Lattner if (target_sp) 46430fdc8d8SChris Lattner { 465c14ee32dSGreg Clayton ProcessSP process_sp (target_sp->GetProcessSP()); 466c14ee32dSGreg Clayton exe_ctx.SetProcessSP (process_sp); 467c14ee32dSGreg Clayton if (process_sp && process_sp->IsRunning() == false) 46830fdc8d8SChris Lattner { 469c14ee32dSGreg Clayton ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread()); 470c14ee32dSGreg Clayton if (thread_sp) 47130fdc8d8SChris Lattner { 472c14ee32dSGreg Clayton exe_ctx.SetThreadSP (thread_sp); 473c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame()); 474c14ee32dSGreg Clayton if (exe_ctx.GetFramePtr() == NULL) 475c14ee32dSGreg Clayton exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0)); 47630fdc8d8SChris Lattner } 47730fdc8d8SChris Lattner } 47830fdc8d8SChris Lattner } 47930fdc8d8SChris Lattner return exe_ctx; 48030fdc8d8SChris Lattner 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner 483b44880caSCaroline Tice InputReaderSP 484b44880caSCaroline Tice Debugger::GetCurrentInputReader () 485b44880caSCaroline Tice { 486b44880caSCaroline Tice InputReaderSP reader_sp; 487b44880caSCaroline Tice 488d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 489b44880caSCaroline Tice { 490b44880caSCaroline Tice // Clear any finished readers from the stack 491b44880caSCaroline Tice while (CheckIfTopInputReaderIsDone()) ; 492b44880caSCaroline Tice 493d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 494d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 495b44880caSCaroline Tice } 496b44880caSCaroline Tice 497b44880caSCaroline Tice return reader_sp; 498b44880caSCaroline Tice } 499b44880caSCaroline Tice 50030fdc8d8SChris Lattner void 50130fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len) 50230fdc8d8SChris Lattner { 503efed6131SCaroline Tice if (bytes_len > 0) 50430fdc8d8SChris Lattner ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len); 505efed6131SCaroline Tice else 506efed6131SCaroline Tice ((Debugger *)baton)->DispatchInputEndOfFile (); 50730fdc8d8SChris Lattner } 50830fdc8d8SChris Lattner 50930fdc8d8SChris Lattner 51030fdc8d8SChris Lattner void 51130fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len) 51230fdc8d8SChris Lattner { 513efed6131SCaroline Tice if (bytes == NULL || bytes_len == 0) 514efed6131SCaroline Tice return; 51530fdc8d8SChris Lattner 51630fdc8d8SChris Lattner WriteToDefaultReader (bytes, bytes_len); 51730fdc8d8SChris Lattner } 51830fdc8d8SChris Lattner 51930fdc8d8SChris Lattner void 520efed6131SCaroline Tice Debugger::DispatchInputInterrupt () 521efed6131SCaroline Tice { 522efed6131SCaroline Tice m_input_reader_data.clear(); 523efed6131SCaroline Tice 524b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 525efed6131SCaroline Tice if (reader_sp) 526b44880caSCaroline Tice { 527efed6131SCaroline Tice reader_sp->Notify (eInputReaderInterrupt); 528efed6131SCaroline Tice 529b44880caSCaroline Tice // If notifying the reader of the interrupt finished the reader, we should pop it off the stack. 530efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 531efed6131SCaroline Tice } 532efed6131SCaroline Tice } 533efed6131SCaroline Tice 534efed6131SCaroline Tice void 535efed6131SCaroline Tice Debugger::DispatchInputEndOfFile () 536efed6131SCaroline Tice { 537efed6131SCaroline Tice m_input_reader_data.clear(); 538efed6131SCaroline Tice 539b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 540efed6131SCaroline Tice if (reader_sp) 541b44880caSCaroline Tice { 542efed6131SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 543efed6131SCaroline Tice 544b44880caSCaroline Tice // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack. 545efed6131SCaroline Tice while (CheckIfTopInputReaderIsDone ()) ; 546efed6131SCaroline Tice } 547efed6131SCaroline Tice } 548efed6131SCaroline Tice 549efed6131SCaroline Tice void 5503d6086f6SCaroline Tice Debugger::CleanUpInputReaders () 5513d6086f6SCaroline Tice { 5523d6086f6SCaroline Tice m_input_reader_data.clear(); 5533d6086f6SCaroline Tice 554b44880caSCaroline Tice // The bottom input reader should be the main debugger input reader. We do not want to close that one here. 555d5a0a01bSCaroline Tice while (m_input_reader_stack.GetSize() > 1) 5563d6086f6SCaroline Tice { 557b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 5583d6086f6SCaroline Tice if (reader_sp) 5593d6086f6SCaroline Tice { 5603d6086f6SCaroline Tice reader_sp->Notify (eInputReaderEndOfFile); 5613d6086f6SCaroline Tice reader_sp->SetIsDone (true); 5623d6086f6SCaroline Tice } 5633d6086f6SCaroline Tice } 5643d6086f6SCaroline Tice } 5653d6086f6SCaroline Tice 5663d6086f6SCaroline Tice void 567969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification) 568969ed3d1SCaroline Tice { 569969ed3d1SCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader()); 570969ed3d1SCaroline Tice if (reader_sp) 571969ed3d1SCaroline Tice { 572969ed3d1SCaroline Tice reader_sp->Notify (notification); 573969ed3d1SCaroline Tice 574969ed3d1SCaroline Tice // Flush out any input readers that are done. 575969ed3d1SCaroline Tice while (CheckIfTopInputReaderIsDone ()) 576969ed3d1SCaroline Tice /* Do nothing. */; 577969ed3d1SCaroline Tice } 578969ed3d1SCaroline Tice } 579969ed3d1SCaroline Tice 5809088b068SCaroline Tice bool 5814d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp) 5829088b068SCaroline Tice { 5839088b068SCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader()); 5849088b068SCaroline Tice 585d61c10bcSCaroline Tice return (reader_sp.get() == top_reader_sp.get()); 5869088b068SCaroline Tice } 5879088b068SCaroline Tice 5889088b068SCaroline Tice 589969ed3d1SCaroline Tice void 59030fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len) 59130fdc8d8SChris Lattner { 59230fdc8d8SChris Lattner if (bytes && bytes_len) 59330fdc8d8SChris Lattner m_input_reader_data.append (bytes, bytes_len); 59430fdc8d8SChris Lattner 59530fdc8d8SChris Lattner if (m_input_reader_data.empty()) 59630fdc8d8SChris Lattner return; 59730fdc8d8SChris Lattner 598d5a0a01bSCaroline Tice while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty()) 59930fdc8d8SChris Lattner { 60030fdc8d8SChris Lattner // Get the input reader from the top of the stack 601b44880caSCaroline Tice InputReaderSP reader_sp (GetCurrentInputReader ()); 60230fdc8d8SChris Lattner if (!reader_sp) 60330fdc8d8SChris Lattner break; 60430fdc8d8SChris Lattner 605471b31ceSGreg Clayton size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(), 60630fdc8d8SChris Lattner m_input_reader_data.size()); 60730fdc8d8SChris Lattner if (bytes_handled) 60830fdc8d8SChris Lattner { 60930fdc8d8SChris Lattner m_input_reader_data.erase (0, bytes_handled); 61030fdc8d8SChris Lattner } 61130fdc8d8SChris Lattner else 61230fdc8d8SChris Lattner { 61330fdc8d8SChris Lattner // No bytes were handled, we might not have reached our 61430fdc8d8SChris Lattner // granularity, just return and wait for more data 61530fdc8d8SChris Lattner break; 61630fdc8d8SChris Lattner } 61730fdc8d8SChris Lattner } 61830fdc8d8SChris Lattner 619b44880caSCaroline Tice // Flush out any input readers that are done. 62030fdc8d8SChris Lattner while (CheckIfTopInputReaderIsDone ()) 62130fdc8d8SChris Lattner /* Do nothing. */; 62230fdc8d8SChris Lattner 62330fdc8d8SChris Lattner } 62430fdc8d8SChris Lattner 62530fdc8d8SChris Lattner void 62630fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp) 62730fdc8d8SChris Lattner { 62830fdc8d8SChris Lattner if (!reader_sp) 62930fdc8d8SChris Lattner return; 630b44880caSCaroline Tice 63130fdc8d8SChris Lattner // Deactivate the old top reader 632b44880caSCaroline Tice InputReaderSP top_reader_sp (GetCurrentInputReader ()); 633b44880caSCaroline Tice 63430fdc8d8SChris Lattner if (top_reader_sp) 63530fdc8d8SChris Lattner top_reader_sp->Notify (eInputReaderDeactivate); 636b44880caSCaroline Tice 637d5a0a01bSCaroline Tice m_input_reader_stack.Push (reader_sp); 63830fdc8d8SChris Lattner reader_sp->Notify (eInputReaderActivate); 63930fdc8d8SChris Lattner ActivateInputReader (reader_sp); 64030fdc8d8SChris Lattner } 64130fdc8d8SChris Lattner 64230fdc8d8SChris Lattner bool 6434d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp) 64430fdc8d8SChris Lattner { 64530fdc8d8SChris Lattner bool result = false; 64630fdc8d8SChris Lattner 64730fdc8d8SChris Lattner // The reader on the stop of the stack is done, so let the next 64830fdc8d8SChris Lattner // read on the stack referesh its prompt and if there is one... 649d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 65030fdc8d8SChris Lattner { 651b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 652d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 65330fdc8d8SChris Lattner 65430fdc8d8SChris Lattner if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) 65530fdc8d8SChris Lattner { 656d5a0a01bSCaroline Tice m_input_reader_stack.Pop (); 65730fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDeactivate); 65830fdc8d8SChris Lattner reader_sp->Notify (eInputReaderDone); 65930fdc8d8SChris Lattner result = true; 66030fdc8d8SChris Lattner 661d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 66230fdc8d8SChris Lattner { 663d5a0a01bSCaroline Tice reader_sp = m_input_reader_stack.Top(); 66430fdc8d8SChris Lattner if (reader_sp) 66530fdc8d8SChris Lattner { 66630fdc8d8SChris Lattner ActivateInputReader (reader_sp); 66730fdc8d8SChris Lattner reader_sp->Notify (eInputReaderReactivate); 66830fdc8d8SChris Lattner } 66930fdc8d8SChris Lattner } 67030fdc8d8SChris Lattner } 67130fdc8d8SChris Lattner } 67230fdc8d8SChris Lattner return result; 67330fdc8d8SChris Lattner } 67430fdc8d8SChris Lattner 67530fdc8d8SChris Lattner bool 67630fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone () 67730fdc8d8SChris Lattner { 67830fdc8d8SChris Lattner bool result = false; 679d5a0a01bSCaroline Tice if (!m_input_reader_stack.IsEmpty()) 68030fdc8d8SChris Lattner { 681b44880caSCaroline Tice // Cannot call GetCurrentInputReader here, as that would cause an infinite loop. 682d5a0a01bSCaroline Tice InputReaderSP reader_sp(m_input_reader_stack.Top()); 68330fdc8d8SChris Lattner 68430fdc8d8SChris Lattner if (reader_sp && reader_sp->IsDone()) 68530fdc8d8SChris Lattner { 68630fdc8d8SChris Lattner result = true; 68730fdc8d8SChris Lattner PopInputReader (reader_sp); 68830fdc8d8SChris Lattner } 68930fdc8d8SChris Lattner } 69030fdc8d8SChris Lattner return result; 69130fdc8d8SChris Lattner } 69230fdc8d8SChris Lattner 69330fdc8d8SChris Lattner void 69430fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp) 69530fdc8d8SChris Lattner { 69651b1e2d2SGreg Clayton int input_fd = m_input_file.GetFile().GetDescriptor(); 69730fdc8d8SChris Lattner 69851b1e2d2SGreg Clayton if (input_fd >= 0) 69930fdc8d8SChris Lattner { 70051b1e2d2SGreg Clayton Terminal tty(input_fd); 701a3406614SGreg Clayton 702a3406614SGreg Clayton tty.SetEcho(reader_sp->GetEcho()); 70330fdc8d8SChris Lattner 70430fdc8d8SChris Lattner switch (reader_sp->GetGranularity()) 70530fdc8d8SChris Lattner { 70630fdc8d8SChris Lattner case eInputReaderGranularityByte: 70730fdc8d8SChris Lattner case eInputReaderGranularityWord: 708a3406614SGreg Clayton tty.SetCanonical (false); 70930fdc8d8SChris Lattner break; 71030fdc8d8SChris Lattner 71130fdc8d8SChris Lattner case eInputReaderGranularityLine: 71230fdc8d8SChris Lattner case eInputReaderGranularityAll: 713a3406614SGreg Clayton tty.SetCanonical (true); 71430fdc8d8SChris Lattner break; 71530fdc8d8SChris Lattner 71630fdc8d8SChris Lattner default: 71730fdc8d8SChris Lattner break; 71830fdc8d8SChris Lattner } 71930fdc8d8SChris Lattner } 72030fdc8d8SChris Lattner } 7216611103cSGreg Clayton 7225b52f0c7SJim Ingham StreamSP 7235b52f0c7SJim Ingham Debugger::GetAsyncOutputStream () 7245b52f0c7SJim Ingham { 7255b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 7265b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousOutputData)); 7275b52f0c7SJim Ingham } 7285b52f0c7SJim Ingham 7295b52f0c7SJim Ingham StreamSP 7305b52f0c7SJim Ingham Debugger::GetAsyncErrorStream () 7315b52f0c7SJim Ingham { 7325b52f0c7SJim Ingham return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(), 7335b52f0c7SJim Ingham CommandInterpreter::eBroadcastBitAsynchronousErrorData)); 7345b52f0c7SJim Ingham } 7355b52f0c7SJim Ingham 736061858ceSEnrico Granata uint32_t 737061858ceSEnrico Granata Debugger::GetNumDebuggers() 738061858ceSEnrico Granata { 739061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 740061858ceSEnrico Granata return GetDebuggerList().size(); 741061858ceSEnrico Granata } 742061858ceSEnrico Granata 743061858ceSEnrico Granata lldb::DebuggerSP 744061858ceSEnrico Granata Debugger::GetDebuggerAtIndex (uint32_t index) 745061858ceSEnrico Granata { 746061858ceSEnrico Granata DebuggerSP debugger_sp; 747061858ceSEnrico Granata 748061858ceSEnrico Granata Mutex::Locker locker (GetDebuggerListMutex ()); 749061858ceSEnrico Granata DebuggerList &debugger_list = GetDebuggerList(); 750061858ceSEnrico Granata 751061858ceSEnrico Granata if (index < debugger_list.size()) 752061858ceSEnrico Granata debugger_sp = debugger_list[index]; 753061858ceSEnrico Granata 754061858ceSEnrico Granata return debugger_sp; 755061858ceSEnrico Granata } 756061858ceSEnrico Granata 757ebc1bb27SCaroline Tice DebuggerSP 758ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id) 759ebc1bb27SCaroline Tice { 7604d122c40SGreg Clayton DebuggerSP debugger_sp; 761ebc1bb27SCaroline Tice 762ebc1bb27SCaroline Tice Mutex::Locker locker (GetDebuggerListMutex ()); 763ebc1bb27SCaroline Tice DebuggerList &debugger_list = GetDebuggerList(); 764ebc1bb27SCaroline Tice DebuggerList::iterator pos, end = debugger_list.end(); 765ebc1bb27SCaroline Tice for (pos = debugger_list.begin(); pos != end; ++pos) 766ebc1bb27SCaroline Tice { 767ebc1bb27SCaroline Tice if ((*pos).get()->GetID() == id) 768ebc1bb27SCaroline Tice { 769ebc1bb27SCaroline Tice debugger_sp = *pos; 770ebc1bb27SCaroline Tice break; 771ebc1bb27SCaroline Tice } 772ebc1bb27SCaroline Tice } 773ebc1bb27SCaroline Tice return debugger_sp; 774ebc1bb27SCaroline Tice } 7753df9a8dfSCaroline Tice 7761b654882SGreg Clayton static void 7771b654882SGreg Clayton TestPromptFormats (StackFrame *frame) 7781b654882SGreg Clayton { 7791b654882SGreg Clayton if (frame == NULL) 7801b654882SGreg Clayton return; 7811b654882SGreg Clayton 7821b654882SGreg Clayton StreamString s; 7831b654882SGreg Clayton const char *prompt_format = 7841b654882SGreg Clayton "{addr = '${addr}'\n}" 7851b654882SGreg Clayton "{process.id = '${process.id}'\n}" 7861b654882SGreg Clayton "{process.name = '${process.name}'\n}" 7871b654882SGreg Clayton "{process.file.basename = '${process.file.basename}'\n}" 7881b654882SGreg Clayton "{process.file.fullpath = '${process.file.fullpath}'\n}" 7891b654882SGreg Clayton "{thread.id = '${thread.id}'\n}" 7901b654882SGreg Clayton "{thread.index = '${thread.index}'\n}" 7911b654882SGreg Clayton "{thread.name = '${thread.name}'\n}" 7921b654882SGreg Clayton "{thread.queue = '${thread.queue}'\n}" 7931b654882SGreg Clayton "{thread.stop-reason = '${thread.stop-reason}'\n}" 7941b654882SGreg Clayton "{target.arch = '${target.arch}'\n}" 7951b654882SGreg Clayton "{module.file.basename = '${module.file.basename}'\n}" 7961b654882SGreg Clayton "{module.file.fullpath = '${module.file.fullpath}'\n}" 7971b654882SGreg Clayton "{file.basename = '${file.basename}'\n}" 7981b654882SGreg Clayton "{file.fullpath = '${file.fullpath}'\n}" 7991b654882SGreg Clayton "{frame.index = '${frame.index}'\n}" 8001b654882SGreg Clayton "{frame.pc = '${frame.pc}'\n}" 8011b654882SGreg Clayton "{frame.sp = '${frame.sp}'\n}" 8021b654882SGreg Clayton "{frame.fp = '${frame.fp}'\n}" 8031b654882SGreg Clayton "{frame.flags = '${frame.flags}'\n}" 8041b654882SGreg Clayton "{frame.reg.rdi = '${frame.reg.rdi}'\n}" 8051b654882SGreg Clayton "{frame.reg.rip = '${frame.reg.rip}'\n}" 8061b654882SGreg Clayton "{frame.reg.rsp = '${frame.reg.rsp}'\n}" 8071b654882SGreg Clayton "{frame.reg.rbp = '${frame.reg.rbp}'\n}" 8081b654882SGreg Clayton "{frame.reg.rflags = '${frame.reg.rflags}'\n}" 8091b654882SGreg Clayton "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}" 8101b654882SGreg Clayton "{frame.reg.carp = '${frame.reg.carp}'\n}" 8111b654882SGreg Clayton "{function.id = '${function.id}'\n}" 8121b654882SGreg Clayton "{function.name = '${function.name}'\n}" 813ccbc08e6SGreg Clayton "{function.name-with-args = '${function.name-with-args}'\n}" 8141b654882SGreg Clayton "{function.addr-offset = '${function.addr-offset}'\n}" 8151b654882SGreg Clayton "{function.line-offset = '${function.line-offset}'\n}" 8161b654882SGreg Clayton "{function.pc-offset = '${function.pc-offset}'\n}" 8171b654882SGreg Clayton "{line.file.basename = '${line.file.basename}'\n}" 8181b654882SGreg Clayton "{line.file.fullpath = '${line.file.fullpath}'\n}" 8191b654882SGreg Clayton "{line.number = '${line.number}'\n}" 8201b654882SGreg Clayton "{line.start-addr = '${line.start-addr}'\n}" 8211b654882SGreg Clayton "{line.end-addr = '${line.end-addr}'\n}" 8221b654882SGreg Clayton ; 8231b654882SGreg Clayton 8241b654882SGreg Clayton SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything)); 8251b654882SGreg Clayton ExecutionContext exe_ctx; 8260603aa9dSGreg Clayton frame->CalculateExecutionContext(exe_ctx); 8271b654882SGreg Clayton const char *end = NULL; 8281b654882SGreg Clayton if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end)) 8291b654882SGreg Clayton { 8301b654882SGreg Clayton printf("%s\n", s.GetData()); 8311b654882SGreg Clayton } 8321b654882SGreg Clayton else 8331b654882SGreg Clayton { 8341b654882SGreg Clayton printf ("error: at '%s'\n", end); 8351b654882SGreg Clayton printf ("what we got: %s\n", s.GetData()); 8361b654882SGreg Clayton } 8371b654882SGreg Clayton } 8381b654882SGreg Clayton 8399fc1944eSEnrico Granata static bool 8409fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin, 8419fc1944eSEnrico Granata const char* var_name_end, 8429fc1944eSEnrico Granata const char** var_name_final, 8439fc1944eSEnrico Granata const char** percent_position, 8444d122c40SGreg Clayton Format* custom_format, 8459fc1944eSEnrico Granata ValueObject::ValueObjectRepresentationStyle* val_obj_display) 8469fc1944eSEnrico Granata { 847e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 8489fc1944eSEnrico Granata *percent_position = ::strchr(var_name_begin,'%'); 8499fc1944eSEnrico Granata if (!*percent_position || *percent_position > var_name_end) 850e992a089SEnrico Granata { 851e992a089SEnrico Granata if (log) 852e992a089SEnrico Granata log->Printf("no format descriptor in string, skipping"); 8539fc1944eSEnrico Granata *var_name_final = var_name_end; 854e992a089SEnrico Granata } 8559fc1944eSEnrico Granata else 8569fc1944eSEnrico Granata { 8579fc1944eSEnrico Granata *var_name_final = *percent_position; 8589fc1944eSEnrico Granata char* format_name = new char[var_name_end-*var_name_final]; format_name[var_name_end-*var_name_final-1] = '\0'; 8599fc1944eSEnrico Granata memcpy(format_name, *var_name_final+1, var_name_end-*var_name_final-1); 860e992a089SEnrico Granata if (log) 861e992a089SEnrico Granata log->Printf("parsing %s as a format descriptor", format_name); 8629fc1944eSEnrico Granata if ( !FormatManager::GetFormatFromCString(format_name, 8639fc1944eSEnrico Granata true, 8649fc1944eSEnrico Granata *custom_format) ) 8659fc1944eSEnrico Granata { 866e992a089SEnrico Granata if (log) 867e992a089SEnrico Granata log->Printf("%s is an unknown format", format_name); 8689fc1944eSEnrico Granata // if this is an @ sign, print ObjC description 8699fc1944eSEnrico Granata if (*format_name == '@') 87086cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific; 8719fc1944eSEnrico Granata // if this is a V, print the value using the default format 872e992a089SEnrico Granata else if (*format_name == 'V') 87386cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 874d55546b2SEnrico Granata // if this is an L, print the location of the value 875e992a089SEnrico Granata else if (*format_name == 'L') 87686cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation; 877d55546b2SEnrico Granata // if this is an S, print the summary after all 878e992a089SEnrico Granata else if (*format_name == 'S') 87986cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 8805dfd49ccSEnrico Granata else if (*format_name == '#') 88186cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount; 882d64d0bc0SEnrico Granata else if (*format_name == 'T') 88386cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleType; 884e992a089SEnrico Granata else if (log) 885e992a089SEnrico Granata log->Printf("%s is an error, leaving the previous value alone", format_name); 8869fc1944eSEnrico Granata } 8879fc1944eSEnrico Granata // a good custom format tells us to print the value using it 8889fc1944eSEnrico Granata else 889e992a089SEnrico Granata { 890e992a089SEnrico Granata if (log) 891e992a089SEnrico Granata log->Printf("will display value for this VO"); 89286cc9829SEnrico Granata *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 893e992a089SEnrico Granata } 8949fc1944eSEnrico Granata delete format_name; 8959fc1944eSEnrico Granata } 896e992a089SEnrico Granata if (log) 897e992a089SEnrico Granata log->Printf("final format description outcome: custom_format = %d, val_obj_display = %d", 898e992a089SEnrico Granata *custom_format, 899e992a089SEnrico Granata *val_obj_display); 9009fc1944eSEnrico Granata return true; 9019fc1944eSEnrico Granata } 9029fc1944eSEnrico Granata 9039fc1944eSEnrico Granata static bool 9049fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin, 9059fc1944eSEnrico Granata const char* var_name_end, 9069fc1944eSEnrico Granata const char* var_name_final, 9079fc1944eSEnrico Granata const char** open_bracket_position, 9089fc1944eSEnrico Granata const char** separator_position, 9099fc1944eSEnrico Granata const char** close_bracket_position, 9109fc1944eSEnrico Granata const char** var_name_final_if_array_range, 9119fc1944eSEnrico Granata int64_t* index_lower, 9129fc1944eSEnrico Granata int64_t* index_higher) 9139fc1944eSEnrico Granata { 914e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 9159fc1944eSEnrico Granata *open_bracket_position = ::strchr(var_name_begin,'['); 9169fc1944eSEnrico Granata if (*open_bracket_position && *open_bracket_position < var_name_final) 9179fc1944eSEnrico Granata { 9189fc1944eSEnrico Granata *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield 9199fc1944eSEnrico Granata *close_bracket_position = ::strchr(*open_bracket_position,']'); 9209fc1944eSEnrico Granata // as usual, we assume that [] will come before % 9219fc1944eSEnrico Granata //printf("trying to expand a []\n"); 9229fc1944eSEnrico Granata *var_name_final_if_array_range = *open_bracket_position; 9239fc1944eSEnrico Granata if (*close_bracket_position - *open_bracket_position == 1) 9249fc1944eSEnrico Granata { 925e992a089SEnrico Granata if (log) 926e992a089SEnrico Granata log->Printf("[] detected.. going from 0 to end of data"); 9279fc1944eSEnrico Granata *index_lower = 0; 9289fc1944eSEnrico Granata } 9299fc1944eSEnrico Granata else if (*separator_position == NULL || *separator_position > var_name_end) 9309fc1944eSEnrico Granata { 9319fc1944eSEnrico Granata char *end = NULL; 9329fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 9339fc1944eSEnrico Granata *index_higher = *index_lower; 934e992a089SEnrico Granata if (log) 935fd54b368SJason Molenda log->Printf("[%lld] detected, high index is same", *index_lower); 9369fc1944eSEnrico Granata } 9379fc1944eSEnrico Granata else if (*close_bracket_position && *close_bracket_position < var_name_end) 9389fc1944eSEnrico Granata { 9399fc1944eSEnrico Granata char *end = NULL; 9409fc1944eSEnrico Granata *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); 9419fc1944eSEnrico Granata *index_higher = ::strtoul (*separator_position+1, &end, 0); 942e992a089SEnrico Granata if (log) 943fd54b368SJason Molenda log->Printf("[%lld-%lld] detected", *index_lower, *index_higher); 9449fc1944eSEnrico Granata } 9459fc1944eSEnrico Granata else 946e992a089SEnrico Granata { 947e992a089SEnrico Granata if (log) 948e992a089SEnrico Granata log->Printf("expression is erroneous, cannot extract indices out of it"); 9499fc1944eSEnrico Granata return false; 950e992a089SEnrico Granata } 9519fc1944eSEnrico Granata if (*index_lower > *index_higher && *index_higher > 0) 9529fc1944eSEnrico Granata { 953e992a089SEnrico Granata if (log) 954e992a089SEnrico Granata log->Printf("swapping indices"); 9559fc1944eSEnrico Granata int temp = *index_lower; 9569fc1944eSEnrico Granata *index_lower = *index_higher; 9579fc1944eSEnrico Granata *index_higher = temp; 9589fc1944eSEnrico Granata } 9599fc1944eSEnrico Granata } 960e992a089SEnrico Granata else if (log) 961e992a089SEnrico Granata log->Printf("no bracketed range, skipping entirely"); 9629fc1944eSEnrico Granata return true; 9639fc1944eSEnrico Granata } 9649fc1944eSEnrico Granata 9659fc1944eSEnrico Granata 9669fc1944eSEnrico Granata static ValueObjectSP 967c482a192SEnrico Granata ExpandExpressionPath (ValueObject* valobj, 9689fc1944eSEnrico Granata StackFrame* frame, 9699fc1944eSEnrico Granata bool* do_deref_pointer, 9709fc1944eSEnrico Granata const char* var_name_begin, 9719fc1944eSEnrico Granata const char* var_name_final, 9729fc1944eSEnrico Granata Error& error) 9739fc1944eSEnrico Granata { 974e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 9759fc1944eSEnrico Granata StreamString sstring; 9769fc1944eSEnrico Granata VariableSP var_sp; 9779fc1944eSEnrico Granata 9789fc1944eSEnrico Granata if (*do_deref_pointer) 979e992a089SEnrico Granata { 980e992a089SEnrico Granata if (log) 981e992a089SEnrico Granata log->Printf("been told to deref_pointer by caller"); 9829fc1944eSEnrico Granata sstring.PutChar('*'); 983e992a089SEnrico Granata } 984c482a192SEnrico Granata else if (valobj->IsDereferenceOfParent() && ClangASTContext::IsPointerType(valobj->GetParent()->GetClangType()) && !valobj->IsArrayItemForPointer()) 9859fc1944eSEnrico Granata { 986e992a089SEnrico Granata if (log) 987e992a089SEnrico Granata log->Printf("decided to deref_pointer myself"); 9889fc1944eSEnrico Granata sstring.PutChar('*'); 9899fc1944eSEnrico Granata *do_deref_pointer = true; 9909fc1944eSEnrico Granata } 9919fc1944eSEnrico Granata 99286cc9829SEnrico Granata valobj->GetExpressionPath(sstring, true, ValueObject::eGetExpressionPathFormatHonorPointers); 993e992a089SEnrico Granata if (log) 994e992a089SEnrico Granata log->Printf("expression path to expand in phase 0: %s",sstring.GetData()); 9959fc1944eSEnrico Granata sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3); 996e992a089SEnrico Granata if (log) 997e992a089SEnrico Granata log->Printf("expression path to expand in phase 1: %s",sstring.GetData()); 9989fc1944eSEnrico Granata std::string name = std::string(sstring.GetData()); 9999fc1944eSEnrico Granata ValueObjectSP target = frame->GetValueForVariableExpressionPath (name.c_str(), 10009fc1944eSEnrico Granata eNoDynamicValues, 10019fc1944eSEnrico Granata 0, 10029fc1944eSEnrico Granata var_sp, 10039fc1944eSEnrico Granata error); 10049fc1944eSEnrico Granata return target; 10059fc1944eSEnrico Granata } 10069fc1944eSEnrico Granata 10079fc1944eSEnrico Granata static ValueObjectSP 1008c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj, 10099fc1944eSEnrico Granata uint32_t index, 10109fc1944eSEnrico Granata StackFrame* frame, 1011fc7a7f3bSEnrico Granata bool deref_pointer) 10129fc1944eSEnrico Granata { 1013e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 1014fc7a7f3bSEnrico Granata const char* ptr_deref_format = "[%d]"; 1015fc7a7f3bSEnrico Granata std::auto_ptr<char> ptr_deref_buffer(new char[10]); 1016fc7a7f3bSEnrico Granata ::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index); 1017e992a089SEnrico Granata if (log) 1018e992a089SEnrico Granata log->Printf("name to deref: %s",ptr_deref_buffer.get()); 1019fc7a7f3bSEnrico Granata const char* first_unparsed; 1020fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 1021fc7a7f3bSEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type; 1022fc7a7f3bSEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop; 102386cc9829SEnrico Granata ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1024c482a192SEnrico Granata ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.get(), 1025fc7a7f3bSEnrico Granata &first_unparsed, 1026fc7a7f3bSEnrico Granata &reason_to_stop, 1027fc7a7f3bSEnrico Granata &final_value_type, 1028fc7a7f3bSEnrico Granata options, 1029fc7a7f3bSEnrico Granata &what_next); 1030fc7a7f3bSEnrico Granata if (!item) 1031fc7a7f3bSEnrico Granata { 1032e992a089SEnrico Granata if (log) 1033e992a089SEnrico Granata log->Printf("ERROR: unparsed portion = %s, why stopping = %d," 1034e992a089SEnrico Granata " final_value_type %d", 1035fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1036fc7a7f3bSEnrico Granata } 10379fc1944eSEnrico Granata else 10389fc1944eSEnrico Granata { 1039e992a089SEnrico Granata if (log) 1040e992a089SEnrico Granata log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d," 1041e992a089SEnrico Granata " final_value_type %d", 1042fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 10439fc1944eSEnrico Granata } 10449fc1944eSEnrico Granata return item; 10459fc1944eSEnrico Granata } 10469fc1944eSEnrico Granata 10471b654882SGreg Clayton bool 10481b654882SGreg Clayton Debugger::FormatPrompt 10491b654882SGreg Clayton ( 10501b654882SGreg Clayton const char *format, 10511b654882SGreg Clayton const SymbolContext *sc, 10521b654882SGreg Clayton const ExecutionContext *exe_ctx, 10531b654882SGreg Clayton const Address *addr, 10541b654882SGreg Clayton Stream &s, 10554becb37eSEnrico Granata const char **end, 1056c482a192SEnrico Granata ValueObject* valobj 10571b654882SGreg Clayton ) 10581b654882SGreg Clayton { 1059c482a192SEnrico Granata ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers 10601b654882SGreg Clayton bool success = true; 10611b654882SGreg Clayton const char *p; 1062e992a089SEnrico Granata LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 10631b654882SGreg Clayton for (p = format; *p != '\0'; ++p) 10641b654882SGreg Clayton { 1065c482a192SEnrico Granata if (realvalobj) 10664becb37eSEnrico Granata { 1067c482a192SEnrico Granata valobj = realvalobj; 1068c482a192SEnrico Granata realvalobj = NULL; 10694becb37eSEnrico Granata } 10701b654882SGreg Clayton size_t non_special_chars = ::strcspn (p, "${}\\"); 10711b654882SGreg Clayton if (non_special_chars > 0) 10721b654882SGreg Clayton { 10731b654882SGreg Clayton if (success) 10741b654882SGreg Clayton s.Write (p, non_special_chars); 10751b654882SGreg Clayton p += non_special_chars; 10761b654882SGreg Clayton } 10771b654882SGreg Clayton 10781b654882SGreg Clayton if (*p == '\0') 10791b654882SGreg Clayton { 10801b654882SGreg Clayton break; 10811b654882SGreg Clayton } 10821b654882SGreg Clayton else if (*p == '{') 10831b654882SGreg Clayton { 10841b654882SGreg Clayton // Start a new scope that must have everything it needs if it is to 10851b654882SGreg Clayton // to make it into the final output stream "s". If you want to make 10861b654882SGreg Clayton // a format that only prints out the function or symbol name if there 10871b654882SGreg Clayton // is one in the symbol context you can use: 10881b654882SGreg Clayton // "{function =${function.name}}" 10891b654882SGreg Clayton // The first '{' starts a new scope that end with the matching '}' at 10901b654882SGreg Clayton // the end of the string. The contents "function =${function.name}" 10911b654882SGreg Clayton // will then be evaluated and only be output if there is a function 10921b654882SGreg Clayton // or symbol with a valid name. 10931b654882SGreg Clayton StreamString sub_strm; 10941b654882SGreg Clayton 10951b654882SGreg Clayton ++p; // Skip the '{' 10961b654882SGreg Clayton 1097c482a192SEnrico Granata if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj)) 10981b654882SGreg Clayton { 10991b654882SGreg Clayton // The stream had all it needed 11001b654882SGreg Clayton s.Write(sub_strm.GetData(), sub_strm.GetSize()); 11011b654882SGreg Clayton } 11021b654882SGreg Clayton if (*p != '}') 11031b654882SGreg Clayton { 11041b654882SGreg Clayton success = false; 11051b654882SGreg Clayton break; 11061b654882SGreg Clayton } 11071b654882SGreg Clayton } 11081b654882SGreg Clayton else if (*p == '}') 11091b654882SGreg Clayton { 11101b654882SGreg Clayton // End of a enclosing scope 11111b654882SGreg Clayton break; 11121b654882SGreg Clayton } 11131b654882SGreg Clayton else if (*p == '$') 11141b654882SGreg Clayton { 11151b654882SGreg Clayton // We have a prompt variable to print 11161b654882SGreg Clayton ++p; 11171b654882SGreg Clayton if (*p == '{') 11181b654882SGreg Clayton { 11191b654882SGreg Clayton ++p; 11201b654882SGreg Clayton const char *var_name_begin = p; 11211b654882SGreg Clayton const char *var_name_end = ::strchr (p, '}'); 11221b654882SGreg Clayton 11231b654882SGreg Clayton if (var_name_end && var_name_begin < var_name_end) 11241b654882SGreg Clayton { 11251b654882SGreg Clayton // if we have already failed to parse, skip this variable 11261b654882SGreg Clayton if (success) 11271b654882SGreg Clayton { 11281b654882SGreg Clayton const char *cstr = NULL; 11291b654882SGreg Clayton Address format_addr; 11301b654882SGreg Clayton bool calculate_format_addr_function_offset = false; 11311b654882SGreg Clayton // Set reg_kind and reg_num to invalid values 11321b654882SGreg Clayton RegisterKind reg_kind = kNumRegisterKinds; 11331b654882SGreg Clayton uint32_t reg_num = LLDB_INVALID_REGNUM; 11341b654882SGreg Clayton FileSpec format_file_spec; 1135e0d378b3SGreg Clayton const RegisterInfo *reg_info = NULL; 11361b654882SGreg Clayton RegisterContext *reg_ctx = NULL; 11379fc1944eSEnrico Granata bool do_deref_pointer = false; 113886cc9829SEnrico Granata ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 113986cc9829SEnrico Granata ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain; 11401b654882SGreg Clayton 11411b654882SGreg Clayton // Each variable must set success to true below... 11421b654882SGreg Clayton bool var_success = false; 11431b654882SGreg Clayton switch (var_name_begin[0]) 11441b654882SGreg Clayton { 11454becb37eSEnrico Granata case '*': 11466f3533fbSEnrico Granata case 'v': 11476f3533fbSEnrico Granata case 's': 11484becb37eSEnrico Granata { 1149c482a192SEnrico Granata if (!valobj) 115034132754SGreg Clayton break; 11516f3533fbSEnrico Granata 1152c3e320a7SEnrico Granata if (log) 1153c3e320a7SEnrico Granata log->Printf("initial string: %s",var_name_begin); 1154c3e320a7SEnrico Granata 11556f3533fbSEnrico Granata // check for *var and *svar 11566f3533fbSEnrico Granata if (*var_name_begin == '*') 11576f3533fbSEnrico Granata { 11589fc1944eSEnrico Granata do_deref_pointer = true; 11599fc1944eSEnrico Granata var_name_begin++; 11609fc1944eSEnrico Granata } 1161c3e320a7SEnrico Granata 1162c3e320a7SEnrico Granata if (log) 1163c3e320a7SEnrico Granata log->Printf("initial string: %s",var_name_begin); 1164c3e320a7SEnrico Granata 11656f3533fbSEnrico Granata if (*var_name_begin == 's') 11664becb37eSEnrico Granata { 1167*c5bc412cSEnrico Granata if (!valobj->IsSynthetic()) 116886cc9829SEnrico Granata valobj = valobj->GetSyntheticValue().get(); 116986cc9829SEnrico Granata if (!valobj) 117086cc9829SEnrico Granata break; 11716f3533fbSEnrico Granata var_name_begin++; 11726f3533fbSEnrico Granata } 11736f3533fbSEnrico Granata 1174c3e320a7SEnrico Granata if (log) 1175c3e320a7SEnrico Granata log->Printf("initial string: %s",var_name_begin); 1176c3e320a7SEnrico Granata 11776f3533fbSEnrico Granata // should be a 'v' by now 11786f3533fbSEnrico Granata if (*var_name_begin != 'v') 11796f3533fbSEnrico Granata break; 11806f3533fbSEnrico Granata 1181c3e320a7SEnrico Granata if (log) 1182c3e320a7SEnrico Granata log->Printf("initial string: %s",var_name_begin); 1183c3e320a7SEnrico Granata 1184fc7a7f3bSEnrico Granata ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ? 118586cc9829SEnrico Granata ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing); 1186fc7a7f3bSEnrico Granata ValueObject::GetValueForExpressionPathOptions options; 11878c9d3560SEnrico Granata options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren(); 118886cc9829SEnrico Granata ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary; 118934132754SGreg Clayton ValueObject* target = NULL; 11904d122c40SGreg Clayton Format custom_format = eFormatInvalid; 119134132754SGreg Clayton const char* var_name_final = NULL; 11929fc1944eSEnrico Granata const char* var_name_final_if_array_range = NULL; 119334132754SGreg Clayton const char* close_bracket_position = NULL; 119434132754SGreg Clayton int64_t index_lower = -1; 119534132754SGreg Clayton int64_t index_higher = -1; 11969fc1944eSEnrico Granata bool is_array_range = false; 1197fc7a7f3bSEnrico Granata const char* first_unparsed; 119885933ed4SEnrico Granata bool was_plain_var = false; 119985933ed4SEnrico Granata bool was_var_format = false; 1200fc7a7f3bSEnrico Granata 1201c482a192SEnrico Granata if (!valobj) break; 1202c482a192SEnrico Granata // simplest case ${var}, just print valobj's value 12039fc1944eSEnrico Granata if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) 12040a3958e0SEnrico Granata { 120585933ed4SEnrico Granata was_plain_var = true; 1206c482a192SEnrico Granata target = valobj; 120786cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 12080a3958e0SEnrico Granata } 12099fc1944eSEnrico Granata else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) 12109fc1944eSEnrico Granata { 121185933ed4SEnrico Granata was_var_format = true; 12129fc1944eSEnrico Granata // this is a variable with some custom format applied to it 12139fc1944eSEnrico Granata const char* percent_position; 1214c482a192SEnrico Granata target = valobj; 121586cc9829SEnrico Granata val_obj_display = ValueObject::eValueObjectRepresentationStyleValue; 12169fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 12179fc1944eSEnrico Granata var_name_end, 12189fc1944eSEnrico Granata &var_name_final, 12199fc1944eSEnrico Granata &percent_position, 12209fc1944eSEnrico Granata &custom_format, 12219fc1944eSEnrico Granata &val_obj_display); 12220a3958e0SEnrico Granata } 12239fc1944eSEnrico Granata // this is ${var.something} or multiple .something nested 12249fc1944eSEnrico Granata else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) 12259fc1944eSEnrico Granata { 12269fc1944eSEnrico Granata 12279fc1944eSEnrico Granata const char* percent_position; 12289fc1944eSEnrico Granata ScanFormatDescriptor (var_name_begin, 12299fc1944eSEnrico Granata var_name_end, 12309fc1944eSEnrico Granata &var_name_final, 12319fc1944eSEnrico Granata &percent_position, 12329fc1944eSEnrico Granata &custom_format, 12339fc1944eSEnrico Granata &val_obj_display); 12349fc1944eSEnrico Granata 12359fc1944eSEnrico Granata const char* open_bracket_position; 12369fc1944eSEnrico Granata const char* separator_position; 12379fc1944eSEnrico Granata ScanBracketedRange (var_name_begin, 12389fc1944eSEnrico Granata var_name_end, 12399fc1944eSEnrico Granata var_name_final, 12409fc1944eSEnrico Granata &open_bracket_position, 12419fc1944eSEnrico Granata &separator_position, 12429fc1944eSEnrico Granata &close_bracket_position, 12439fc1944eSEnrico Granata &var_name_final_if_array_range, 12449fc1944eSEnrico Granata &index_lower, 12459fc1944eSEnrico Granata &index_higher); 12469fc1944eSEnrico Granata 12479fc1944eSEnrico Granata Error error; 12489fc1944eSEnrico Granata 1249fc7a7f3bSEnrico Granata std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]); 1250fc7a7f3bSEnrico Granata ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1); 1251fc7a7f3bSEnrico Granata memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3); 1252fc7a7f3bSEnrico Granata 1253e992a089SEnrico Granata if (log) 1254e992a089SEnrico Granata log->Printf("symbol to expand: %s",expr_path.get()); 1255fc7a7f3bSEnrico Granata 1256c482a192SEnrico Granata target = valobj->GetValueForExpressionPath(expr_path.get(), 1257fc7a7f3bSEnrico Granata &first_unparsed, 1258fc7a7f3bSEnrico Granata &reason_to_stop, 1259fc7a7f3bSEnrico Granata &final_value_type, 1260fc7a7f3bSEnrico Granata options, 1261fc7a7f3bSEnrico Granata &what_next).get(); 1262fc7a7f3bSEnrico Granata 1263fc7a7f3bSEnrico Granata if (!target) 12649fc1944eSEnrico Granata { 1265e992a089SEnrico Granata if (log) 1266e992a089SEnrico Granata log->Printf("ERROR: unparsed portion = %s, why stopping = %d," 1267e992a089SEnrico Granata " final_value_type %d", 1268fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1269fc7a7f3bSEnrico Granata break; 12700a3958e0SEnrico Granata } 1271a7187d00SEnrico Granata else 1272fc7a7f3bSEnrico Granata { 1273e992a089SEnrico Granata if (log) 1274e992a089SEnrico Granata log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d," 1275e992a089SEnrico Granata " final_value_type %d", 1276fc7a7f3bSEnrico Granata first_unparsed, reason_to_stop, final_value_type); 1277a7187d00SEnrico Granata } 12780a3958e0SEnrico Granata } 12790a3958e0SEnrico Granata else 12800a3958e0SEnrico Granata break; 12819fc1944eSEnrico Granata 128286cc9829SEnrico Granata is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange || 128386cc9829SEnrico Granata final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange); 1284fc7a7f3bSEnrico Granata 128586cc9829SEnrico Granata do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference); 1286fc7a7f3bSEnrico Granata 1287a7187d00SEnrico Granata if (do_deref_pointer && !is_array_range) 12880a3958e0SEnrico Granata { 12899fc1944eSEnrico Granata // I have not deref-ed yet, let's do it 12909fc1944eSEnrico Granata // this happens when we are not going through GetValueForVariableExpressionPath 12919fc1944eSEnrico Granata // to get to the target ValueObject 12929fc1944eSEnrico Granata Error error; 12939fc1944eSEnrico Granata target = target->Dereference(error).get(); 1294dc940730SEnrico Granata if (error.Fail()) 1295dc940730SEnrico Granata { 1296dc940730SEnrico Granata if (log) 1297dc940730SEnrico Granata log->Printf("ERROR: %s\n", error.AsCString("unknown")); \ 1298dc940730SEnrico Granata break; 1299dc940730SEnrico Granata } 13009fc1944eSEnrico Granata do_deref_pointer = false; 13010a3958e0SEnrico Granata } 13020a3958e0SEnrico Granata 130385933ed4SEnrico Granata // TODO use flags for these 1304f4efecd9SEnrico Granata bool is_array = ClangASTContext::IsArrayType(target->GetClangType()); 1305f4efecd9SEnrico Granata bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType()); 130685933ed4SEnrico Granata bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType()); 1307f4efecd9SEnrico Granata 130886cc9829SEnrico Granata if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions 1309f4efecd9SEnrico Granata { 131085933ed4SEnrico Granata StreamString str_temp; 1311e992a089SEnrico Granata if (log) 1312e992a089SEnrico Granata log->Printf("I am into array || pointer && !range"); 1313d64d0bc0SEnrico Granata 131486cc9829SEnrico Granata if (target->HasSpecialPrintableRepresentation(val_obj_display, 1315d64d0bc0SEnrico Granata custom_format)) 1316d64d0bc0SEnrico Granata { 1317f4efecd9SEnrico Granata // try to use the special cases 131885933ed4SEnrico Granata var_success = target->DumpPrintableRepresentation(str_temp, 131985933ed4SEnrico Granata val_obj_display, 132085933ed4SEnrico Granata custom_format); 1321e992a089SEnrico Granata if (log) 1322e992a089SEnrico Granata log->Printf("special cases did%s match", var_success ? "" : "n't"); 1323d64d0bc0SEnrico Granata 1324d64d0bc0SEnrico Granata // should not happen 132585933ed4SEnrico Granata if (!var_success) 132685933ed4SEnrico Granata s << "<invalid usage of pointer value as object>"; 132785933ed4SEnrico Granata else 132885933ed4SEnrico Granata s << str_temp.GetData(); 1329d64d0bc0SEnrico Granata var_success = true; 1330d64d0bc0SEnrico Granata break; 1331d64d0bc0SEnrico Granata } 1332d64d0bc0SEnrico Granata else 1333d64d0bc0SEnrico Granata { 133488da35f8SEnrico Granata if (was_plain_var) // if ${var} 1335d64d0bc0SEnrico Granata { 1336d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1337d64d0bc0SEnrico Granata } 133888da35f8SEnrico Granata else if (is_pointer) // if pointer, value is the address stored 133988da35f8SEnrico Granata { 134086cc9829SEnrico Granata var_success = target->DumpPrintableRepresentation(s, 134188da35f8SEnrico Granata val_obj_display, 134286cc9829SEnrico Granata custom_format, 134386cc9829SEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 134488da35f8SEnrico Granata } 1345d64d0bc0SEnrico Granata else 1346d64d0bc0SEnrico Granata { 1347d64d0bc0SEnrico Granata s << "<invalid usage of pointer value as object>"; 1348d64d0bc0SEnrico Granata } 1349d64d0bc0SEnrico Granata var_success = true; 1350d64d0bc0SEnrico Granata break; 1351d64d0bc0SEnrico Granata } 1352d64d0bc0SEnrico Granata } 1353d64d0bc0SEnrico Granata 1354d64d0bc0SEnrico Granata // if directly trying to print ${var}, and this is an aggregate, display a nice 1355d64d0bc0SEnrico Granata // type @ location message 1356d64d0bc0SEnrico Granata if (is_aggregate && was_plain_var) 1357d64d0bc0SEnrico Granata { 1358d64d0bc0SEnrico Granata s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); 1359d64d0bc0SEnrico Granata var_success = true; 136085933ed4SEnrico Granata break; 136185933ed4SEnrico Granata } 136285933ed4SEnrico Granata 1363d64d0bc0SEnrico Granata // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it 136486cc9829SEnrico Granata if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue))) 136585933ed4SEnrico Granata { 136685933ed4SEnrico Granata s << "<invalid use of aggregate type>"; 136785933ed4SEnrico Granata var_success = true; 1368f4efecd9SEnrico Granata break; 1369f4efecd9SEnrico Granata } 1370f4efecd9SEnrico Granata 13719fc1944eSEnrico Granata if (!is_array_range) 1372e992a089SEnrico Granata { 1373e992a089SEnrico Granata if (log) 1374e992a089SEnrico Granata log->Printf("dumping ordinary printable output"); 13759fc1944eSEnrico Granata var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); 1376e992a089SEnrico Granata } 13779fc1944eSEnrico Granata else 13789fc1944eSEnrico Granata { 1379e992a089SEnrico Granata if (log) 1380e992a089SEnrico Granata log->Printf("checking if I can handle as array"); 13819fc1944eSEnrico Granata if (!is_array && !is_pointer) 13829fc1944eSEnrico Granata break; 1383e992a089SEnrico Granata if (log) 1384e992a089SEnrico Granata log->Printf("handle as array"); 1385fc7a7f3bSEnrico Granata const char* special_directions = NULL; 1386fc7a7f3bSEnrico Granata StreamString special_directions_writer; 13870a3958e0SEnrico Granata if (close_bracket_position && (var_name_end-close_bracket_position > 1)) 13880a3958e0SEnrico Granata { 1389fc7a7f3bSEnrico Granata ConstString additional_data; 1390fc7a7f3bSEnrico Granata additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1); 1391fc7a7f3bSEnrico Granata special_directions_writer.Printf("${%svar%s}", 1392fc7a7f3bSEnrico Granata do_deref_pointer ? "*" : "", 1393fc7a7f3bSEnrico Granata additional_data.GetCString()); 1394fc7a7f3bSEnrico Granata special_directions = special_directions_writer.GetData(); 13950a3958e0SEnrico Granata } 13960a3958e0SEnrico Granata 13970a3958e0SEnrico Granata // let us display items index_lower thru index_higher of this array 13980a3958e0SEnrico Granata s.PutChar('['); 13990a3958e0SEnrico Granata var_success = true; 14000a3958e0SEnrico Granata 14019fc1944eSEnrico Granata if (index_higher < 0) 1402c482a192SEnrico Granata index_higher = valobj->GetNumChildren() - 1; 14030a3958e0SEnrico Granata 1404cc4d0146SGreg Clayton uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 140522c55d18SEnrico Granata 14060a3958e0SEnrico Granata for (;index_lower<=index_higher;index_lower++) 14070a3958e0SEnrico Granata { 1408fc7a7f3bSEnrico Granata ValueObject* item = ExpandIndexedExpression (target, 14099fc1944eSEnrico Granata index_lower, 1410c14ee32dSGreg Clayton exe_ctx->GetFramePtr(), 1411fc7a7f3bSEnrico Granata false).get(); 14120a3958e0SEnrico Granata 1413fc7a7f3bSEnrico Granata if (!item) 1414fc7a7f3bSEnrico Granata { 1415e992a089SEnrico Granata if (log) 1416fd54b368SJason Molenda log->Printf("ERROR in getting child item at index %lld", index_lower); 1417fc7a7f3bSEnrico Granata } 1418fc7a7f3bSEnrico Granata else 1419fc7a7f3bSEnrico Granata { 1420e992a089SEnrico Granata if (log) 1421e992a089SEnrico Granata log->Printf("special_directions for child item: %s",special_directions); 1422fc7a7f3bSEnrico Granata } 1423fc7a7f3bSEnrico Granata 14240a3958e0SEnrico Granata if (!special_directions) 14259fc1944eSEnrico Granata var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); 14260a3958e0SEnrico Granata else 14270a3958e0SEnrico Granata var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); 14280a3958e0SEnrico Granata 142922c55d18SEnrico Granata if (--max_num_children == 0) 143022c55d18SEnrico Granata { 143122c55d18SEnrico Granata s.PutCString(", ..."); 143222c55d18SEnrico Granata break; 143322c55d18SEnrico Granata } 143422c55d18SEnrico Granata 14350a3958e0SEnrico Granata if (index_lower < index_higher) 14360a3958e0SEnrico Granata s.PutChar(','); 14370a3958e0SEnrico Granata } 14380a3958e0SEnrico Granata s.PutChar(']'); 14394becb37eSEnrico Granata } 14404becb37eSEnrico Granata } 144134132754SGreg Clayton break; 14421b654882SGreg Clayton case 'a': 14431b654882SGreg Clayton if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) 14441b654882SGreg Clayton { 14451b654882SGreg Clayton if (addr && addr->IsValid()) 14461b654882SGreg Clayton { 14471b654882SGreg Clayton var_success = true; 14481b654882SGreg Clayton format_addr = *addr; 14491b654882SGreg Clayton } 14501b654882SGreg Clayton } 14515a31471eSGreg Clayton else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0) 14525a31471eSGreg Clayton { 14535a31471eSGreg Clayton var_success = true; 14545a31471eSGreg Clayton var_name_begin += strlen("ansi."); // Skip the "ansi." 14555a31471eSGreg Clayton if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0) 14565a31471eSGreg Clayton { 14575a31471eSGreg Clayton var_name_begin += strlen("fg."); // Skip the "fg." 14585a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 14595a31471eSGreg Clayton { 14605a31471eSGreg Clayton s.Printf ("%s%s%s", 14615a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 14625a31471eSGreg Clayton lldb_utility::ansi::k_fg_black, 14635a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 14645a31471eSGreg Clayton } 14655a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 14665a31471eSGreg Clayton { 14675a31471eSGreg Clayton s.Printf ("%s%s%s", 14685a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 14695a31471eSGreg Clayton lldb_utility::ansi::k_fg_red, 14705a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 14715a31471eSGreg Clayton } 14725a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 14735a31471eSGreg Clayton { 14745a31471eSGreg Clayton s.Printf ("%s%s%s", 14755a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 14765a31471eSGreg Clayton lldb_utility::ansi::k_fg_green, 14775a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 14785a31471eSGreg Clayton } 14795a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 14805a31471eSGreg Clayton { 14815a31471eSGreg Clayton s.Printf ("%s%s%s", 14825a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 14835a31471eSGreg Clayton lldb_utility::ansi::k_fg_yellow, 14845a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 14855a31471eSGreg Clayton } 14865a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 14875a31471eSGreg Clayton { 14885a31471eSGreg Clayton s.Printf ("%s%s%s", 14895a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 14905a31471eSGreg Clayton lldb_utility::ansi::k_fg_blue, 14915a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 14925a31471eSGreg Clayton } 14935a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 14945a31471eSGreg Clayton { 14955a31471eSGreg Clayton s.Printf ("%s%s%s", 14965a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 14975a31471eSGreg Clayton lldb_utility::ansi::k_fg_purple, 14985a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 14995a31471eSGreg Clayton } 15005a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 15015a31471eSGreg Clayton { 15025a31471eSGreg Clayton s.Printf ("%s%s%s", 15035a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15045a31471eSGreg Clayton lldb_utility::ansi::k_fg_cyan, 15055a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15065a31471eSGreg Clayton } 15075a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 15085a31471eSGreg Clayton { 15095a31471eSGreg Clayton s.Printf ("%s%s%s", 15105a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15115a31471eSGreg Clayton lldb_utility::ansi::k_fg_white, 15125a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15135a31471eSGreg Clayton } 15145a31471eSGreg Clayton else 15155a31471eSGreg Clayton { 15165a31471eSGreg Clayton var_success = false; 15175a31471eSGreg Clayton } 15185a31471eSGreg Clayton } 15195a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0) 15205a31471eSGreg Clayton { 15215a31471eSGreg Clayton var_name_begin += strlen("bg."); // Skip the "bg." 15225a31471eSGreg Clayton if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0) 15235a31471eSGreg Clayton { 15245a31471eSGreg Clayton s.Printf ("%s%s%s", 15255a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15265a31471eSGreg Clayton lldb_utility::ansi::k_bg_black, 15275a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15285a31471eSGreg Clayton } 15295a31471eSGreg Clayton else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0) 15305a31471eSGreg Clayton { 15315a31471eSGreg Clayton s.Printf ("%s%s%s", 15325a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15335a31471eSGreg Clayton lldb_utility::ansi::k_bg_red, 15345a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15355a31471eSGreg Clayton } 15365a31471eSGreg Clayton else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0) 15375a31471eSGreg Clayton { 15385a31471eSGreg Clayton s.Printf ("%s%s%s", 15395a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15405a31471eSGreg Clayton lldb_utility::ansi::k_bg_green, 15415a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15425a31471eSGreg Clayton } 15435a31471eSGreg Clayton else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0) 15445a31471eSGreg Clayton { 15455a31471eSGreg Clayton s.Printf ("%s%s%s", 15465a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15475a31471eSGreg Clayton lldb_utility::ansi::k_bg_yellow, 15485a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15495a31471eSGreg Clayton } 15505a31471eSGreg Clayton else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0) 15515a31471eSGreg Clayton { 15525a31471eSGreg Clayton s.Printf ("%s%s%s", 15535a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15545a31471eSGreg Clayton lldb_utility::ansi::k_bg_blue, 15555a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15565a31471eSGreg Clayton } 15575a31471eSGreg Clayton else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0) 15585a31471eSGreg Clayton { 15595a31471eSGreg Clayton s.Printf ("%s%s%s", 15605a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15615a31471eSGreg Clayton lldb_utility::ansi::k_bg_purple, 15625a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15635a31471eSGreg Clayton } 15645a31471eSGreg Clayton else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0) 15655a31471eSGreg Clayton { 15665a31471eSGreg Clayton s.Printf ("%s%s%s", 15675a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15685a31471eSGreg Clayton lldb_utility::ansi::k_bg_cyan, 15695a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15705a31471eSGreg Clayton } 15715a31471eSGreg Clayton else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0) 15725a31471eSGreg Clayton { 15735a31471eSGreg Clayton s.Printf ("%s%s%s", 15745a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15755a31471eSGreg Clayton lldb_utility::ansi::k_bg_white, 15765a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15775a31471eSGreg Clayton } 15785a31471eSGreg Clayton else 15795a31471eSGreg Clayton { 15805a31471eSGreg Clayton var_success = false; 15815a31471eSGreg Clayton } 15825a31471eSGreg Clayton } 15835a31471eSGreg Clayton else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0) 15845a31471eSGreg Clayton { 15855a31471eSGreg Clayton s.Printf ("%s%s%s", 15865a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15875a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_normal, 15885a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15895a31471eSGreg Clayton } 15905a31471eSGreg Clayton else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0) 15915a31471eSGreg Clayton { 15925a31471eSGreg Clayton s.Printf ("%s%s%s", 15935a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 15945a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_bold, 15955a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 15965a31471eSGreg Clayton } 15975a31471eSGreg Clayton else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0) 15985a31471eSGreg Clayton { 15995a31471eSGreg Clayton s.Printf ("%s%s%s", 16005a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16015a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_faint, 16025a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16035a31471eSGreg Clayton } 16045a31471eSGreg Clayton else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0) 16055a31471eSGreg Clayton { 16065a31471eSGreg Clayton s.Printf ("%s%s%s", 16075a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16085a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_italic, 16095a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16105a31471eSGreg Clayton } 16115a31471eSGreg Clayton else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0) 16125a31471eSGreg Clayton { 16135a31471eSGreg Clayton s.Printf ("%s%s%s", 16145a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16155a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_underline, 16165a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16175a31471eSGreg Clayton } 16185a31471eSGreg Clayton else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0) 16195a31471eSGreg Clayton { 16205a31471eSGreg Clayton s.Printf ("%s%s%s", 16215a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16225a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_slow_blink, 16235a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16245a31471eSGreg Clayton } 16255a31471eSGreg Clayton else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0) 16265a31471eSGreg Clayton { 16275a31471eSGreg Clayton s.Printf ("%s%s%s", 16285a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16295a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_fast_blink, 16305a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16315a31471eSGreg Clayton } 16325a31471eSGreg Clayton else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0) 16335a31471eSGreg Clayton { 16345a31471eSGreg Clayton s.Printf ("%s%s%s", 16355a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16365a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_negative, 16375a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16385a31471eSGreg Clayton } 16395a31471eSGreg Clayton else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0) 16405a31471eSGreg Clayton { 16415a31471eSGreg Clayton s.Printf ("%s%s%s", 16425a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16435a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_conceal, 16445a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16455a31471eSGreg Clayton 16465a31471eSGreg Clayton } 16475a31471eSGreg Clayton else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0) 16485a31471eSGreg Clayton { 16495a31471eSGreg Clayton s.Printf ("%s%s%s", 16505a31471eSGreg Clayton lldb_utility::ansi::k_escape_start, 16515a31471eSGreg Clayton lldb_utility::ansi::k_ctrl_crossed_out, 16525a31471eSGreg Clayton lldb_utility::ansi::k_escape_end); 16535a31471eSGreg Clayton } 16545a31471eSGreg Clayton else 16555a31471eSGreg Clayton { 16565a31471eSGreg Clayton var_success = false; 16575a31471eSGreg Clayton } 16585a31471eSGreg Clayton } 16591b654882SGreg Clayton break; 16601b654882SGreg Clayton 16611b654882SGreg Clayton case 'p': 16621b654882SGreg Clayton if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0) 16631b654882SGreg Clayton { 1664c14ee32dSGreg Clayton if (exe_ctx) 1665c14ee32dSGreg Clayton { 1666c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr(); 1667c14ee32dSGreg Clayton if (process) 16681b654882SGreg Clayton { 16691b654882SGreg Clayton var_name_begin += ::strlen ("process."); 16701b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 16711b654882SGreg Clayton { 167281c22f61SGreg Clayton s.Printf("%llu", process->GetID()); 16731b654882SGreg Clayton var_success = true; 16741b654882SGreg Clayton } 16751b654882SGreg Clayton else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) || 16761b654882SGreg Clayton (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) || 16771b654882SGreg Clayton (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0)) 16781b654882SGreg Clayton { 1679c14ee32dSGreg Clayton Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 1680aa149cbdSGreg Clayton if (exe_module) 16811b654882SGreg Clayton { 16821b654882SGreg Clayton if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f') 16831b654882SGreg Clayton { 1684aa149cbdSGreg Clayton format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename(); 16851b654882SGreg Clayton var_success = format_file_spec; 16861b654882SGreg Clayton } 16871b654882SGreg Clayton else 16881b654882SGreg Clayton { 1689aa149cbdSGreg Clayton format_file_spec = exe_module->GetFileSpec(); 16901b654882SGreg Clayton var_success = format_file_spec; 16911b654882SGreg Clayton } 16921b654882SGreg Clayton } 16931b654882SGreg Clayton } 16941b654882SGreg Clayton } 16951b654882SGreg Clayton } 1696c14ee32dSGreg Clayton } 16971b654882SGreg Clayton break; 16981b654882SGreg Clayton 16991b654882SGreg Clayton case 't': 17001b654882SGreg Clayton if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0) 17011b654882SGreg Clayton { 1702c14ee32dSGreg Clayton if (exe_ctx) 1703c14ee32dSGreg Clayton { 1704c14ee32dSGreg Clayton Thread *thread = exe_ctx->GetThreadPtr(); 1705c14ee32dSGreg Clayton if (thread) 17061b654882SGreg Clayton { 17071b654882SGreg Clayton var_name_begin += ::strlen ("thread."); 17081b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 17091b654882SGreg Clayton { 171081c22f61SGreg Clayton s.Printf("0x%4.4llx", thread->GetID()); 17111b654882SGreg Clayton var_success = true; 17121b654882SGreg Clayton } 17131b654882SGreg Clayton else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 17141b654882SGreg Clayton { 1715c14ee32dSGreg Clayton s.Printf("%u", thread->GetIndexID()); 17161b654882SGreg Clayton var_success = true; 17171b654882SGreg Clayton } 17181b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 17191b654882SGreg Clayton { 1720c14ee32dSGreg Clayton cstr = thread->GetName(); 17211b654882SGreg Clayton var_success = cstr && cstr[0]; 17221b654882SGreg Clayton if (var_success) 17231b654882SGreg Clayton s.PutCString(cstr); 17241b654882SGreg Clayton } 17251b654882SGreg Clayton else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0) 17261b654882SGreg Clayton { 1727c14ee32dSGreg Clayton cstr = thread->GetQueueName(); 17281b654882SGreg Clayton var_success = cstr && cstr[0]; 17291b654882SGreg Clayton if (var_success) 17301b654882SGreg Clayton s.PutCString(cstr); 17311b654882SGreg Clayton } 17321b654882SGreg Clayton else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0) 17331b654882SGreg Clayton { 1734c14ee32dSGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 1735b15bfc75SJim Ingham if (stop_info_sp) 17361b654882SGreg Clayton { 1737b15bfc75SJim Ingham cstr = stop_info_sp->GetDescription(); 17381b654882SGreg Clayton if (cstr && cstr[0]) 17391b654882SGreg Clayton { 17401b654882SGreg Clayton s.PutCString(cstr); 17411b654882SGreg Clayton var_success = true; 17421b654882SGreg Clayton } 17431b654882SGreg Clayton } 17441b654882SGreg Clayton } 174573ca05a2SJim Ingham else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0) 174673ca05a2SJim Ingham { 174773ca05a2SJim Ingham StopInfoSP stop_info_sp = thread->GetStopInfo (); 174873ca05a2SJim Ingham if (stop_info_sp) 174973ca05a2SJim Ingham { 175073ca05a2SJim Ingham ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 175173ca05a2SJim Ingham if (return_valobj_sp) 175273ca05a2SJim Ingham { 1753ef651600SJim Ingham ValueObject::DumpValueObjectOptions dump_options; 1754ef651600SJim Ingham ValueObject::DumpValueObject (s, return_valobj_sp.get(), dump_options); 175573ca05a2SJim Ingham var_success = true; 175673ca05a2SJim Ingham } 175773ca05a2SJim Ingham } 175873ca05a2SJim Ingham } 175973ca05a2SJim Ingham } 17601b654882SGreg Clayton } 17611b654882SGreg Clayton } 17621b654882SGreg Clayton else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0) 17631b654882SGreg Clayton { 17640603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 17650603aa9dSGreg Clayton if (target) 17661b654882SGreg Clayton { 17671b654882SGreg Clayton var_name_begin += ::strlen ("target."); 17681b654882SGreg Clayton if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0) 17691b654882SGreg Clayton { 17701b654882SGreg Clayton ArchSpec arch (target->GetArchitecture ()); 17711b654882SGreg Clayton if (arch.IsValid()) 17721b654882SGreg Clayton { 177364195a2cSGreg Clayton s.PutCString (arch.GetArchitectureName()); 17741b654882SGreg Clayton var_success = true; 17751b654882SGreg Clayton } 17761b654882SGreg Clayton } 17771b654882SGreg Clayton } 17781b654882SGreg Clayton } 17791b654882SGreg Clayton break; 17801b654882SGreg Clayton 17811b654882SGreg Clayton 17821b654882SGreg Clayton case 'm': 17831b654882SGreg Clayton if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0) 17841b654882SGreg Clayton { 17850603aa9dSGreg Clayton if (sc && sc->module_sp.get()) 17861b654882SGreg Clayton { 17870603aa9dSGreg Clayton Module *module = sc->module_sp.get(); 17881b654882SGreg Clayton var_name_begin += ::strlen ("module."); 17891b654882SGreg Clayton 17901b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 17911b654882SGreg Clayton { 17921b654882SGreg Clayton if (module->GetFileSpec()) 17931b654882SGreg Clayton { 17941b654882SGreg Clayton var_name_begin += ::strlen ("file."); 17951b654882SGreg Clayton 17961b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 17971b654882SGreg Clayton { 17981b654882SGreg Clayton format_file_spec.GetFilename() = module->GetFileSpec().GetFilename(); 17991b654882SGreg Clayton var_success = format_file_spec; 18001b654882SGreg Clayton } 18011b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 18021b654882SGreg Clayton { 18031b654882SGreg Clayton format_file_spec = module->GetFileSpec(); 18041b654882SGreg Clayton var_success = format_file_spec; 18051b654882SGreg Clayton } 18061b654882SGreg Clayton } 18071b654882SGreg Clayton } 18081b654882SGreg Clayton } 18091b654882SGreg Clayton } 18101b654882SGreg Clayton break; 18111b654882SGreg Clayton 18121b654882SGreg Clayton 18131b654882SGreg Clayton case 'f': 18141b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 18151b654882SGreg Clayton { 18161b654882SGreg Clayton if (sc && sc->comp_unit != NULL) 18171b654882SGreg Clayton { 18181b654882SGreg Clayton var_name_begin += ::strlen ("file."); 18191b654882SGreg Clayton 18201b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 18211b654882SGreg Clayton { 18221b654882SGreg Clayton format_file_spec.GetFilename() = sc->comp_unit->GetFilename(); 18231b654882SGreg Clayton var_success = format_file_spec; 18241b654882SGreg Clayton } 18251b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 18261b654882SGreg Clayton { 18271b654882SGreg Clayton format_file_spec = *sc->comp_unit; 18281b654882SGreg Clayton var_success = format_file_spec; 18291b654882SGreg Clayton } 18301b654882SGreg Clayton } 18311b654882SGreg Clayton } 18321b654882SGreg Clayton else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0) 18331b654882SGreg Clayton { 1834c14ee32dSGreg Clayton if (exe_ctx) 1835c14ee32dSGreg Clayton { 1836c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 1837c14ee32dSGreg Clayton if (frame) 18381b654882SGreg Clayton { 18391b654882SGreg Clayton var_name_begin += ::strlen ("frame."); 18401b654882SGreg Clayton if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0) 18411b654882SGreg Clayton { 1842c14ee32dSGreg Clayton s.Printf("%u", frame->GetFrameIndex()); 18431b654882SGreg Clayton var_success = true; 18441b654882SGreg Clayton } 18451b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0) 18461b654882SGreg Clayton { 18471b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 18481b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_PC; 18491b654882SGreg Clayton var_success = true; 18501b654882SGreg Clayton } 18511b654882SGreg Clayton else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0) 18521b654882SGreg Clayton { 18531b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 18541b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_SP; 18551b654882SGreg Clayton var_success = true; 18561b654882SGreg Clayton } 18571b654882SGreg Clayton else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0) 18581b654882SGreg Clayton { 18591b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 18601b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FP; 18611b654882SGreg Clayton var_success = true; 18621b654882SGreg Clayton } 18631b654882SGreg Clayton else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0) 18641b654882SGreg Clayton { 18651b654882SGreg Clayton reg_kind = eRegisterKindGeneric; 18661b654882SGreg Clayton reg_num = LLDB_REGNUM_GENERIC_FLAGS; 18671b654882SGreg Clayton var_success = true; 18681b654882SGreg Clayton } 18691b654882SGreg Clayton else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0) 18701b654882SGreg Clayton { 1871c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 18721b654882SGreg Clayton if (reg_ctx) 18731b654882SGreg Clayton { 18741b654882SGreg Clayton var_name_begin += ::strlen ("reg."); 18751b654882SGreg Clayton if (var_name_begin < var_name_end) 18761b654882SGreg Clayton { 18771b654882SGreg Clayton std::string reg_name (var_name_begin, var_name_end); 18781b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str()); 18791b654882SGreg Clayton if (reg_info) 18801b654882SGreg Clayton var_success = true; 18811b654882SGreg Clayton } 18821b654882SGreg Clayton } 18831b654882SGreg Clayton } 18841b654882SGreg Clayton } 18851b654882SGreg Clayton } 1886c14ee32dSGreg Clayton } 18871b654882SGreg Clayton else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0) 18881b654882SGreg Clayton { 18891b654882SGreg Clayton if (sc && (sc->function != NULL || sc->symbol != NULL)) 18901b654882SGreg Clayton { 18911b654882SGreg Clayton var_name_begin += ::strlen ("function."); 18921b654882SGreg Clayton if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0) 18931b654882SGreg Clayton { 18941b654882SGreg Clayton if (sc->function) 189581c22f61SGreg Clayton s.Printf("function{0x%8.8llx}", sc->function->GetID()); 18961b654882SGreg Clayton else 18971b654882SGreg Clayton s.Printf("symbol[%u]", sc->symbol->GetID()); 18981b654882SGreg Clayton 18991b654882SGreg Clayton var_success = true; 19001b654882SGreg Clayton } 19011b654882SGreg Clayton else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0) 19021b654882SGreg Clayton { 19031b654882SGreg Clayton if (sc->function) 19041b654882SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 19051b654882SGreg Clayton else if (sc->symbol) 19061b654882SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 19071b654882SGreg Clayton if (cstr) 19081b654882SGreg Clayton { 19091b654882SGreg Clayton s.PutCString(cstr); 19100d9c9934SGreg Clayton 19110d9c9934SGreg Clayton if (sc->block) 19120d9c9934SGreg Clayton { 19130d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 19140d9c9934SGreg Clayton if (inline_block) 19150d9c9934SGreg Clayton { 19160d9c9934SGreg Clayton const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); 19170d9c9934SGreg Clayton if (inline_info) 19180d9c9934SGreg Clayton { 19190d9c9934SGreg Clayton s.PutCString(" [inlined] "); 19200d9c9934SGreg Clayton inline_info->GetName().Dump(&s); 19210d9c9934SGreg Clayton } 19220d9c9934SGreg Clayton } 19230d9c9934SGreg Clayton } 19241b654882SGreg Clayton var_success = true; 19251b654882SGreg Clayton } 19261b654882SGreg Clayton } 19276d3dbf51SGreg Clayton else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0) 19286d3dbf51SGreg Clayton { 19296d3dbf51SGreg Clayton // Print the function name with arguments in it 19306d3dbf51SGreg Clayton 19316d3dbf51SGreg Clayton if (sc->function) 19326d3dbf51SGreg Clayton { 19336d3dbf51SGreg Clayton var_success = true; 19346d3dbf51SGreg Clayton ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; 19356d3dbf51SGreg Clayton cstr = sc->function->GetName().AsCString (NULL); 19366d3dbf51SGreg Clayton if (cstr) 19376d3dbf51SGreg Clayton { 19386d3dbf51SGreg Clayton const InlineFunctionInfo *inline_info = NULL; 19396d3dbf51SGreg Clayton VariableListSP variable_list_sp; 19406d3dbf51SGreg Clayton bool get_function_vars = true; 19416d3dbf51SGreg Clayton if (sc->block) 19426d3dbf51SGreg Clayton { 19436d3dbf51SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 19446d3dbf51SGreg Clayton 19456d3dbf51SGreg Clayton if (inline_block) 19466d3dbf51SGreg Clayton { 19476d3dbf51SGreg Clayton get_function_vars = false; 19486d3dbf51SGreg Clayton inline_info = sc->block->GetInlinedFunctionInfo(); 19496d3dbf51SGreg Clayton if (inline_info) 19506d3dbf51SGreg Clayton variable_list_sp = inline_block->GetBlockVariableList (true); 19516d3dbf51SGreg Clayton } 19526d3dbf51SGreg Clayton } 19536d3dbf51SGreg Clayton 19546d3dbf51SGreg Clayton if (get_function_vars) 19556d3dbf51SGreg Clayton { 19566d3dbf51SGreg Clayton variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); 19576d3dbf51SGreg Clayton } 19586d3dbf51SGreg Clayton 19596d3dbf51SGreg Clayton if (inline_info) 19606d3dbf51SGreg Clayton { 19616d3dbf51SGreg Clayton s.PutCString (cstr); 19626d3dbf51SGreg Clayton s.PutCString (" [inlined] "); 19636d3dbf51SGreg Clayton cstr = inline_info->GetName().GetCString(); 19646d3dbf51SGreg Clayton } 19656d3dbf51SGreg Clayton 19666d3dbf51SGreg Clayton VariableList args; 19676d3dbf51SGreg Clayton if (variable_list_sp) 19686d3dbf51SGreg Clayton { 19696d3dbf51SGreg Clayton const size_t num_variables = variable_list_sp->GetSize(); 19706d3dbf51SGreg Clayton for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) 19716d3dbf51SGreg Clayton { 19726d3dbf51SGreg Clayton VariableSP var_sp (variable_list_sp->GetVariableAtIndex(var_idx)); 19736d3dbf51SGreg Clayton if (var_sp->GetScope() == eValueTypeVariableArgument) 19746d3dbf51SGreg Clayton args.AddVariable (var_sp); 19756d3dbf51SGreg Clayton } 19766d3dbf51SGreg Clayton 19776d3dbf51SGreg Clayton } 19786d3dbf51SGreg Clayton if (args.GetSize() > 0) 19796d3dbf51SGreg Clayton { 19806d3dbf51SGreg Clayton const char *open_paren = strchr (cstr, '('); 19816d3dbf51SGreg Clayton const char *close_paren = NULL; 19826d3dbf51SGreg Clayton if (open_paren) 19836d3dbf51SGreg Clayton close_paren = strchr (open_paren, ')'); 19846d3dbf51SGreg Clayton 19856d3dbf51SGreg Clayton if (open_paren) 19866d3dbf51SGreg Clayton s.Write(cstr, open_paren - cstr + 1); 19876d3dbf51SGreg Clayton else 19886d3dbf51SGreg Clayton { 19896d3dbf51SGreg Clayton s.PutCString (cstr); 19906d3dbf51SGreg Clayton s.PutChar ('('); 19916d3dbf51SGreg Clayton } 19925b6889b1SGreg Clayton const size_t num_args = args.GetSize(); 19936d3dbf51SGreg Clayton for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) 19946d3dbf51SGreg Clayton { 19956d3dbf51SGreg Clayton VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); 19966d3dbf51SGreg Clayton ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); 19976d3dbf51SGreg Clayton const char *var_name = var_value_sp->GetName().GetCString(); 19986d3dbf51SGreg Clayton const char *var_value = var_value_sp->GetValueAsCString(); 19996d3dbf51SGreg Clayton if (var_value_sp->GetError().Success()) 20006d3dbf51SGreg Clayton { 20016d3dbf51SGreg Clayton if (arg_idx > 0) 20026d3dbf51SGreg Clayton s.PutCString (", "); 20036d3dbf51SGreg Clayton s.Printf ("%s=%s", var_name, var_value); 20046d3dbf51SGreg Clayton } 20056d3dbf51SGreg Clayton } 20066d3dbf51SGreg Clayton 20076d3dbf51SGreg Clayton if (close_paren) 20086d3dbf51SGreg Clayton s.PutCString (close_paren); 20096d3dbf51SGreg Clayton else 20106d3dbf51SGreg Clayton s.PutChar(')'); 20116d3dbf51SGreg Clayton 20126d3dbf51SGreg Clayton } 20136d3dbf51SGreg Clayton else 20146d3dbf51SGreg Clayton { 20156d3dbf51SGreg Clayton s.PutCString(cstr); 20166d3dbf51SGreg Clayton } 20176d3dbf51SGreg Clayton } 20186d3dbf51SGreg Clayton } 20196d3dbf51SGreg Clayton else if (sc->symbol) 20206d3dbf51SGreg Clayton { 20216d3dbf51SGreg Clayton cstr = sc->symbol->GetName().AsCString (NULL); 20226d3dbf51SGreg Clayton if (cstr) 20236d3dbf51SGreg Clayton { 20246d3dbf51SGreg Clayton s.PutCString(cstr); 20256d3dbf51SGreg Clayton var_success = true; 20266d3dbf51SGreg Clayton } 20276d3dbf51SGreg Clayton } 20286d3dbf51SGreg Clayton } 20291b654882SGreg Clayton else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0) 20301b654882SGreg Clayton { 20311b654882SGreg Clayton var_success = addr != NULL; 20321b654882SGreg Clayton if (var_success) 20331b654882SGreg Clayton { 20341b654882SGreg Clayton format_addr = *addr; 20351b654882SGreg Clayton calculate_format_addr_function_offset = true; 20361b654882SGreg Clayton } 20371b654882SGreg Clayton } 20381b654882SGreg Clayton else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0) 20391b654882SGreg Clayton { 20401b654882SGreg Clayton var_success = sc->line_entry.range.GetBaseAddress().IsValid(); 20411b654882SGreg Clayton if (var_success) 20421b654882SGreg Clayton { 20431b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 20441b654882SGreg Clayton calculate_format_addr_function_offset = true; 20451b654882SGreg Clayton } 20461b654882SGreg Clayton } 20471b654882SGreg Clayton else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0) 20481b654882SGreg Clayton { 2049c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 2050c14ee32dSGreg Clayton var_success = frame != NULL; 20511b654882SGreg Clayton if (var_success) 20521b654882SGreg Clayton { 2053c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 20541b654882SGreg Clayton calculate_format_addr_function_offset = true; 20551b654882SGreg Clayton } 20561b654882SGreg Clayton } 20571b654882SGreg Clayton } 20581b654882SGreg Clayton } 20591b654882SGreg Clayton break; 20601b654882SGreg Clayton 20611b654882SGreg Clayton case 'l': 20621b654882SGreg Clayton if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0) 20631b654882SGreg Clayton { 20641b654882SGreg Clayton if (sc && sc->line_entry.IsValid()) 20651b654882SGreg Clayton { 20661b654882SGreg Clayton var_name_begin += ::strlen ("line."); 20671b654882SGreg Clayton if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0) 20681b654882SGreg Clayton { 20691b654882SGreg Clayton var_name_begin += ::strlen ("file."); 20701b654882SGreg Clayton 20711b654882SGreg Clayton if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0) 20721b654882SGreg Clayton { 20731b654882SGreg Clayton format_file_spec.GetFilename() = sc->line_entry.file.GetFilename(); 20741b654882SGreg Clayton var_success = format_file_spec; 20751b654882SGreg Clayton } 20761b654882SGreg Clayton else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0) 20771b654882SGreg Clayton { 20781b654882SGreg Clayton format_file_spec = sc->line_entry.file; 20791b654882SGreg Clayton var_success = format_file_spec; 20801b654882SGreg Clayton } 20811b654882SGreg Clayton } 20821b654882SGreg Clayton else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0) 20831b654882SGreg Clayton { 20841b654882SGreg Clayton var_success = true; 20851b654882SGreg Clayton s.Printf("%u", sc->line_entry.line); 20861b654882SGreg Clayton } 20871b654882SGreg Clayton else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) || 20881b654882SGreg Clayton (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0)) 20891b654882SGreg Clayton { 20901b654882SGreg Clayton var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid(); 20911b654882SGreg Clayton if (var_success) 20921b654882SGreg Clayton { 20931b654882SGreg Clayton format_addr = sc->line_entry.range.GetBaseAddress(); 20941b654882SGreg Clayton if (var_name_begin[0] == 'e') 20951b654882SGreg Clayton format_addr.Slide (sc->line_entry.range.GetByteSize()); 20961b654882SGreg Clayton } 20971b654882SGreg Clayton } 20981b654882SGreg Clayton } 20991b654882SGreg Clayton } 21001b654882SGreg Clayton break; 21011b654882SGreg Clayton } 21021b654882SGreg Clayton 21031b654882SGreg Clayton if (var_success) 21041b654882SGreg Clayton { 21051b654882SGreg Clayton // If format addr is valid, then we need to print an address 21061b654882SGreg Clayton if (reg_num != LLDB_INVALID_REGNUM) 21071b654882SGreg Clayton { 2108c14ee32dSGreg Clayton StackFrame *frame = exe_ctx->GetFramePtr(); 21091b654882SGreg Clayton // We have a register value to display... 21101b654882SGreg Clayton if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric) 21111b654882SGreg Clayton { 2112c14ee32dSGreg Clayton format_addr = frame->GetFrameCodeAddress(); 21131b654882SGreg Clayton } 21141b654882SGreg Clayton else 21151b654882SGreg Clayton { 21161b654882SGreg Clayton if (reg_ctx == NULL) 2117c14ee32dSGreg Clayton reg_ctx = frame->GetRegisterContext().get(); 21181b654882SGreg Clayton 21191b654882SGreg Clayton if (reg_ctx) 21201b654882SGreg Clayton { 21211b654882SGreg Clayton if (reg_kind != kNumRegisterKinds) 21221b654882SGreg Clayton reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 21231b654882SGreg Clayton reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 21241b654882SGreg Clayton var_success = reg_info != NULL; 21251b654882SGreg Clayton } 21261b654882SGreg Clayton } 21271b654882SGreg Clayton } 21281b654882SGreg Clayton 21291b654882SGreg Clayton if (reg_info != NULL) 21301b654882SGreg Clayton { 21317349bd90SGreg Clayton RegisterValue reg_value; 21327349bd90SGreg Clayton var_success = reg_ctx->ReadRegister (reg_info, reg_value); 21337349bd90SGreg Clayton if (var_success) 21341b654882SGreg Clayton { 21359a8fa916SGreg Clayton reg_value.Dump(&s, reg_info, false, false, eFormatDefault); 21361b654882SGreg Clayton } 21371b654882SGreg Clayton } 21381b654882SGreg Clayton 21391b654882SGreg Clayton if (format_file_spec) 21401b654882SGreg Clayton { 21411b654882SGreg Clayton s << format_file_spec; 21421b654882SGreg Clayton } 21431b654882SGreg Clayton 21441b654882SGreg Clayton // If format addr is valid, then we need to print an address 21451b654882SGreg Clayton if (format_addr.IsValid()) 21461b654882SGreg Clayton { 21470603aa9dSGreg Clayton var_success = false; 21480603aa9dSGreg Clayton 21491b654882SGreg Clayton if (calculate_format_addr_function_offset) 21501b654882SGreg Clayton { 21511b654882SGreg Clayton Address func_addr; 21520603aa9dSGreg Clayton 21530603aa9dSGreg Clayton if (sc) 21540603aa9dSGreg Clayton { 21551b654882SGreg Clayton if (sc->function) 21560d9c9934SGreg Clayton { 21571b654882SGreg Clayton func_addr = sc->function->GetAddressRange().GetBaseAddress(); 21580d9c9934SGreg Clayton if (sc->block) 21590d9c9934SGreg Clayton { 21600d9c9934SGreg Clayton // Check to make sure we aren't in an inline 21610d9c9934SGreg Clayton // function. If we are, use the inline block 21620d9c9934SGreg Clayton // range that contains "format_addr" since 21630d9c9934SGreg Clayton // blocks can be discontiguous. 21640d9c9934SGreg Clayton Block *inline_block = sc->block->GetContainingInlinedBlock (); 21650d9c9934SGreg Clayton AddressRange inline_range; 21660d9c9934SGreg Clayton if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range)) 21670d9c9934SGreg Clayton func_addr = inline_range.GetBaseAddress(); 21680d9c9934SGreg Clayton } 21690d9c9934SGreg Clayton } 2170e7612134SGreg Clayton else if (sc->symbol && sc->symbol->ValueIsAddress()) 2171e7612134SGreg Clayton func_addr = sc->symbol->GetAddress(); 21720603aa9dSGreg Clayton } 21731b654882SGreg Clayton 21740603aa9dSGreg Clayton if (func_addr.IsValid()) 21751b654882SGreg Clayton { 21761b654882SGreg Clayton if (func_addr.GetSection() == format_addr.GetSection()) 21771b654882SGreg Clayton { 21781b654882SGreg Clayton addr_t func_file_addr = func_addr.GetFileAddress(); 21791b654882SGreg Clayton addr_t addr_file_addr = format_addr.GetFileAddress(); 21801b654882SGreg Clayton if (addr_file_addr > func_file_addr) 21811b654882SGreg Clayton s.Printf(" + %llu", addr_file_addr - func_file_addr); 21821b654882SGreg Clayton else if (addr_file_addr < func_file_addr) 21831b654882SGreg Clayton s.Printf(" - %llu", func_file_addr - addr_file_addr); 21840603aa9dSGreg Clayton var_success = true; 21851b654882SGreg Clayton } 21861b654882SGreg Clayton else 21870603aa9dSGreg Clayton { 21880603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 21890603aa9dSGreg Clayton if (target) 21900603aa9dSGreg Clayton { 21910603aa9dSGreg Clayton addr_t func_load_addr = func_addr.GetLoadAddress (target); 21920603aa9dSGreg Clayton addr_t addr_load_addr = format_addr.GetLoadAddress (target); 21930603aa9dSGreg Clayton if (addr_load_addr > func_load_addr) 21940603aa9dSGreg Clayton s.Printf(" + %llu", addr_load_addr - func_load_addr); 21950603aa9dSGreg Clayton else if (addr_load_addr < func_load_addr) 21960603aa9dSGreg Clayton s.Printf(" - %llu", func_load_addr - addr_load_addr); 21970603aa9dSGreg Clayton var_success = true; 21980603aa9dSGreg Clayton } 21990603aa9dSGreg Clayton } 22001b654882SGreg Clayton } 22011b654882SGreg Clayton } 22021b654882SGreg Clayton else 22031b654882SGreg Clayton { 22040603aa9dSGreg Clayton Target *target = Target::GetTargetFromContexts (exe_ctx, sc); 22051b654882SGreg Clayton addr_t vaddr = LLDB_INVALID_ADDRESS; 22060603aa9dSGreg Clayton if (exe_ctx && !target->GetSectionLoadList().IsEmpty()) 22070603aa9dSGreg Clayton vaddr = format_addr.GetLoadAddress (target); 22081b654882SGreg Clayton if (vaddr == LLDB_INVALID_ADDRESS) 22091b654882SGreg Clayton vaddr = format_addr.GetFileAddress (); 22101b654882SGreg Clayton 22111b654882SGreg Clayton if (vaddr != LLDB_INVALID_ADDRESS) 22120603aa9dSGreg Clayton { 2213514487e8SGreg Clayton int addr_width = target->GetArchitecture().GetAddressByteSize() * 2; 221435f1a0d5SGreg Clayton if (addr_width == 0) 221535f1a0d5SGreg Clayton addr_width = 16; 221635f1a0d5SGreg Clayton s.Printf("0x%*.*llx", addr_width, addr_width, vaddr); 22170603aa9dSGreg Clayton var_success = true; 22180603aa9dSGreg Clayton } 22191b654882SGreg Clayton } 22201b654882SGreg Clayton } 22211b654882SGreg Clayton } 22221b654882SGreg Clayton 22231b654882SGreg Clayton if (var_success == false) 22241b654882SGreg Clayton success = false; 22251b654882SGreg Clayton } 22261b654882SGreg Clayton p = var_name_end; 22271b654882SGreg Clayton } 22281b654882SGreg Clayton else 22291b654882SGreg Clayton break; 22301b654882SGreg Clayton } 22311b654882SGreg Clayton else 22321b654882SGreg Clayton { 22331b654882SGreg Clayton // We got a dollar sign with no '{' after it, it must just be a dollar sign 22341b654882SGreg Clayton s.PutChar(*p); 22351b654882SGreg Clayton } 22361b654882SGreg Clayton } 22371b654882SGreg Clayton else if (*p == '\\') 22381b654882SGreg Clayton { 22391b654882SGreg Clayton ++p; // skip the slash 22401b654882SGreg Clayton switch (*p) 22411b654882SGreg Clayton { 22421b654882SGreg Clayton case 'a': s.PutChar ('\a'); break; 22431b654882SGreg Clayton case 'b': s.PutChar ('\b'); break; 22441b654882SGreg Clayton case 'f': s.PutChar ('\f'); break; 22451b654882SGreg Clayton case 'n': s.PutChar ('\n'); break; 22461b654882SGreg Clayton case 'r': s.PutChar ('\r'); break; 22471b654882SGreg Clayton case 't': s.PutChar ('\t'); break; 22481b654882SGreg Clayton case 'v': s.PutChar ('\v'); break; 22491b654882SGreg Clayton case '\'': s.PutChar ('\''); break; 22501b654882SGreg Clayton case '\\': s.PutChar ('\\'); break; 22511b654882SGreg Clayton case '0': 22521b654882SGreg Clayton // 1 to 3 octal chars 22531b654882SGreg Clayton { 22540603aa9dSGreg Clayton // Make a string that can hold onto the initial zero char, 22550603aa9dSGreg Clayton // up to 3 octal digits, and a terminating NULL. 22560603aa9dSGreg Clayton char oct_str[5] = { 0, 0, 0, 0, 0 }; 22570603aa9dSGreg Clayton 22580603aa9dSGreg Clayton int i; 22590603aa9dSGreg Clayton for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) 22600603aa9dSGreg Clayton oct_str[i] = p[i]; 22610603aa9dSGreg Clayton 22620603aa9dSGreg Clayton // We don't want to consume the last octal character since 22630603aa9dSGreg Clayton // the main for loop will do this for us, so we advance p by 22640603aa9dSGreg Clayton // one less than i (even if i is zero) 22650603aa9dSGreg Clayton p += i - 1; 22660603aa9dSGreg Clayton unsigned long octal_value = ::strtoul (oct_str, NULL, 8); 22670603aa9dSGreg Clayton if (octal_value <= UINT8_MAX) 22681b654882SGreg Clayton { 22690603aa9dSGreg Clayton char octal_char = octal_value; 22700603aa9dSGreg Clayton s.Write (&octal_char, 1); 22711b654882SGreg Clayton } 22721b654882SGreg Clayton } 22731b654882SGreg Clayton break; 22741b654882SGreg Clayton 22751b654882SGreg Clayton case 'x': 22761b654882SGreg Clayton // hex number in the format 22770603aa9dSGreg Clayton if (isxdigit(p[1])) 22781b654882SGreg Clayton { 22790603aa9dSGreg Clayton ++p; // Skip the 'x' 22801b654882SGreg Clayton 22810603aa9dSGreg Clayton // Make a string that can hold onto two hex chars plus a 22820603aa9dSGreg Clayton // NULL terminator 22831b654882SGreg Clayton char hex_str[3] = { 0,0,0 }; 22841b654882SGreg Clayton hex_str[0] = *p; 22850603aa9dSGreg Clayton if (isxdigit(p[1])) 22860603aa9dSGreg Clayton { 22870603aa9dSGreg Clayton ++p; // Skip the first of the two hex chars 22881b654882SGreg Clayton hex_str[1] = *p; 22890603aa9dSGreg Clayton } 22900603aa9dSGreg Clayton 22911b654882SGreg Clayton unsigned long hex_value = strtoul (hex_str, NULL, 16); 22920603aa9dSGreg Clayton if (hex_value <= UINT8_MAX) 22931b654882SGreg Clayton s.PutChar (hex_value); 22941b654882SGreg Clayton } 22951b654882SGreg Clayton else 22961b654882SGreg Clayton { 22970603aa9dSGreg Clayton s.PutChar('x'); 22981b654882SGreg Clayton } 22991b654882SGreg Clayton break; 23001b654882SGreg Clayton 23011b654882SGreg Clayton default: 23020603aa9dSGreg Clayton // Just desensitize any other character by just printing what 23030603aa9dSGreg Clayton // came after the '\' 23040603aa9dSGreg Clayton s << *p; 23051b654882SGreg Clayton break; 23061b654882SGreg Clayton 23071b654882SGreg Clayton } 23081b654882SGreg Clayton 23091b654882SGreg Clayton } 23101b654882SGreg Clayton } 23111b654882SGreg Clayton if (end) 23121b654882SGreg Clayton *end = p; 23131b654882SGreg Clayton return success; 23141b654882SGreg Clayton } 23151b654882SGreg Clayton 2316228063cdSJim Ingham void 2317228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) 2318228063cdSJim Ingham { 23194f02b22dSJim Ingham // For simplicity's sake, I am not going to deal with how to close down any 23204f02b22dSJim Ingham // open logging streams, I just redirect everything from here on out to the 23214f02b22dSJim Ingham // callback. 2322228063cdSJim Ingham m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton)); 2323228063cdSJim Ingham } 2324228063cdSJim Ingham 2325228063cdSJim Ingham bool 2326228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream) 2327228063cdSJim Ingham { 2328228063cdSJim Ingham Log::Callbacks log_callbacks; 2329228063cdSJim Ingham 2330228063cdSJim Ingham StreamSP log_stream_sp; 2331228063cdSJim Ingham if (m_log_callback_stream_sp != NULL) 2332228063cdSJim Ingham { 2333228063cdSJim Ingham log_stream_sp = m_log_callback_stream_sp; 2334228063cdSJim Ingham // For now when using the callback mode you always get thread & timestamp. 2335228063cdSJim Ingham log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 2336228063cdSJim Ingham } 2337228063cdSJim Ingham else if (log_file == NULL || *log_file == '\0') 2338228063cdSJim Ingham { 2339228063cdSJim Ingham log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false)); 2340228063cdSJim Ingham } 2341228063cdSJim Ingham else 2342228063cdSJim Ingham { 2343228063cdSJim Ingham LogStreamMap::iterator pos = m_log_streams.find(log_file); 2344228063cdSJim Ingham if (pos == m_log_streams.end()) 2345228063cdSJim Ingham { 2346228063cdSJim Ingham log_stream_sp.reset (new StreamFile (log_file)); 2347228063cdSJim Ingham m_log_streams[log_file] = log_stream_sp; 2348228063cdSJim Ingham } 2349228063cdSJim Ingham else 2350228063cdSJim Ingham log_stream_sp = pos->second; 2351228063cdSJim Ingham } 2352228063cdSJim Ingham assert (log_stream_sp.get()); 2353228063cdSJim Ingham 2354228063cdSJim Ingham if (log_options == 0) 2355228063cdSJim Ingham log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 2356228063cdSJim Ingham 2357228063cdSJim Ingham if (Log::GetLogChannelCallbacks (channel, log_callbacks)) 2358228063cdSJim Ingham { 2359228063cdSJim Ingham log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream); 2360228063cdSJim Ingham return true; 2361228063cdSJim Ingham } 2362228063cdSJim Ingham else 2363228063cdSJim Ingham { 2364228063cdSJim Ingham LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel)); 2365228063cdSJim Ingham if (log_channel_sp) 2366228063cdSJim Ingham { 2367228063cdSJim Ingham if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories)) 2368228063cdSJim Ingham { 2369228063cdSJim Ingham return true; 2370228063cdSJim Ingham } 2371228063cdSJim Ingham else 2372228063cdSJim Ingham { 2373228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2374228063cdSJim Ingham return false; 2375228063cdSJim Ingham } 2376228063cdSJim Ingham } 2377228063cdSJim Ingham else 2378228063cdSJim Ingham { 2379228063cdSJim Ingham error_stream.Printf ("Invalid log channel '%s'.\n", channel); 2380228063cdSJim Ingham return false; 2381228063cdSJim Ingham } 2382228063cdSJim Ingham } 2383228063cdSJim Ingham return false; 2384228063cdSJim Ingham } 2385228063cdSJim Ingham 23861b654882SGreg Clayton #pragma mark Debugger::SettingsController 23871b654882SGreg Clayton 23883df9a8dfSCaroline Tice //-------------------------------------------------- 23891b654882SGreg Clayton // class Debugger::SettingsController 23903df9a8dfSCaroline Tice //-------------------------------------------------- 23913df9a8dfSCaroline Tice 23921b654882SGreg Clayton Debugger::SettingsController::SettingsController () : 23934d122c40SGreg Clayton UserSettingsController ("", UserSettingsControllerSP()) 23943df9a8dfSCaroline Tice { 23953df9a8dfSCaroline Tice } 23963df9a8dfSCaroline Tice 23971b654882SGreg Clayton Debugger::SettingsController::~SettingsController () 23983df9a8dfSCaroline Tice { 23993df9a8dfSCaroline Tice } 24003df9a8dfSCaroline Tice 24013df9a8dfSCaroline Tice 24024d122c40SGreg Clayton InstanceSettingsSP 24031b654882SGreg Clayton Debugger::SettingsController::CreateInstanceSettings (const char *instance_name) 24043df9a8dfSCaroline Tice { 2405b9556accSGreg Clayton InstanceSettingsSP new_settings_sp (new DebuggerInstanceSettings (GetSettingsController(), 2406b9556accSGreg Clayton false, 2407b9556accSGreg Clayton instance_name)); 24083df9a8dfSCaroline Tice return new_settings_sp; 24093df9a8dfSCaroline Tice } 24103df9a8dfSCaroline Tice 24111b654882SGreg Clayton #pragma mark DebuggerInstanceSettings 24123df9a8dfSCaroline Tice //-------------------------------------------------- 24133df9a8dfSCaroline Tice // class DebuggerInstanceSettings 24143df9a8dfSCaroline Tice //-------------------------------------------------- 24153df9a8dfSCaroline Tice 2416a7015092SGreg Clayton DebuggerInstanceSettings::DebuggerInstanceSettings 2417a7015092SGreg Clayton ( 2418b9556accSGreg Clayton const UserSettingsControllerSP &m_owner_sp, 2419a7015092SGreg Clayton bool live_instance, 2420a7015092SGreg Clayton const char *name 2421a7015092SGreg Clayton ) : 2422b9556accSGreg Clayton InstanceSettings (m_owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), 2423a7015092SGreg Clayton m_term_width (80), 2424e372b98dSGreg Clayton m_stop_source_before_count (3), 2425e372b98dSGreg Clayton m_stop_source_after_count (3), 2426e372b98dSGreg Clayton m_stop_disassembly_count (4), 2427e372b98dSGreg Clayton m_stop_disassembly_display (eStopDisassemblyTypeNoSource), 24283df9a8dfSCaroline Tice m_prompt (), 24290603aa9dSGreg Clayton m_frame_format (), 24300603aa9dSGreg Clayton m_thread_format (), 2431daccaa9eSCaroline Tice m_script_lang (), 24323bcdb29cSJim Ingham m_use_external_editor (false), 24333bcdb29cSJim Ingham m_auto_confirm_on (false) 24343df9a8dfSCaroline Tice { 2435f20e8239SCaroline Tice // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called 2436f20e8239SCaroline Tice // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers. 2437f20e8239SCaroline Tice // For this reason it has to be called here, rather than in the initializer or in the parent constructor. 24389e41c15dSCaroline Tice // The same is true of CreateInstanceName(). 24399e41c15dSCaroline Tice 24409e41c15dSCaroline Tice if (GetInstanceName() == InstanceSettings::InvalidName()) 24419e41c15dSCaroline Tice { 24429e41c15dSCaroline Tice ChangeInstanceName (std::string (CreateInstanceName().AsCString())); 2443b9556accSGreg Clayton m_owner_sp->RegisterInstanceSettings (this); 24449e41c15dSCaroline Tice } 2445f20e8239SCaroline Tice 2446f20e8239SCaroline Tice if (live_instance) 24473df9a8dfSCaroline Tice { 2448b9556accSGreg Clayton const InstanceSettingsSP &pending_settings = m_owner_sp->FindPendingSettings (m_instance_name); 24493df9a8dfSCaroline Tice CopyInstanceSettings (pending_settings, false); 24503df9a8dfSCaroline Tice } 24513df9a8dfSCaroline Tice } 24523df9a8dfSCaroline Tice 24533df9a8dfSCaroline Tice DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) : 2454b9556accSGreg Clayton InstanceSettings (Debugger::GetSettingsController(), CreateInstanceName ().AsCString()), 24553df9a8dfSCaroline Tice m_prompt (rhs.m_prompt), 24560603aa9dSGreg Clayton m_frame_format (rhs.m_frame_format), 24570603aa9dSGreg Clayton m_thread_format (rhs.m_thread_format), 2458daccaa9eSCaroline Tice m_script_lang (rhs.m_script_lang), 24593bcdb29cSJim Ingham m_use_external_editor (rhs.m_use_external_editor), 24603bcdb29cSJim Ingham m_auto_confirm_on(rhs.m_auto_confirm_on) 24613df9a8dfSCaroline Tice { 2462b9556accSGreg Clayton UserSettingsControllerSP owner_sp (m_owner_wp.lock()); 2463b9556accSGreg Clayton if (owner_sp) 2464b9556accSGreg Clayton { 2465b9556accSGreg Clayton CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false); 2466b9556accSGreg Clayton owner_sp->RemovePendingSettings (m_instance_name); 2467b9556accSGreg Clayton } 24683df9a8dfSCaroline Tice } 24693df9a8dfSCaroline Tice 24703df9a8dfSCaroline Tice DebuggerInstanceSettings::~DebuggerInstanceSettings () 24713df9a8dfSCaroline Tice { 24723df9a8dfSCaroline Tice } 24733df9a8dfSCaroline Tice 24743df9a8dfSCaroline Tice DebuggerInstanceSettings& 24753df9a8dfSCaroline Tice DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs) 24763df9a8dfSCaroline Tice { 24773df9a8dfSCaroline Tice if (this != &rhs) 24783df9a8dfSCaroline Tice { 24791b654882SGreg Clayton m_term_width = rhs.m_term_width; 24803df9a8dfSCaroline Tice m_prompt = rhs.m_prompt; 24810603aa9dSGreg Clayton m_frame_format = rhs.m_frame_format; 24820603aa9dSGreg Clayton m_thread_format = rhs.m_thread_format; 24833df9a8dfSCaroline Tice m_script_lang = rhs.m_script_lang; 2484daccaa9eSCaroline Tice m_use_external_editor = rhs.m_use_external_editor; 24853bcdb29cSJim Ingham m_auto_confirm_on = rhs.m_auto_confirm_on; 24863df9a8dfSCaroline Tice } 24873df9a8dfSCaroline Tice 24883df9a8dfSCaroline Tice return *this; 24893df9a8dfSCaroline Tice } 24903df9a8dfSCaroline Tice 24911b654882SGreg Clayton bool 24921b654882SGreg Clayton DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err) 24931b654882SGreg Clayton { 24941b654882SGreg Clayton bool valid = false; 24951b654882SGreg Clayton 24961b654882SGreg Clayton // Verify we have a value string. 24971b654882SGreg Clayton if (value == NULL || value[0] == '\0') 24981b654882SGreg Clayton { 249986edbf41SGreg Clayton err.SetErrorString ("missing value, can't set terminal width without a value"); 25001b654882SGreg Clayton } 25011b654882SGreg Clayton else 25021b654882SGreg Clayton { 25031b654882SGreg Clayton char *end = NULL; 25041b654882SGreg Clayton const uint32_t width = ::strtoul (value, &end, 0); 25051b654882SGreg Clayton 2506ea9fc181SJohnny Chen if (end && end[0] == '\0') 25071b654882SGreg Clayton { 2508433d7741SJohnny Chen if (width >= 10 && width <= 1024) 25091b654882SGreg Clayton valid = true; 25101b654882SGreg Clayton else 251186edbf41SGreg Clayton err.SetErrorString ("invalid term-width value; value must be between 10 and 1024"); 25121b654882SGreg Clayton } 25131b654882SGreg Clayton else 251486edbf41SGreg Clayton err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string", value); 25151b654882SGreg Clayton } 25161b654882SGreg Clayton 25171b654882SGreg Clayton return valid; 25181b654882SGreg Clayton } 25191b654882SGreg Clayton 25201b654882SGreg Clayton 25213df9a8dfSCaroline Tice void 25223df9a8dfSCaroline Tice DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, 25233df9a8dfSCaroline Tice const char *index_value, 25243df9a8dfSCaroline Tice const char *value, 25253df9a8dfSCaroline Tice const ConstString &instance_name, 25263df9a8dfSCaroline Tice const SettingEntry &entry, 2527e0d378b3SGreg Clayton VarSetOperationType op, 25283df9a8dfSCaroline Tice Error &err, 25293df9a8dfSCaroline Tice bool pending) 25303df9a8dfSCaroline Tice { 25310603aa9dSGreg Clayton 25320603aa9dSGreg Clayton if (var_name == TermWidthVarName()) 25330603aa9dSGreg Clayton { 25340603aa9dSGreg Clayton if (ValidTermWidthValue (value, err)) 25350603aa9dSGreg Clayton { 25360603aa9dSGreg Clayton m_term_width = ::strtoul (value, NULL, 0); 25370603aa9dSGreg Clayton } 25380603aa9dSGreg Clayton } 25390603aa9dSGreg Clayton else if (var_name == PromptVarName()) 25403df9a8dfSCaroline Tice { 25413df9a8dfSCaroline Tice UserSettingsController::UpdateStringVariable (op, m_prompt, value, err); 25423df9a8dfSCaroline Tice if (!pending) 25433df9a8dfSCaroline Tice { 254449e2737eSCaroline Tice // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to 254549e2737eSCaroline Tice // strip off the brackets before passing it to BroadcastPromptChange. 254649e2737eSCaroline Tice 254749e2737eSCaroline Tice std::string tmp_instance_name (instance_name.AsCString()); 254849e2737eSCaroline Tice if ((tmp_instance_name[0] == '[') 254949e2737eSCaroline Tice && (tmp_instance_name[instance_name.GetLength() - 1] == ']')) 255049e2737eSCaroline Tice tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2); 255149e2737eSCaroline Tice ConstString new_name (tmp_instance_name.c_str()); 255249e2737eSCaroline Tice 255349e2737eSCaroline Tice BroadcastPromptChange (new_name, m_prompt.c_str()); 25543df9a8dfSCaroline Tice } 25553df9a8dfSCaroline Tice } 25560603aa9dSGreg Clayton else if (var_name == GetFrameFormatName()) 25570603aa9dSGreg Clayton { 25580603aa9dSGreg Clayton UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err); 25590603aa9dSGreg Clayton } 25600603aa9dSGreg Clayton else if (var_name == GetThreadFormatName()) 25610603aa9dSGreg Clayton { 25620603aa9dSGreg Clayton UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err); 25630603aa9dSGreg Clayton } 25643df9a8dfSCaroline Tice else if (var_name == ScriptLangVarName()) 25653df9a8dfSCaroline Tice { 25663df9a8dfSCaroline Tice bool success; 25673df9a8dfSCaroline Tice m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault, 25683df9a8dfSCaroline Tice &success); 25693df9a8dfSCaroline Tice } 2570daccaa9eSCaroline Tice else if (var_name == UseExternalEditorVarName ()) 2571daccaa9eSCaroline Tice { 2572385aa28cSGreg Clayton UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err); 2573daccaa9eSCaroline Tice } 25743bcdb29cSJim Ingham else if (var_name == AutoConfirmName ()) 25753bcdb29cSJim Ingham { 2576385aa28cSGreg Clayton UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err); 25773bcdb29cSJim Ingham } 2578e372b98dSGreg Clayton else if (var_name == StopSourceContextBeforeName ()) 2579e372b98dSGreg Clayton { 2580e372b98dSGreg Clayton uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL); 2581e372b98dSGreg Clayton if (new_value != UINT32_MAX) 2582e372b98dSGreg Clayton m_stop_source_before_count = new_value; 2583e372b98dSGreg Clayton else 2584e372b98dSGreg Clayton err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextAfterName ().GetCString()); 2585e372b98dSGreg Clayton } 2586e372b98dSGreg Clayton else if (var_name == StopSourceContextAfterName ()) 2587e372b98dSGreg Clayton { 2588e372b98dSGreg Clayton uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL); 2589e372b98dSGreg Clayton if (new_value != UINT32_MAX) 2590e372b98dSGreg Clayton m_stop_source_after_count = new_value; 2591e372b98dSGreg Clayton else 2592e372b98dSGreg Clayton err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextBeforeName ().GetCString()); 2593e372b98dSGreg Clayton } 2594e372b98dSGreg Clayton else if (var_name == StopDisassemblyCountName ()) 2595e372b98dSGreg Clayton { 2596e372b98dSGreg Clayton uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL); 2597e372b98dSGreg Clayton if (new_value != UINT32_MAX) 2598e372b98dSGreg Clayton m_stop_disassembly_count = new_value; 2599e372b98dSGreg Clayton else 2600e372b98dSGreg Clayton err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopDisassemblyCountName ().GetCString()); 2601e372b98dSGreg Clayton } 2602e372b98dSGreg Clayton else if (var_name == StopDisassemblyDisplayName ()) 2603e372b98dSGreg Clayton { 2604e372b98dSGreg Clayton int new_value; 2605e372b98dSGreg Clayton UserSettingsController::UpdateEnumVariable (g_show_disassembly_enum_values, &new_value, value, err); 2606e372b98dSGreg Clayton if (err.Success()) 2607e372b98dSGreg Clayton m_stop_disassembly_display = (StopDisassemblyType)new_value; 2608e372b98dSGreg Clayton } 26093df9a8dfSCaroline Tice } 26103df9a8dfSCaroline Tice 261112cecd74SCaroline Tice bool 26123df9a8dfSCaroline Tice DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, 26133df9a8dfSCaroline Tice const ConstString &var_name, 2614daccaa9eSCaroline Tice StringList &value, 261512cecd74SCaroline Tice Error *err) 26163df9a8dfSCaroline Tice { 26173df9a8dfSCaroline Tice if (var_name == PromptVarName()) 26183df9a8dfSCaroline Tice { 26190603aa9dSGreg Clayton value.AppendString (m_prompt.c_str(), m_prompt.size()); 26203df9a8dfSCaroline Tice 26213df9a8dfSCaroline Tice } 26223df9a8dfSCaroline Tice else if (var_name == ScriptLangVarName()) 26233df9a8dfSCaroline Tice { 26243df9a8dfSCaroline Tice value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str()); 26253df9a8dfSCaroline Tice } 2626101c7c20SCaroline Tice else if (var_name == TermWidthVarName()) 2627101c7c20SCaroline Tice { 2628101c7c20SCaroline Tice StreamString width_str; 2629e372b98dSGreg Clayton width_str.Printf ("%u", m_term_width); 2630101c7c20SCaroline Tice value.AppendString (width_str.GetData()); 2631101c7c20SCaroline Tice } 26320603aa9dSGreg Clayton else if (var_name == GetFrameFormatName ()) 26330603aa9dSGreg Clayton { 26340603aa9dSGreg Clayton value.AppendString(m_frame_format.c_str(), m_frame_format.size()); 26350603aa9dSGreg Clayton } 26360603aa9dSGreg Clayton else if (var_name == GetThreadFormatName ()) 26370603aa9dSGreg Clayton { 26380603aa9dSGreg Clayton value.AppendString(m_thread_format.c_str(), m_thread_format.size()); 26390603aa9dSGreg Clayton } 2640daccaa9eSCaroline Tice else if (var_name == UseExternalEditorVarName()) 2641daccaa9eSCaroline Tice { 2642daccaa9eSCaroline Tice if (m_use_external_editor) 2643daccaa9eSCaroline Tice value.AppendString ("true"); 2644daccaa9eSCaroline Tice else 2645daccaa9eSCaroline Tice value.AppendString ("false"); 2646daccaa9eSCaroline Tice } 26473bcdb29cSJim Ingham else if (var_name == AutoConfirmName()) 26483bcdb29cSJim Ingham { 26493bcdb29cSJim Ingham if (m_auto_confirm_on) 26503bcdb29cSJim Ingham value.AppendString ("true"); 26513bcdb29cSJim Ingham else 26523bcdb29cSJim Ingham value.AppendString ("false"); 26533bcdb29cSJim Ingham } 2654e372b98dSGreg Clayton else if (var_name == StopSourceContextAfterName ()) 2655e372b98dSGreg Clayton { 2656e372b98dSGreg Clayton StreamString strm; 2657e372b98dSGreg Clayton strm.Printf ("%u", m_stop_source_before_count); 2658e372b98dSGreg Clayton value.AppendString (strm.GetData()); 2659e372b98dSGreg Clayton } 2660e372b98dSGreg Clayton else if (var_name == StopSourceContextBeforeName ()) 2661e372b98dSGreg Clayton { 2662e372b98dSGreg Clayton StreamString strm; 2663e372b98dSGreg Clayton strm.Printf ("%u", m_stop_source_after_count); 2664e372b98dSGreg Clayton value.AppendString (strm.GetData()); 2665e372b98dSGreg Clayton } 2666e372b98dSGreg Clayton else if (var_name == StopDisassemblyCountName ()) 2667e372b98dSGreg Clayton { 2668e372b98dSGreg Clayton StreamString strm; 2669e372b98dSGreg Clayton strm.Printf ("%u", m_stop_disassembly_count); 2670e372b98dSGreg Clayton value.AppendString (strm.GetData()); 2671e372b98dSGreg Clayton } 2672e372b98dSGreg Clayton else if (var_name == StopDisassemblyDisplayName ()) 2673e372b98dSGreg Clayton { 2674e372b98dSGreg Clayton if (m_stop_disassembly_display >= eStopDisassemblyTypeNever && m_stop_disassembly_display <= eStopDisassemblyTypeAlways) 2675e372b98dSGreg Clayton value.AppendString (g_show_disassembly_enum_values[m_stop_disassembly_display].string_value); 2676e372b98dSGreg Clayton else 2677e372b98dSGreg Clayton value.AppendString ("<invalid>"); 2678e372b98dSGreg Clayton } 2679daccaa9eSCaroline Tice else 268012cecd74SCaroline Tice { 268112cecd74SCaroline Tice if (err) 268212cecd74SCaroline Tice err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString()); 268312cecd74SCaroline Tice return false; 268412cecd74SCaroline Tice } 268512cecd74SCaroline Tice return true; 26863df9a8dfSCaroline Tice } 26873df9a8dfSCaroline Tice 26883df9a8dfSCaroline Tice void 26894d122c40SGreg Clayton DebuggerInstanceSettings::CopyInstanceSettings (const InstanceSettingsSP &new_settings, 26903df9a8dfSCaroline Tice bool pending) 26913df9a8dfSCaroline Tice { 26923df9a8dfSCaroline Tice if (new_settings.get() == NULL) 26933df9a8dfSCaroline Tice return; 26943df9a8dfSCaroline Tice 26953df9a8dfSCaroline Tice DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get(); 26963df9a8dfSCaroline Tice 26973df9a8dfSCaroline Tice m_prompt = new_debugger_settings->m_prompt; 26983df9a8dfSCaroline Tice if (!pending) 269949e2737eSCaroline Tice { 270049e2737eSCaroline Tice // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to 270149e2737eSCaroline Tice // strip off the brackets before passing it to BroadcastPromptChange. 270249e2737eSCaroline Tice 270349e2737eSCaroline Tice std::string tmp_instance_name (m_instance_name.AsCString()); 270449e2737eSCaroline Tice if ((tmp_instance_name[0] == '[') 270549e2737eSCaroline Tice && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']')) 270649e2737eSCaroline Tice tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2); 270749e2737eSCaroline Tice ConstString new_name (tmp_instance_name.c_str()); 270849e2737eSCaroline Tice 270949e2737eSCaroline Tice BroadcastPromptChange (new_name, m_prompt.c_str()); 271049e2737eSCaroline Tice } 27110603aa9dSGreg Clayton m_frame_format = new_debugger_settings->m_frame_format; 27120603aa9dSGreg Clayton m_thread_format = new_debugger_settings->m_thread_format; 2713daccaa9eSCaroline Tice m_term_width = new_debugger_settings->m_term_width; 27143df9a8dfSCaroline Tice m_script_lang = new_debugger_settings->m_script_lang; 2715daccaa9eSCaroline Tice m_use_external_editor = new_debugger_settings->m_use_external_editor; 27163bcdb29cSJim Ingham m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on; 27173df9a8dfSCaroline Tice } 27183df9a8dfSCaroline Tice 27193df9a8dfSCaroline Tice 27203df9a8dfSCaroline Tice bool 27213df9a8dfSCaroline Tice DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt) 27223df9a8dfSCaroline Tice { 27233df9a8dfSCaroline Tice std::string tmp_prompt; 27243df9a8dfSCaroline Tice 27253df9a8dfSCaroline Tice if (new_prompt != NULL) 27263df9a8dfSCaroline Tice { 27273df9a8dfSCaroline Tice tmp_prompt = new_prompt ; 27283df9a8dfSCaroline Tice int len = tmp_prompt.size(); 27293df9a8dfSCaroline Tice if (len > 1 27303df9a8dfSCaroline Tice && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"') 27313df9a8dfSCaroline Tice && (tmp_prompt[len-1] == tmp_prompt[0])) 27323df9a8dfSCaroline Tice { 27333df9a8dfSCaroline Tice tmp_prompt = tmp_prompt.substr(1,len-2); 27343df9a8dfSCaroline Tice } 27353df9a8dfSCaroline Tice len = tmp_prompt.size(); 27363df9a8dfSCaroline Tice if (tmp_prompt[len-1] != ' ') 27373df9a8dfSCaroline Tice tmp_prompt.append(" "); 27383df9a8dfSCaroline Tice } 27393df9a8dfSCaroline Tice EventSP new_event_sp; 27403df9a8dfSCaroline Tice new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt, 27413df9a8dfSCaroline Tice new EventDataBytes (tmp_prompt.c_str()))); 27423df9a8dfSCaroline Tice 27433df9a8dfSCaroline Tice if (instance_name.GetLength() != 0) 27443df9a8dfSCaroline Tice { 27453df9a8dfSCaroline Tice // Set prompt for a particular instance. 27463df9a8dfSCaroline Tice Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get(); 27473df9a8dfSCaroline Tice if (dbg != NULL) 27483df9a8dfSCaroline Tice { 27493df9a8dfSCaroline Tice dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp); 27503df9a8dfSCaroline Tice } 27513df9a8dfSCaroline Tice } 27523df9a8dfSCaroline Tice 27533df9a8dfSCaroline Tice return true; 27543df9a8dfSCaroline Tice } 27553df9a8dfSCaroline Tice 27563df9a8dfSCaroline Tice const ConstString 27573df9a8dfSCaroline Tice DebuggerInstanceSettings::CreateInstanceName () 27583df9a8dfSCaroline Tice { 27593df9a8dfSCaroline Tice static int instance_count = 1; 27603df9a8dfSCaroline Tice StreamString sstr; 27613df9a8dfSCaroline Tice 27623df9a8dfSCaroline Tice sstr.Printf ("debugger_%d", instance_count); 27633df9a8dfSCaroline Tice ++instance_count; 27643df9a8dfSCaroline Tice 27653df9a8dfSCaroline Tice const ConstString ret_val (sstr.GetData()); 27663df9a8dfSCaroline Tice 27673df9a8dfSCaroline Tice return ret_val; 27683df9a8dfSCaroline Tice } 27693df9a8dfSCaroline Tice 27703bcdb29cSJim Ingham 27713df9a8dfSCaroline Tice //-------------------------------------------------- 27721b654882SGreg Clayton // SettingsController Variable Tables 27733df9a8dfSCaroline Tice //-------------------------------------------------- 27743df9a8dfSCaroline Tice 27753df9a8dfSCaroline Tice 27763df9a8dfSCaroline Tice SettingEntry 27771b654882SGreg Clayton Debugger::SettingsController::global_settings_table[] = 27783df9a8dfSCaroline Tice { 27793df9a8dfSCaroline Tice //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, 2780101c7c20SCaroline Tice // The Debugger level global table should always be empty; all Debugger settable variables should be instance 2781101c7c20SCaroline Tice // variables. 27823df9a8dfSCaroline Tice { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 27833df9a8dfSCaroline Tice }; 27843df9a8dfSCaroline Tice 2785bb562b13SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}" 27860603aa9dSGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" 27873df9a8dfSCaroline Tice 27880603aa9dSGreg Clayton #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 27890603aa9dSGreg Clayton "{, ${frame.pc}}"\ 27900603aa9dSGreg Clayton MODULE_WITH_FUNC\ 2791cf4b9078SGreg Clayton FILE_AND_LINE\ 27920603aa9dSGreg Clayton "{, stop reason = ${thread.stop-reason}}"\ 2793ef651600SJim Ingham "{\\nReturn value: ${thread.return-value}}"\ 27940603aa9dSGreg Clayton "\\n" 27950603aa9dSGreg Clayton 2796315d2cabSGreg Clayton //#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\ 2797315d2cabSGreg Clayton // "{, ${frame.pc}}"\ 2798315d2cabSGreg Clayton // MODULE_WITH_FUNC\ 2799315d2cabSGreg Clayton // FILE_AND_LINE\ 2800315d2cabSGreg Clayton // "{, stop reason = ${thread.stop-reason}}"\ 2801315d2cabSGreg Clayton // "{, name = ${thread.name}}"\ 2802315d2cabSGreg Clayton // "{, queue = ${thread.queue}}"\ 2803315d2cabSGreg Clayton // "\\n" 2804315d2cabSGreg Clayton 28050603aa9dSGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ 28060603aa9dSGreg Clayton MODULE_WITH_FUNC\ 28070603aa9dSGreg Clayton FILE_AND_LINE\ 28080603aa9dSGreg Clayton "\\n" 28093df9a8dfSCaroline Tice 28103df9a8dfSCaroline Tice SettingEntry 28111b654882SGreg Clayton Debugger::SettingsController::instance_settings_table[] = 28123df9a8dfSCaroline Tice { 28130603aa9dSGreg Clayton // NAME Setting variable type Default Enum Init'd Hidden Help 28140603aa9dSGreg Clayton // ======================= ======================= ====================== ==== ====== ====== ====================== 28150603aa9dSGreg Clayton { "frame-format", eSetVarTypeString, DEFAULT_FRAME_FORMAT, NULL, false, false, "The default frame format string to use when displaying thread information." }, 28163bcdb29cSJim Ingham { "prompt", eSetVarTypeString, "(lldb) ", NULL, false, false, "The debugger command line prompt displayed for the user." }, 28173bcdb29cSJim Ingham { "script-lang", eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." }, 28183bcdb29cSJim Ingham { "term-width", eSetVarTypeInt, "80" , NULL, false, false, "The maximum number of columns to use for displaying text." }, 28190603aa9dSGreg Clayton { "thread-format", eSetVarTypeString, DEFAULT_THREAD_FORMAT, NULL, false, false, "The default thread format string to use when displaying thread information." }, 282006e827ccSJim Ingham { "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." }, 282106e827ccSJim Ingham { "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." }, 2822e372b98dSGreg Clayton { "stop-line-count-before",eSetVarTypeInt, "3", NULL, false, false, "The number of sources lines to display that come before the current source line when displaying a stopped context." }, 2823e372b98dSGreg Clayton { "stop-line-count-after", eSetVarTypeInt, "3", NULL, false, false, "The number of sources lines to display that come after the current source line when displaying a stopped context." }, 2824e372b98dSGreg Clayton { "stop-disassembly-count", eSetVarTypeInt, "0", NULL, false, false, "The number of disassembly lines to show when displaying a stopped context." }, 2825e372b98dSGreg Clayton { "stop-disassembly-display", eSetVarTypeEnum, "no-source", g_show_disassembly_enum_values, false, false, "Control when to display disassembly when displaying a stopped context." }, 28260603aa9dSGreg Clayton { NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL } 28273df9a8dfSCaroline Tice }; 2828