OperatingSystemPython.cpp revision 263363
1254721Semaste//===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#ifndef LLDB_DISABLE_PYTHON 13254721Semaste 14254721Semaste#include "OperatingSystemPython.h" 15254721Semaste// C Includes 16254721Semaste// C++ Includes 17254721Semaste// Other libraries and framework includes 18254721Semaste#include "lldb/Core/ArchSpec.h" 19254721Semaste#include "lldb/Core/DataBufferHeap.h" 20254721Semaste#include "lldb/Core/Debugger.h" 21254721Semaste#include "lldb/Core/Module.h" 22254721Semaste#include "lldb/Core/PluginManager.h" 23254721Semaste#include "lldb/Core/RegisterValue.h" 24254721Semaste#include "lldb/Core/StreamString.h" 25254721Semaste#include "lldb/Core/ValueObjectVariable.h" 26254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 27254721Semaste#include "lldb/Interpreter/PythonDataObjects.h" 28254721Semaste#include "lldb/Symbol/ClangNamespaceDecl.h" 29254721Semaste#include "lldb/Symbol/ObjectFile.h" 30254721Semaste#include "lldb/Symbol/VariableList.h" 31254721Semaste#include "lldb/Target/Process.h" 32254721Semaste#include "lldb/Target/StopInfo.h" 33254721Semaste#include "lldb/Target/Target.h" 34254721Semaste#include "lldb/Target/ThreadList.h" 35254721Semaste#include "lldb/Target/Thread.h" 36254721Semaste#include "Plugins/Process/Utility/DynamicRegisterInfo.h" 37254721Semaste#include "Plugins/Process/Utility/RegisterContextDummy.h" 38254721Semaste#include "Plugins/Process/Utility/RegisterContextMemory.h" 39254721Semaste#include "Plugins/Process/Utility/ThreadMemory.h" 40254721Semaste 41254721Semasteusing namespace lldb; 42254721Semasteusing namespace lldb_private; 43254721Semaste 44254721Semastevoid 45254721SemasteOperatingSystemPython::Initialize() 46254721Semaste{ 47254721Semaste PluginManager::RegisterPlugin (GetPluginNameStatic(), 48254721Semaste GetPluginDescriptionStatic(), 49254721Semaste CreateInstance); 50254721Semaste} 51254721Semaste 52254721Semastevoid 53254721SemasteOperatingSystemPython::Terminate() 54254721Semaste{ 55254721Semaste PluginManager::UnregisterPlugin (CreateInstance); 56254721Semaste} 57254721Semaste 58254721SemasteOperatingSystem * 59254721SemasteOperatingSystemPython::CreateInstance (Process *process, bool force) 60254721Semaste{ 61254721Semaste // Python OperatingSystem plug-ins must be requested by name, so force must be true 62254721Semaste FileSpec python_os_plugin_spec (process->GetPythonOSPluginPath()); 63254721Semaste if (python_os_plugin_spec && python_os_plugin_spec.Exists()) 64254721Semaste { 65254721Semaste std::unique_ptr<OperatingSystemPython> os_ap (new OperatingSystemPython (process, python_os_plugin_spec)); 66254721Semaste if (os_ap.get() && os_ap->IsValid()) 67254721Semaste return os_ap.release(); 68254721Semaste } 69254721Semaste return NULL; 70254721Semaste} 71254721Semaste 72254721Semaste 73254721SemasteConstString 74254721SemasteOperatingSystemPython::GetPluginNameStatic() 75254721Semaste{ 76254721Semaste static ConstString g_name("python"); 77254721Semaste return g_name; 78254721Semaste} 79254721Semaste 80254721Semasteconst char * 81254721SemasteOperatingSystemPython::GetPluginDescriptionStatic() 82254721Semaste{ 83254721Semaste return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality."; 84254721Semaste} 85254721Semaste 86254721Semaste 87254721SemasteOperatingSystemPython::OperatingSystemPython (lldb_private::Process *process, const FileSpec &python_module_path) : 88254721Semaste OperatingSystem (process), 89254721Semaste m_thread_list_valobj_sp (), 90254721Semaste m_register_info_ap (), 91254721Semaste m_interpreter (NULL), 92254721Semaste m_python_object_sp () 93254721Semaste{ 94254721Semaste if (!process) 95254721Semaste return; 96254721Semaste TargetSP target_sp = process->CalculateTarget(); 97254721Semaste if (!target_sp) 98254721Semaste return; 99254721Semaste m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 100254721Semaste if (m_interpreter) 101254721Semaste { 102254721Semaste 103254721Semaste std::string os_plugin_class_name (python_module_path.GetFilename().AsCString("")); 104254721Semaste if (!os_plugin_class_name.empty()) 105254721Semaste { 106254721Semaste const bool init_session = false; 107254721Semaste const bool allow_reload = true; 108254721Semaste char python_module_path_cstr[PATH_MAX]; 109254721Semaste python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr)); 110254721Semaste Error error; 111254721Semaste if (m_interpreter->LoadScriptingModule (python_module_path_cstr, allow_reload, init_session, error)) 112254721Semaste { 113254721Semaste // Strip the ".py" extension if there is one 114254721Semaste size_t py_extension_pos = os_plugin_class_name.rfind(".py"); 115254721Semaste if (py_extension_pos != std::string::npos) 116254721Semaste os_plugin_class_name.erase (py_extension_pos); 117254721Semaste // Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn" 118254721Semaste os_plugin_class_name += ".OperatingSystemPlugIn"; 119254721Semaste ScriptInterpreterObjectSP object_sp = m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess()); 120254721Semaste if (object_sp && object_sp->GetObject()) 121254721Semaste m_python_object_sp = object_sp; 122254721Semaste } 123254721Semaste } 124254721Semaste } 125254721Semaste} 126254721Semaste 127254721SemasteOperatingSystemPython::~OperatingSystemPython () 128254721Semaste{ 129254721Semaste} 130254721Semaste 131254721SemasteDynamicRegisterInfo * 132254721SemasteOperatingSystemPython::GetDynamicRegisterInfo () 133254721Semaste{ 134254721Semaste if (m_register_info_ap.get() == NULL) 135254721Semaste { 136254721Semaste if (!m_interpreter || !m_python_object_sp) 137254721Semaste return NULL; 138254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS)); 139254721Semaste 140254721Semaste if (log) 141254721Semaste log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID()); 142254721Semaste 143254721Semaste PythonDictionary dictionary(m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp)); 144254721Semaste if (!dictionary) 145254721Semaste return NULL; 146254721Semaste 147263363Semaste m_register_info_ap.reset (new DynamicRegisterInfo (dictionary, m_process->GetTarget().GetArchitecture().GetByteOrder())); 148254721Semaste assert (m_register_info_ap->GetNumRegisters() > 0); 149254721Semaste assert (m_register_info_ap->GetNumRegisterSets() > 0); 150254721Semaste } 151254721Semaste return m_register_info_ap.get(); 152254721Semaste} 153254721Semaste 154254721Semaste//------------------------------------------------------------------ 155254721Semaste// PluginInterface protocol 156254721Semaste//------------------------------------------------------------------ 157254721SemasteConstString 158254721SemasteOperatingSystemPython::GetPluginName() 159254721Semaste{ 160254721Semaste return GetPluginNameStatic(); 161254721Semaste} 162254721Semaste 163254721Semasteuint32_t 164254721SemasteOperatingSystemPython::GetPluginVersion() 165254721Semaste{ 166254721Semaste return 1; 167254721Semaste} 168254721Semaste 169254721Semastebool 170254721SemasteOperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, 171254721Semaste ThreadList &core_thread_list, 172254721Semaste ThreadList &new_thread_list) 173254721Semaste{ 174254721Semaste if (!m_interpreter || !m_python_object_sp) 175254721Semaste return false; 176254721Semaste 177254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS)); 178254721Semaste 179254721Semaste // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 180254721Semaste // content of the process, and we're going to use python, which requires the API lock to do it. 181254721Semaste // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 182254721Semaste Target &target = m_process->GetTarget(); 183254721Semaste Mutex::Locker api_locker (target.GetAPIMutex()); 184254721Semaste 185254721Semaste if (log) 186254721Semaste log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %" PRIu64, m_process->GetID()); 187254721Semaste 188254721Semaste // The threads that are in "new_thread_list" upon entry are the threads from the 189254721Semaste // lldb_private::Process subclass, no memory threads will be in this list. 190254721Semaste 191254721Semaste auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive 192254721Semaste PythonList threads_list(m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp)); 193254721Semaste if (threads_list) 194254721Semaste { 195254721Semaste if (log) 196254721Semaste { 197254721Semaste StreamString strm; 198254721Semaste threads_list.Dump(strm); 199254721Semaste log->Printf("threads_list = %s", strm.GetString().c_str()); 200254721Semaste } 201254721Semaste uint32_t i; 202254721Semaste const uint32_t num_threads = threads_list.GetSize(); 203254721Semaste if (num_threads > 0) 204254721Semaste { 205254721Semaste for (i=0; i<num_threads; ++i) 206254721Semaste { 207254721Semaste PythonDictionary thread_dict(threads_list.GetItemAtIndex(i)); 208254721Semaste if (thread_dict) 209254721Semaste { 210254721Semaste ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_dict, core_thread_list, old_thread_list, NULL)); 211254721Semaste if (thread_sp) 212254721Semaste new_thread_list.AddThread(thread_sp); 213254721Semaste } 214254721Semaste } 215254721Semaste } 216254721Semaste } 217254721Semaste 218254721Semaste // No new threads added from the thread info array gotten from python, just 219254721Semaste // display the core threads. 220254721Semaste if (new_thread_list.GetSize(false) == 0) 221254721Semaste new_thread_list = core_thread_list; 222254721Semaste 223254721Semaste return new_thread_list.GetSize(false) > 0; 224254721Semaste} 225254721Semaste 226254721SemasteThreadSP 227254721SemasteOperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict, 228254721Semaste ThreadList &core_thread_list, 229254721Semaste ThreadList &old_thread_list, 230254721Semaste bool *did_create_ptr) 231254721Semaste{ 232254721Semaste ThreadSP thread_sp; 233254721Semaste if (thread_dict) 234254721Semaste { 235254721Semaste PythonString tid_pystr("tid"); 236254721Semaste const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID); 237254721Semaste if (tid != LLDB_INVALID_THREAD_ID) 238254721Semaste { 239254721Semaste PythonString core_pystr("core"); 240254721Semaste PythonString name_pystr("name"); 241254721Semaste PythonString queue_pystr("queue"); 242254721Semaste //PythonString state_pystr("state"); 243254721Semaste //PythonString stop_reason_pystr("stop_reason"); 244254721Semaste PythonString reg_data_addr_pystr ("register_data_addr"); 245254721Semaste 246254721Semaste const uint32_t core_number = thread_dict.GetItemForKeyAsInteger (core_pystr, UINT32_MAX); 247254721Semaste const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS); 248254721Semaste const char *name = thread_dict.GetItemForKeyAsString (name_pystr); 249254721Semaste const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr); 250254721Semaste //const char *state = thread_dict.GetItemForKeyAsString (state_pystr); 251254721Semaste //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr); 252254721Semaste 253254721Semaste // See if a thread already exists for "tid" 254254721Semaste thread_sp = old_thread_list.FindThreadByID (tid, false); 255254721Semaste if (thread_sp) 256254721Semaste { 257254721Semaste // A thread already does exist for "tid", make sure it was an operating system 258254721Semaste // plug-in generated thread. 259254721Semaste if (!IsOperatingSystemPluginThread(thread_sp)) 260254721Semaste { 261254721Semaste // We have thread ID overlap between the protocol threads and the 262254721Semaste // operating system threads, clear the thread so we create an 263254721Semaste // operating system thread for this. 264254721Semaste thread_sp.reset(); 265254721Semaste } 266254721Semaste } 267254721Semaste 268254721Semaste if (!thread_sp) 269254721Semaste { 270254721Semaste if (did_create_ptr) 271254721Semaste *did_create_ptr = true; 272254721Semaste thread_sp.reset (new ThreadMemory (*m_process, 273254721Semaste tid, 274254721Semaste name, 275254721Semaste queue, 276254721Semaste reg_data_addr)); 277254721Semaste 278254721Semaste } 279254721Semaste 280254721Semaste if (core_number < core_thread_list.GetSize(false)) 281254721Semaste { 282254721Semaste ThreadSP core_thread_sp (core_thread_list.GetThreadAtIndex(core_number, false)); 283254721Semaste if (core_thread_sp) 284254721Semaste { 285254721Semaste ThreadSP backing_core_thread_sp (core_thread_sp->GetBackingThread()); 286254721Semaste if (backing_core_thread_sp) 287254721Semaste { 288254721Semaste thread_sp->SetBackingThread(backing_core_thread_sp); 289254721Semaste } 290254721Semaste else 291254721Semaste { 292254721Semaste thread_sp->SetBackingThread(core_thread_sp); 293254721Semaste } 294254721Semaste } 295254721Semaste } 296254721Semaste } 297254721Semaste } 298254721Semaste return thread_sp; 299254721Semaste} 300254721Semaste 301254721Semaste 302254721Semaste 303254721Semastevoid 304254721SemasteOperatingSystemPython::ThreadWasSelected (Thread *thread) 305254721Semaste{ 306254721Semaste} 307254721Semaste 308254721SemasteRegisterContextSP 309254721SemasteOperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t reg_data_addr) 310254721Semaste{ 311254721Semaste RegisterContextSP reg_ctx_sp; 312254721Semaste if (!m_interpreter || !m_python_object_sp || !thread) 313254721Semaste return reg_ctx_sp; 314254721Semaste 315254721Semaste if (!IsOperatingSystemPluginThread(thread->shared_from_this())) 316254721Semaste return reg_ctx_sp; 317254721Semaste 318254721Semaste // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 319254721Semaste // content of the process, and we're going to use python, which requires the API lock to do it. 320254721Semaste // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 321254721Semaste Target &target = m_process->GetTarget(); 322254721Semaste Mutex::Locker api_locker (target.GetAPIMutex()); 323254721Semaste 324254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 325254721Semaste 326254721Semaste auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure python objects stays alive 327254721Semaste if (reg_data_addr != LLDB_INVALID_ADDRESS) 328254721Semaste { 329254721Semaste // The registers data is in contiguous memory, just create the register 330254721Semaste // context using the address provided 331254721Semaste if (log) 332254721Semaste log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context", 333254721Semaste thread->GetID(), 334254721Semaste thread->GetProtocolID(), 335254721Semaste reg_data_addr); 336254721Semaste reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr)); 337254721Semaste } 338254721Semaste else 339254721Semaste { 340254721Semaste // No register data address is provided, query the python plug-in to let 341254721Semaste // it make up the data as it sees fit 342254721Semaste if (log) 343254721Semaste log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ") fetching register data from python", 344254721Semaste thread->GetID(), 345254721Semaste thread->GetProtocolID()); 346254721Semaste 347254721Semaste PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID())); 348254721Semaste if (reg_context_data) 349254721Semaste { 350254721Semaste DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(), 351254721Semaste reg_context_data.GetSize())); 352254721Semaste if (data_sp->GetByteSize()) 353254721Semaste { 354254721Semaste RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS); 355254721Semaste if (reg_ctx_memory) 356254721Semaste { 357254721Semaste reg_ctx_sp.reset(reg_ctx_memory); 358254721Semaste reg_ctx_memory->SetAllRegisterData (data_sp); 359254721Semaste } 360254721Semaste } 361254721Semaste } 362254721Semaste } 363254721Semaste // if we still have no register data, fallback on a dummy context to avoid crashing 364254721Semaste if (!reg_ctx_sp) 365254721Semaste { 366254721Semaste if (log) 367254721Semaste log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") forcing a dummy register context", thread->GetID()); 368254721Semaste reg_ctx_sp.reset(new RegisterContextDummy(*thread,0,target.GetArchitecture().GetAddressByteSize())); 369254721Semaste } 370254721Semaste return reg_ctx_sp; 371254721Semaste} 372254721Semaste 373254721SemasteStopInfoSP 374254721SemasteOperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread) 375254721Semaste{ 376254721Semaste // We should have gotten the thread stop info from the dictionary of data for 377254721Semaste // the thread in the initial call to get_thread_info(), this should have been 378254721Semaste // cached so we can return it here 379254721Semaste StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP)); 380254721Semaste return stop_info_sp; 381254721Semaste} 382254721Semaste 383254721Semastelldb::ThreadSP 384254721SemasteOperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context) 385254721Semaste{ 386254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 387254721Semaste 388254721Semaste if (log) 389254721Semaste log->Printf ("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") fetching register data from python", tid, context); 390254721Semaste 391254721Semaste if (m_interpreter && m_python_object_sp) 392254721Semaste { 393254721Semaste // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 394254721Semaste // content of the process, and we're going to use python, which requires the API lock to do it. 395254721Semaste // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 396254721Semaste Target &target = m_process->GetTarget(); 397254721Semaste Mutex::Locker api_locker (target.GetAPIMutex()); 398254721Semaste 399254721Semaste auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive 400254721Semaste PythonDictionary thread_info_dict (m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context)); 401254721Semaste if (thread_info_dict) 402254721Semaste { 403254721Semaste ThreadList core_threads(m_process); 404254721Semaste ThreadList &thread_list = m_process->GetThreadList(); 405254721Semaste bool did_create = false; 406254721Semaste ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, core_threads, thread_list, &did_create)); 407254721Semaste if (did_create) 408254721Semaste thread_list.AddThread(thread_sp); 409254721Semaste return thread_sp; 410254721Semaste } 411254721Semaste } 412254721Semaste return ThreadSP(); 413254721Semaste} 414254721Semaste 415254721Semaste 416254721Semaste 417254721Semaste#endif // #ifndef LLDB_DISABLE_PYTHON 418