diff options
7 files changed, 244 insertions, 13 deletions
diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index e1814eebfa5..76c34e729ac 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -40,6 +40,8 @@ public: const lldb::SBProcess& operator = (const lldb::SBProcess& rhs); + SBProcess (const lldb::ProcessSP &process_sp); + ~SBProcess(); static const char * @@ -217,8 +219,6 @@ protected: friend class SBThread; friend class SBValue; - SBProcess (const lldb::ProcessSP &process_sp); - lldb::ProcessSP GetSP() const; diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index e8f177bc650..a5ba88124d4 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -82,6 +82,10 @@ public: typedef void* (*SWIGPythonCreateSyntheticProvider) (const std::string python_class_name, const char *session_dictionary_name, const lldb::ValueObjectSP& valobj_sp); + + typedef void* (*SWIGPythonCreateOSPlugin) (const std::string python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP& process_sp); typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor); typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx); @@ -195,6 +199,19 @@ public: return lldb::ScriptInterpreterObjectSP(); } + virtual lldb::ScriptInterpreterObjectSP + CreateOSPlugin (std::string class_name, + lldb::ProcessSP process_sp) + { + return lldb::ScriptInterpreterObjectSP(); + } + + virtual lldb::ScriptInterpreterObjectSP + OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object) + { + return lldb::ScriptInterpreterObjectSP(); + } + virtual bool GenerateFunction(const char *signature, const StringList &input) { diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h index eeb73cf0833..7b66c0825ea 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -76,6 +76,13 @@ public: CreateSyntheticScriptedProvider (std::string class_name, lldb::ValueObjectSP valobj); + virtual lldb::ScriptInterpreterObjectSP + CreateOSPlugin (std::string class_name, + lldb::ProcessSP process_sp); + + virtual lldb::ScriptInterpreterObjectSP + OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object); + virtual uint32_t CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor); diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig index cb7c2d6b414..a2c7a48f14d 100644 --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -742,6 +742,103 @@ LLDBSwigPythonCallCommand return retval; } +SWIGEXPORT void* +LLDBSWIGPythonCreateOSPlugin +( + const std::string python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP& process_sp +) +{ + PyObject* retval = NULL; + + if (python_class_name.empty() || !session_dictionary_name) + Py_RETURN_NONE; + + // I do not want the SBValue to be deallocated when going out of scope because python + // has ownership of it and will manage memory for this object by itself + lldb::SBProcess *process_sb = new lldb::SBProcess(process_sp); + + PyObject *SBProc_PyObj = SWIG_NewPointerObj((void *)process_sb, SWIGTYPE_p_lldb__SBProcess, 0); + + if (SBProc_PyObj == NULL) + Py_RETURN_NONE; + + const char* python_function_name = python_class_name.c_str(); + + PyObject *session_dict, *pfunc; + PyObject *pvalue; + + session_dict = FindSessionDictionary (session_dictionary_name); + if (session_dict != NULL) + { + pfunc = ResolvePythonName (python_function_name, session_dict); + if (pfunc != NULL) + { + // Set up the arguments and call the function. + + if (PyCallable_Check (pfunc)) + { + PyObject *argList = Py_BuildValue("S", SBProc_PyObj); + + if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear(); + return retval; + } + + if (argList == NULL) + { + return retval; + } + + Py_INCREF(SBProc_PyObj); + + pvalue = PyObject_CallObject(pfunc, argList); + + Py_DECREF(argList); + + if (pvalue != NULL) + { + if (pvalue != Py_None) + retval = pvalue; + else + { + retval = Py_None; + Py_INCREF(retval); + } + } + else if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear(); + } + Py_INCREF (session_dict); + } + else if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + } + else if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + } + else if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear (); + } + if (retval) + return retval; + else + Py_RETURN_NONE; +} + SWIGEXPORT bool LLDBSwigPythonCallModuleInit ( diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index 79089c56648..94b27bb8297 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -55,6 +55,7 @@ static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = NULL; static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = NULL; static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = NULL; +static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = NULL; // these are the Pythonic implementations of the required callbacks // these are scripting-language specific, which is why they belong here @@ -121,6 +122,13 @@ extern "C" bool LLDBSwigPythonCallModuleInit lldb::DebuggerSP& debugger ); +extern "C" void* LLDBSWIGPythonCreateOSPlugin +( + const std::string python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP& process_sp +); + static int _check_and_flush (FILE *stream) { @@ -1697,6 +1705,85 @@ ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::st } lldb::ScriptInterpreterObjectSP +ScriptInterpreterPython::CreateOSPlugin (std::string class_name, + lldb::ProcessSP process_sp) +{ + if (class_name.empty()) + return lldb::ScriptInterpreterObjectSP(); + + if (!process_sp) + return lldb::ScriptInterpreterObjectSP(); + + void* ret_val; + + { + Locker py_lock(this); + ret_val = g_swig_create_os_plugin (class_name, + m_dictionary_name.c_str(), + process_sp); + } + + return MakeScriptObject(ret_val); +} + +lldb::ScriptInterpreterObjectSP +ScriptInterpreterPython::OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object) +{ + static char callee_name[] = "get_register_info"; + + if (!object) + return lldb::ScriptInterpreterObjectSP(); + + PyObject* implementor = (PyObject*)object->GetObject(); + + if (implementor == NULL || implementor == Py_None) + return lldb::ScriptInterpreterObjectSP(); + + PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name); + + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + if (pmeth == NULL || pmeth == Py_None) + { + Py_XDECREF(pmeth); + return lldb::ScriptInterpreterObjectSP(); + } + + if (PyCallable_Check(pmeth) == 0) + { + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + Py_XDECREF(pmeth); + return lldb::ScriptInterpreterObjectSP(); + } + + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + Py_XDECREF(pmeth); + + // right now we know this function exists and is callable.. + PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL); + + // if it fails, print the error but otherwise go on + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + + return MakeScriptObject(py_return); +} + +lldb::ScriptInterpreterObjectSP ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name, lldb::ValueObjectSP valobj) { @@ -2366,6 +2453,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_ini g_swig_update_provider = LLDBSwigPython_UpdateSynthProviderInstance; g_swig_call_command = LLDBSwigPythonCallCommand; g_swig_call_module_init = LLDBSwigPythonCallModuleInit; + g_swig_create_os_plugin = LLDBSWIGPythonCreateOSPlugin; } void diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index 761da1fa884..ad86f8c7624 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -16,10 +16,13 @@ #include "lldb/Core/ArchSpec.h" #include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/VariableList.h" @@ -53,7 +56,7 @@ OperatingSystem * OperatingSystemPython::CreateInstance (Process *process, bool force) { // Python OperatingSystem plug-ins must be requested by name, so force must be true - if (force) + //if (force) return new OperatingSystemPython (process); return NULL; } @@ -75,14 +78,23 @@ OperatingSystemPython::GetPluginDescriptionStatic() OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) : OperatingSystem (process), m_thread_list_valobj_sp (), - m_register_info_ap () + m_register_info_ap (), + m_interpreter(NULL), + m_python_object(NULL) { - // TODO: python: create a new python class the implements the necessary - // python class that will cache a SBProcess that contains the "process" - // argument above and implements: - // dict get_thread_info() - // dict get_register_info() - // Bytes get_register_context_data(SBThread thread) + if (!process) + return; + lldb::TargetSP target_sp = process->CalculateTarget(); + if (!target_sp) + return; + m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); + if (m_interpreter) + { + // TODO: hardcoded is not good + auto object_sp = m_interpreter->CreateOSPlugin("operating_system.PlugIn",process->CalculateProcess()); + if (object_sp) + m_python_object = object_sp->GetObject(); + } } OperatingSystemPython::~OperatingSystemPython () @@ -92,10 +104,17 @@ OperatingSystemPython::~OperatingSystemPython () DynamicRegisterInfo * OperatingSystemPython::GetDynamicRegisterInfo () { - // TODO: python: call get_register_info() on the python object that - // represents our instance of the OperatingSystem plug-in + if (!m_interpreter || !m_python_object) + return NULL; + auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object)); + if (!object_sp) + return NULL; + PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject()); + PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject(); + if(!dictionary) + return NULL; - // Example code below shows creating a new DynamicRegisterInfo() + // TODO: iterate over the dictionary if (m_register_info_ap.get() == NULL && m_thread_list_valobj_sp) { // static ConstString g_gpr_member_name("gpr"); diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h index 850ec648bff..5711426ca8f 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -14,6 +14,7 @@ // C Includes // C++ Includes // Other libraries and framework includes +#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/OperatingSystem.h" class DynamicRegisterInfo; @@ -82,6 +83,8 @@ protected: lldb::ValueObjectSP m_thread_list_valobj_sp; std::auto_ptr<DynamicRegisterInfo> m_register_info_ap; + lldb_private::ScriptInterpreter *m_interpreter; + void* m_python_object; }; |

