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)); 193269024Semaste 194269024Semaste const uint32_t num_cores = core_thread_list.GetSize(false); 195269024Semaste 196269024Semaste // Make a map so we can keep track of which cores were used from the 197269024Semaste // core_thread list. Any real threads/cores that weren't used should 198269024Semaste // later be put back into the "new_thread_list". 199269024Semaste std::vector<bool> core_used_map(num_cores, false); 200254721Semaste if (threads_list) 201254721Semaste { 202254721Semaste if (log) 203254721Semaste { 204254721Semaste StreamString strm; 205254721Semaste threads_list.Dump(strm); 206254721Semaste log->Printf("threads_list = %s", strm.GetString().c_str()); 207254721Semaste } 208254721Semaste uint32_t i; 209254721Semaste const uint32_t num_threads = threads_list.GetSize(); 210254721Semaste if (num_threads > 0) 211254721Semaste { 212254721Semaste for (i=0; i<num_threads; ++i) 213254721Semaste { 214254721Semaste PythonDictionary thread_dict(threads_list.GetItemAtIndex(i)); 215254721Semaste if (thread_dict) 216254721Semaste { 217269024Semaste ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_dict, core_thread_list, old_thread_list, core_used_map, NULL)); 218254721Semaste if (thread_sp) 219254721Semaste new_thread_list.AddThread(thread_sp); 220254721Semaste } 221254721Semaste } 222254721Semaste } 223254721Semaste } 224254721Semaste 225269024Semaste // Any real core threads that didn't end up backing a memory thread should 226269024Semaste // still be in the main thread list, and they should be inserted at the beginning 227269024Semaste // of the list 228269024Semaste uint32_t insert_idx = 0; 229269024Semaste for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx) 230269024Semaste { 231269024Semaste if (core_used_map[core_idx] == false) 232269024Semaste { 233269024Semaste new_thread_list.InsertThread (core_thread_list.GetThreadAtIndex(core_idx, false), insert_idx); 234269024Semaste ++insert_idx; 235269024Semaste } 236269024Semaste } 237269024Semaste 238254721Semaste return new_thread_list.GetSize(false) > 0; 239254721Semaste} 240254721Semaste 241254721SemasteThreadSP 242254721SemasteOperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict, 243254721Semaste ThreadList &core_thread_list, 244254721Semaste ThreadList &old_thread_list, 245269024Semaste std::vector<bool> &core_used_map, 246254721Semaste bool *did_create_ptr) 247254721Semaste{ 248254721Semaste ThreadSP thread_sp; 249254721Semaste if (thread_dict) 250254721Semaste { 251254721Semaste PythonString tid_pystr("tid"); 252254721Semaste const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID); 253254721Semaste if (tid != LLDB_INVALID_THREAD_ID) 254254721Semaste { 255254721Semaste PythonString core_pystr("core"); 256254721Semaste PythonString name_pystr("name"); 257254721Semaste PythonString queue_pystr("queue"); 258254721Semaste //PythonString state_pystr("state"); 259254721Semaste //PythonString stop_reason_pystr("stop_reason"); 260254721Semaste PythonString reg_data_addr_pystr ("register_data_addr"); 261254721Semaste 262254721Semaste const uint32_t core_number = thread_dict.GetItemForKeyAsInteger (core_pystr, UINT32_MAX); 263254721Semaste const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS); 264254721Semaste const char *name = thread_dict.GetItemForKeyAsString (name_pystr); 265254721Semaste const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr); 266254721Semaste //const char *state = thread_dict.GetItemForKeyAsString (state_pystr); 267254721Semaste //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr); 268254721Semaste 269254721Semaste // See if a thread already exists for "tid" 270254721Semaste thread_sp = old_thread_list.FindThreadByID (tid, false); 271254721Semaste if (thread_sp) 272254721Semaste { 273254721Semaste // A thread already does exist for "tid", make sure it was an operating system 274254721Semaste // plug-in generated thread. 275254721Semaste if (!IsOperatingSystemPluginThread(thread_sp)) 276254721Semaste { 277254721Semaste // We have thread ID overlap between the protocol threads and the 278254721Semaste // operating system threads, clear the thread so we create an 279254721Semaste // operating system thread for this. 280254721Semaste thread_sp.reset(); 281254721Semaste } 282254721Semaste } 283254721Semaste 284254721Semaste if (!thread_sp) 285254721Semaste { 286254721Semaste if (did_create_ptr) 287254721Semaste *did_create_ptr = true; 288254721Semaste thread_sp.reset (new ThreadMemory (*m_process, 289254721Semaste tid, 290254721Semaste name, 291254721Semaste queue, 292254721Semaste reg_data_addr)); 293254721Semaste 294254721Semaste } 295254721Semaste 296254721Semaste if (core_number < core_thread_list.GetSize(false)) 297254721Semaste { 298254721Semaste ThreadSP core_thread_sp (core_thread_list.GetThreadAtIndex(core_number, false)); 299254721Semaste if (core_thread_sp) 300254721Semaste { 301269024Semaste // Keep track of which cores were set as the backing thread for memory threads... 302269024Semaste if (core_number < core_used_map.size()) 303269024Semaste core_used_map[core_number] = true; 304269024Semaste 305254721Semaste ThreadSP backing_core_thread_sp (core_thread_sp->GetBackingThread()); 306254721Semaste if (backing_core_thread_sp) 307254721Semaste { 308254721Semaste thread_sp->SetBackingThread(backing_core_thread_sp); 309254721Semaste } 310254721Semaste else 311254721Semaste { 312254721Semaste thread_sp->SetBackingThread(core_thread_sp); 313254721Semaste } 314254721Semaste } 315254721Semaste } 316254721Semaste } 317254721Semaste } 318254721Semaste return thread_sp; 319254721Semaste} 320254721Semaste 321254721Semaste 322254721Semaste 323254721Semastevoid 324254721SemasteOperatingSystemPython::ThreadWasSelected (Thread *thread) 325254721Semaste{ 326254721Semaste} 327254721Semaste 328254721SemasteRegisterContextSP 329254721SemasteOperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t reg_data_addr) 330254721Semaste{ 331254721Semaste RegisterContextSP reg_ctx_sp; 332254721Semaste if (!m_interpreter || !m_python_object_sp || !thread) 333254721Semaste return reg_ctx_sp; 334254721Semaste 335254721Semaste if (!IsOperatingSystemPluginThread(thread->shared_from_this())) 336254721Semaste return reg_ctx_sp; 337254721Semaste 338254721Semaste // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 339254721Semaste // content of the process, and we're going to use python, which requires the API lock to do it. 340254721Semaste // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 341254721Semaste Target &target = m_process->GetTarget(); 342254721Semaste Mutex::Locker api_locker (target.GetAPIMutex()); 343254721Semaste 344254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 345254721Semaste 346254721Semaste auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure python objects stays alive 347254721Semaste if (reg_data_addr != LLDB_INVALID_ADDRESS) 348254721Semaste { 349254721Semaste // The registers data is in contiguous memory, just create the register 350254721Semaste // context using the address provided 351254721Semaste if (log) 352254721Semaste log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context", 353254721Semaste thread->GetID(), 354254721Semaste thread->GetProtocolID(), 355254721Semaste reg_data_addr); 356254721Semaste reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr)); 357254721Semaste } 358254721Semaste else 359254721Semaste { 360254721Semaste // No register data address is provided, query the python plug-in to let 361254721Semaste // it make up the data as it sees fit 362254721Semaste if (log) 363254721Semaste log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ") fetching register data from python", 364254721Semaste thread->GetID(), 365254721Semaste thread->GetProtocolID()); 366254721Semaste 367254721Semaste PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID())); 368254721Semaste if (reg_context_data) 369254721Semaste { 370254721Semaste DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(), 371254721Semaste reg_context_data.GetSize())); 372254721Semaste if (data_sp->GetByteSize()) 373254721Semaste { 374254721Semaste RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS); 375254721Semaste if (reg_ctx_memory) 376254721Semaste { 377254721Semaste reg_ctx_sp.reset(reg_ctx_memory); 378254721Semaste reg_ctx_memory->SetAllRegisterData (data_sp); 379254721Semaste } 380254721Semaste } 381254721Semaste } 382254721Semaste } 383254721Semaste // if we still have no register data, fallback on a dummy context to avoid crashing 384254721Semaste if (!reg_ctx_sp) 385254721Semaste { 386254721Semaste if (log) 387254721Semaste log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") forcing a dummy register context", thread->GetID()); 388254721Semaste reg_ctx_sp.reset(new RegisterContextDummy(*thread,0,target.GetArchitecture().GetAddressByteSize())); 389254721Semaste } 390254721Semaste return reg_ctx_sp; 391254721Semaste} 392254721Semaste 393254721SemasteStopInfoSP 394254721SemasteOperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread) 395254721Semaste{ 396254721Semaste // We should have gotten the thread stop info from the dictionary of data for 397254721Semaste // the thread in the initial call to get_thread_info(), this should have been 398254721Semaste // cached so we can return it here 399254721Semaste StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP)); 400254721Semaste return stop_info_sp; 401254721Semaste} 402254721Semaste 403254721Semastelldb::ThreadSP 404254721SemasteOperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context) 405254721Semaste{ 406254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 407254721Semaste 408254721Semaste if (log) 409254721Semaste log->Printf ("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") fetching register data from python", tid, context); 410254721Semaste 411254721Semaste if (m_interpreter && m_python_object_sp) 412254721Semaste { 413254721Semaste // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 414254721Semaste // content of the process, and we're going to use python, which requires the API lock to do it. 415254721Semaste // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 416254721Semaste Target &target = m_process->GetTarget(); 417254721Semaste Mutex::Locker api_locker (target.GetAPIMutex()); 418254721Semaste 419254721Semaste auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive 420254721Semaste PythonDictionary thread_info_dict (m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context)); 421269024Semaste std::vector<bool> core_used_map; 422254721Semaste if (thread_info_dict) 423254721Semaste { 424254721Semaste ThreadList core_threads(m_process); 425254721Semaste ThreadList &thread_list = m_process->GetThreadList(); 426254721Semaste bool did_create = false; 427269024Semaste ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, core_threads, thread_list, core_used_map, &did_create)); 428254721Semaste if (did_create) 429254721Semaste thread_list.AddThread(thread_sp); 430254721Semaste return thread_sp; 431254721Semaste } 432254721Semaste } 433254721Semaste return ThreadSP(); 434254721Semaste} 435254721Semaste 436254721Semaste 437254721Semaste 438254721Semaste#endif // #ifndef LLDB_DISABLE_PYTHON 439