1d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===// 2d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// 3d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// The LLVM Compiler Infrastructure 4d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// 5d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// This file is distributed under the University of Illinois Open Source 6d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// License. See LICENSE.TXT for details. 7d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// 8d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//===----------------------------------------------------------------------===// 9d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea 10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h" 11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea 12d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#ifndef LLDB_DISABLE_PYTHON 13d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 14d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "OperatingSystemPython.h" 15d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// C Includes 16d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// C++ Includes 17d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// Other libraries and framework includes 18d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/ArchSpec.h" 19d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/DataBufferHeap.h" 20155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata#include "lldb/Core/Debugger.h" 21d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/Module.h" 22d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/PluginManager.h" 23d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/RegisterValue.h" 24e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton#include "lldb/Core/StreamString.h" 25d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/ValueObjectVariable.h" 26155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata#include "lldb/Interpreter/CommandInterpreter.h" 27155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata#include "lldb/Interpreter/PythonDataObjects.h" 28d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Symbol/ClangNamespaceDecl.h" 29d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Symbol/ObjectFile.h" 30d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Symbol/VariableList.h" 31d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/Process.h" 32d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/StopInfo.h" 33d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/Target.h" 34d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/ThreadList.h" 35d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/Thread.h" 36d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "Plugins/Process/Utility/DynamicRegisterInfo.h" 3749ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata#include "Plugins/Process/Utility/RegisterContextDummy.h" 38d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "Plugins/Process/Utility/RegisterContextMemory.h" 39d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "Plugins/Process/Utility/ThreadMemory.h" 40d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 41d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonusing namespace lldb; 42d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonusing namespace lldb_private; 43d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 44d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonvoid 45d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::Initialize() 46d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 47d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 48d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton GetPluginDescriptionStatic(), 49d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton CreateInstance); 50d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 51d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 52d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonvoid 53d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::Terminate() 54d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 55d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 56d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 57d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 58d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystem * 59d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::CreateInstance (Process *process, bool force) 60d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 61d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton // Python OperatingSystem plug-ins must be requested by name, so force must be true 622e7f313dc473b036788319690116b324cb44b765Greg Clayton FileSpec python_os_plugin_spec (process->GetPythonOSPluginPath()); 632e7f313dc473b036788319690116b324cb44b765Greg Clayton if (python_os_plugin_spec && python_os_plugin_spec.Exists()) 642e7f313dc473b036788319690116b324cb44b765Greg Clayton { 65102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton std::unique_ptr<OperatingSystemPython> os_ap (new OperatingSystemPython (process, python_os_plugin_spec)); 662e7f313dc473b036788319690116b324cb44b765Greg Clayton if (os_ap.get() && os_ap->IsValid()) 672e7f313dc473b036788319690116b324cb44b765Greg Clayton return os_ap.release(); 682e7f313dc473b036788319690116b324cb44b765Greg Clayton } 69d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return NULL; 70d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 71d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 72d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 730e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString 74d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginNameStatic() 75d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 760e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton static ConstString g_name("python"); 770e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton return g_name; 78d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 79d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 80d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonconst char * 81d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginDescriptionStatic() 82d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 83d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality."; 84d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 85d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 86d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 872e7f313dc473b036788319690116b324cb44b765Greg ClaytonOperatingSystemPython::OperatingSystemPython (lldb_private::Process *process, const FileSpec &python_module_path) : 88d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton OperatingSystem (process), 89d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton m_thread_list_valobj_sp (), 90155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata m_register_info_ap (), 912e7f313dc473b036788319690116b324cb44b765Greg Clayton m_interpreter (NULL), 9252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton m_python_object_sp () 93d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 94155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata if (!process) 95155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata return; 9652ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton TargetSP target_sp = process->CalculateTarget(); 97155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata if (!target_sp) 98155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata return; 99155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 100155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata if (m_interpreter) 101155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata { 1022e7f313dc473b036788319690116b324cb44b765Greg Clayton 1032e7f313dc473b036788319690116b324cb44b765Greg Clayton std::string os_plugin_class_name (python_module_path.GetFilename().AsCString("")); 1042e7f313dc473b036788319690116b324cb44b765Greg Clayton if (!os_plugin_class_name.empty()) 10588b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton { 1062e7f313dc473b036788319690116b324cb44b765Greg Clayton const bool init_session = false; 1072e7f313dc473b036788319690116b324cb44b765Greg Clayton const bool allow_reload = true; 1082e7f313dc473b036788319690116b324cb44b765Greg Clayton char python_module_path_cstr[PATH_MAX]; 1092e7f313dc473b036788319690116b324cb44b765Greg Clayton python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr)); 1102e7f313dc473b036788319690116b324cb44b765Greg Clayton Error error; 1112e7f313dc473b036788319690116b324cb44b765Greg Clayton if (m_interpreter->LoadScriptingModule (python_module_path_cstr, allow_reload, init_session, error)) 1122e7f313dc473b036788319690116b324cb44b765Greg Clayton { 1132e7f313dc473b036788319690116b324cb44b765Greg Clayton // Strip the ".py" extension if there is one 1142e7f313dc473b036788319690116b324cb44b765Greg Clayton size_t py_extension_pos = os_plugin_class_name.rfind(".py"); 1152e7f313dc473b036788319690116b324cb44b765Greg Clayton if (py_extension_pos != std::string::npos) 1162e7f313dc473b036788319690116b324cb44b765Greg Clayton os_plugin_class_name.erase (py_extension_pos); 1172e7f313dc473b036788319690116b324cb44b765Greg Clayton // Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn" 1182e7f313dc473b036788319690116b324cb44b765Greg Clayton os_plugin_class_name += ".OperatingSystemPlugIn"; 11952ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton ScriptInterpreterObjectSP object_sp = m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess()); 12052ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (object_sp && object_sp->GetObject()) 12152ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton m_python_object_sp = object_sp; 1222e7f313dc473b036788319690116b324cb44b765Greg Clayton } 12388b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton } 124155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata } 125d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 126d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 127d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::~OperatingSystemPython () 128d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 129d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 130d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 131d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonDynamicRegisterInfo * 132d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetDynamicRegisterInfo () 133d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 13488b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton if (m_register_info_ap.get() == NULL) 135d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton { 13652ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (!m_interpreter || !m_python_object_sp) 13788b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton return NULL; 138e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS)); 139467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton 140467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton if (log) 1415f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID()); 142467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton 14352ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton PythonDictionary dictionary(m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp)); 14488b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton if (!dictionary) 14588b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton return NULL; 14688b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton 14788b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton m_register_info_ap.reset (new DynamicRegisterInfo (dictionary)); 14888b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton assert (m_register_info_ap->GetNumRegisters() > 0); 14988b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton assert (m_register_info_ap->GetNumRegisterSets() > 0); 150d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton } 151d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return m_register_info_ap.get(); 152d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 153d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 154d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//------------------------------------------------------------------ 155d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// PluginInterface protocol 156d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//------------------------------------------------------------------ 1570e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString 158d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginName() 159d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 160d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return GetPluginNameStatic(); 161d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 162d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 163d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonuint32_t 164d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginVersion() 165d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 166d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return 1; 167d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 168d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 169d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonbool 1704e75e3533bddc7cf7264c6c7f7b4d812d4466e96Andrew KaylorOperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, 1714e75e3533bddc7cf7264c6c7f7b4d812d4466e96Andrew Kaylor ThreadList &core_thread_list, 1724e75e3533bddc7cf7264c6c7f7b4d812d4466e96Andrew Kaylor ThreadList &new_thread_list) 173d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 17452ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (!m_interpreter || !m_python_object_sp) 175b9db9d5bb01963774f28540dbe2c5a11f586ff29Daniel Malea return false; 176467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton 177e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OS)); 178467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton 1794a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 1804a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham // content of the process, and we're going to use python, which requires the API lock to do it. 1814a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 1824a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham Target &target = m_process->GetTarget(); 1834a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham Mutex::Locker api_locker (target.GetAPIMutex()); 1844a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham 185467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton if (log) 1865f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %" PRIu64, m_process->GetID()); 187467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton 1889acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton // The threads that are in "new_thread_list" upon entry are the threads from the 1899acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton // lldb_private::Process subclass, no memory threads will be in this list. 1909acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton 191989c6f74bad9acb7580025c1fc35378799c28e43Enrico Granata auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive 19252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton PythonList threads_list(m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp)); 19352ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (threads_list) 194b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton { 195e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton if (log) 196e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton { 197e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton StreamString strm; 198e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton threads_list.Dump(strm); 199e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton log->Printf("threads_list = %s", strm.GetString().c_str()); 200e15e58facd4814a2be1cc1aa385e9f9125b92993Greg Clayton } 2019acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton uint32_t i; 20252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton const uint32_t num_threads = threads_list.GetSize(); 203863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton if (num_threads > 0) 2049acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton { 205863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton for (i=0; i<num_threads; ++i) 2069acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton { 207863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton PythonDictionary thread_dict(threads_list.GetItemAtIndex(i)); 208863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton if (thread_dict) 2099acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton { 210863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_dict, core_thread_list, old_thread_list, NULL)); 211863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton if (thread_sp) 212863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton new_thread_list.AddThread(thread_sp); 213863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton } 214b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton } 215b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton } 216b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton } 217863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton 21895c25e4134db08078cee4098c7bedd3254a18b23Greg Clayton // No new threads added from the thread info array gotten from python, just 21995c25e4134db08078cee4098c7bedd3254a18b23Greg Clayton // display the core threads. 220863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton if (new_thread_list.GetSize(false) == 0) 22195c25e4134db08078cee4098c7bedd3254a18b23Greg Clayton new_thread_list = core_thread_list; 222863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton 223d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return new_thread_list.GetSize(false) > 0; 224d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 225d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 22652ebc0aab1fdecb634801deceeddd71a14c2148cGreg ClaytonThreadSP 2279acf3699d2bea583b45c762f4cd82b2a4af6131bGreg ClaytonOperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict, 2289acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton ThreadList &core_thread_list, 2299acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton ThreadList &old_thread_list, 2309acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton bool *did_create_ptr) 23152ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton{ 23252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton ThreadSP thread_sp; 23352ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (thread_dict) 23452ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton { 23552ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton PythonString tid_pystr("tid"); 23652ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID); 23736da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton if (tid != LLDB_INVALID_THREAD_ID) 23852ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton { 2399acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton PythonString core_pystr("core"); 24036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton PythonString name_pystr("name"); 24136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton PythonString queue_pystr("queue"); 242a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton //PythonString state_pystr("state"); 243a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton //PythonString stop_reason_pystr("stop_reason"); 24436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton PythonString reg_data_addr_pystr ("register_data_addr"); 24536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton 2469acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton const uint32_t core_number = thread_dict.GetItemForKeyAsInteger (core_pystr, UINT32_MAX); 24736da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS); 24836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton const char *name = thread_dict.GetItemForKeyAsString (name_pystr); 24936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr); 25036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton //const char *state = thread_dict.GetItemForKeyAsString (state_pystr); 25136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr); 25236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton 253a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton // See if a thread already exists for "tid" 2549acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton thread_sp = old_thread_list.FindThreadByID (tid, false); 255a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton if (thread_sp) 256a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton { 257a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton // A thread already does exist for "tid", make sure it was an operating system 258a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton // plug-in generated thread. 259a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton if (!IsOperatingSystemPluginThread(thread_sp)) 260a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton { 261a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton // We have thread ID overlap between the protocol threads and the 262a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton // operating system threads, clear the thread so we create an 263a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton // operating system thread for this. 264a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton thread_sp.reset(); 265a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton } 266a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton } 267a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton 26836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton if (!thread_sp) 26936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton { 27036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton if (did_create_ptr) 27136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton *did_create_ptr = true; 27236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton thread_sp.reset (new ThreadMemory (*m_process, 27336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton tid, 27436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton name, 27536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton queue, 27636da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton reg_data_addr)); 2779acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton 2789acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton } 2799acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton 2809acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton if (core_number < core_thread_list.GetSize(false)) 2819acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton { 282a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton ThreadSP core_thread_sp (core_thread_list.GetThreadAtIndex(core_number, false)); 283a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton if (core_thread_sp) 284a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton { 285a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton ThreadSP backing_core_thread_sp (core_thread_sp->GetBackingThread()); 286a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton if (backing_core_thread_sp) 287a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton { 288a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton thread_sp->SetBackingThread(backing_core_thread_sp); 289a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton } 290a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton else 291a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton { 292a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton thread_sp->SetBackingThread(core_thread_sp); 293a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton } 294a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton } 29536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton } 29652ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton } 29752ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton } 29852ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton return thread_sp; 29952ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton} 30052ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 30152ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 30252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 303d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonvoid 304d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::ThreadWasSelected (Thread *thread) 305d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 306d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 307d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 308d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonRegisterContextSP 30952ebc0aab1fdecb634801deceeddd71a14c2148cGreg ClaytonOperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t reg_data_addr) 310d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 311b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton RegisterContextSP reg_ctx_sp; 31252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (!m_interpreter || !m_python_object_sp || !thread) 313a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton return reg_ctx_sp; 314a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton 315a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton if (!IsOperatingSystemPluginThread(thread->shared_from_this())) 316a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton return reg_ctx_sp; 317467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton 3184a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 3194a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham // content of the process, and we're going to use python, which requires the API lock to do it. 3204a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 3214a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham Target &target = m_process->GetTarget(); 3224a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham Mutex::Locker api_locker (target.GetAPIMutex()); 3234a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham 324952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 325467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton 326989c6f74bad9acb7580025c1fc35378799c28e43Enrico Granata auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure python objects stays alive 32791a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton if (reg_data_addr != LLDB_INVALID_ADDRESS) 328b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton { 32991a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton // The registers data is in contiguous memory, just create the register 33091a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton // context using the address provided 33191a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton if (log) 332a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context", 333a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton thread->GetID(), 334a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton thread->GetProtocolID(), 335a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton reg_data_addr); 33691a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr)); 33791a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton } 33891a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton else 33991a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton { 34091a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton // No register data address is provided, query the python plug-in to let 34191a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton // it make up the data as it sees fit 34291a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton if (log) 343a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", 0x%" PRIx64 ") fetching register data from python", 344a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton thread->GetID(), 345a46013bde54626b68cd2013b108f73a205f4b29aGreg Clayton thread->GetProtocolID()); 34691a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton 34752ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID())); 34891a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton if (reg_context_data) 349b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton { 35091a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(), 35191a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton reg_context_data.GetSize())); 35291a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton if (data_sp->GetByteSize()) 353b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton { 35491a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS); 35591a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton if (reg_ctx_memory) 35691a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton { 35791a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton reg_ctx_sp.reset(reg_ctx_memory); 35891a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton reg_ctx_memory->SetAllRegisterData (data_sp); 35991a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton } 360b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton } 361b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton } 362b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton } 36349ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata // if we still have no register data, fallback on a dummy context to avoid crashing 36449ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata if (!reg_ctx_sp) 36549ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata { 36649ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata if (log) 36749ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") forcing a dummy register context", thread->GetID()); 36849ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata reg_ctx_sp.reset(new RegisterContextDummy(*thread,0,target.GetArchitecture().GetAddressByteSize())); 36949ff4e6008bdeb28de57fa4c931aeb8cc67152d4Enrico Granata } 370d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return reg_ctx_sp; 371d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 372d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 373d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonStopInfoSP 374d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread) 375d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{ 376d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton // We should have gotten the thread stop info from the dictionary of data for 377d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton // the thread in the initial call to get_thread_info(), this should have been 378d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton // cached so we can return it here 379d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP)); 380d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton return stop_info_sp; 381d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton} 382d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 38352ebc0aab1fdecb634801deceeddd71a14c2148cGreg Claytonlldb::ThreadSP 38452ebc0aab1fdecb634801deceeddd71a14c2148cGreg ClaytonOperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context) 38552ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton{ 386952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 38752ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 38852ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (log) 38952ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton log->Printf ("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") fetching register data from python", tid, context); 39052ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 39152ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (m_interpreter && m_python_object_sp) 39252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton { 39352ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton // First thing we have to do is get the API lock, and the run lock. We're going to change the thread 39452ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton // content of the process, and we're going to use python, which requires the API lock to do it. 39552ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us. 39652ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton Target &target = m_process->GetTarget(); 39752ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton Mutex::Locker api_locker (target.GetAPIMutex()); 39852ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 399989c6f74bad9acb7580025c1fc35378799c28e43Enrico Granata auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive 40052ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton PythonDictionary thread_info_dict (m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context)); 40152ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (thread_info_dict) 40252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton { 4039acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton ThreadList core_threads(m_process); 40452ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton ThreadList &thread_list = m_process->GetThreadList(); 40552ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton bool did_create = false; 4069acf3699d2bea583b45c762f4cd82b2a4af6131bGreg Clayton ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, core_threads, thread_list, &did_create)); 40752ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton if (did_create) 40852ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton thread_list.AddThread(thread_sp); 40952ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton return thread_sp; 41052ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton } 41152ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton } 41252ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton return ThreadSP(); 41352ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton} 41452ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 41552ebc0aab1fdecb634801deceeddd71a14c2148cGreg Clayton 416d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton 417d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#endif // #ifndef LLDB_DISABLE_PYTHON 418