diff options
Diffstat (limited to 'lldb/scripts/Python')
-rwxr-xr-x | lldb/scripts/Python/build-swig-Python.sh | 2 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBThread.i | 3 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBThreadPlan.i | 123 | ||||
-rw-r--r-- | lldb/scripts/Python/python-swigsafecast.swig | 14 | ||||
-rw-r--r-- | lldb/scripts/Python/python-wrapper.swig | 112 |
5 files changed, 254 insertions, 0 deletions
diff --git a/lldb/scripts/Python/build-swig-Python.sh b/lldb/scripts/Python/build-swig-Python.sh index 88769c88856..3b610e139e2 100755 --- a/lldb/scripts/Python/build-swig-Python.sh +++ b/lldb/scripts/Python/build-swig-Python.sh @@ -114,6 +114,7 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/lldb.h"\ " ${SRC_ROOT}/include/lldb/API/SBTarget.h"\ " ${SRC_ROOT}/include/lldb/API/SBThread.h"\ " ${SRC_ROOT}/include/lldb/API/SBThreadCollection.h"\ +" ${SRC_ROOT}/include/lldb/API/SBThreadPlan.h"\ " ${SRC_ROOT}/include/lldb/API/SBType.h"\ " ${SRC_ROOT}/include/lldb/API/SBTypeCategory.h"\ " ${SRC_ROOT}/include/lldb/API/SBTypeFilter.h"\ @@ -163,6 +164,7 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBTarget.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBThread.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBThreadCollection.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBThreadPlan.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBType.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBTypeCategory.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBTypeFilter.i"\ diff --git a/lldb/scripts/Python/interface/SBThread.i b/lldb/scripts/Python/interface/SBThread.i index 4d69ddaf229..dac0f9bc4a7 100644 --- a/lldb/scripts/Python/interface/SBThread.i +++ b/lldb/scripts/Python/interface/SBThread.i @@ -213,6 +213,9 @@ public: uint32_t line); SBError + StepUsingScriptedThreadPlan (const char *script_class_name); + + SBError JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line); void diff --git a/lldb/scripts/Python/interface/SBThreadPlan.i b/lldb/scripts/Python/interface/SBThreadPlan.i new file mode 100644 index 00000000000..785855ec5b9 --- /dev/null +++ b/lldb/scripts/Python/interface/SBThreadPlan.i @@ -0,0 +1,123 @@ +//===-- SBThread.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBThreadPlan_h_ +#define LLDB_SBThreadPlan_h_ + +#include "lldb/API/SBDefines.h" + +#include <stdio.h> + +namespace lldb { + +%feature("docstring", +"Represents a plan for the execution control of a given thread. + +See also SBThread and SBFrame." +) SBThread; + +class SBThreadPlan +{ + +friend class lldb_private::ThreadPlan; + +public: + SBThreadPlan (); + + SBThreadPlan (const lldb::SBThreadPlan &threadPlan); + + SBThreadPlan (const lldb::ThreadPlanSP& lldb_object_sp); + + SBThreadPlan (lldb::SBThread &thread, const char *class_name); + + ~SBThreadPlan (); + + bool + IsValid() const; + + void + Clear (); + + lldb::StopReason + GetStopReason(); + + /// Get the number of words associated with the stop reason. + /// See also GetStopReasonDataAtIndex(). + size_t + GetStopReasonDataCount(); + + //-------------------------------------------------------------------------- + /// Get information associated with a stop reason. + /// + /// Breakpoint stop reasons will have data that consists of pairs of + /// breakpoint IDs followed by the breakpoint location IDs (they always come + /// in pairs). + /// + /// Stop Reason Count Data Type + /// ======================== ===== ========================================= + /// eStopReasonNone 0 + /// eStopReasonTrace 0 + /// eStopReasonBreakpoint N duple: {breakpoint id, location id} + /// eStopReasonWatchpoint 1 watchpoint id + /// eStopReasonSignal 1 unix signal number + /// eStopReasonException N exception data + /// eStopReasonExec 0 + /// eStopReasonPlanComplete 0 + //-------------------------------------------------------------------------- + uint64_t + GetStopReasonDataAtIndex(uint32_t idx); + + SBThread + GetThread () const; + + bool + GetDescription (lldb::SBStream &description) const; + + void + SetPlanComplete (bool success); + + bool + IsPlanComplete(); + + bool + IsValid(); + + // This section allows an SBThreadPlan to push another of the common types of plans... + SBThreadPlan + QueueThreadPlanForStepOverRange (SBAddress &start_address, + lldb::addr_t range_size); + + SBThreadPlan + QueueThreadPlanForStepInRange (SBAddress &start_address, + lldb::addr_t range_size); + + SBThreadPlan + QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn = false); + + SBThreadPlan + QueueThreadPlanForRunToAddress (SBAddress address); + + +protected: + friend class SBBreakpoint; + friend class SBBreakpointLocation; + friend class SBFrame; + friend class SBProcess; + friend class SBDebugger; + friend class SBValue; + friend class lldb_private::QueueImpl; + friend class SBQueueItem; + +private: + lldb::ThreadPlanSP m_opaque_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBThreadPlan_h_ diff --git a/lldb/scripts/Python/python-swigsafecast.swig b/lldb/scripts/Python/python-swigsafecast.swig index 0150854d2c6..4813c4f8c4d 100644 --- a/lldb/scripts/Python/python-swigsafecast.swig +++ b/lldb/scripts/Python/python-swigsafecast.swig @@ -45,6 +45,13 @@ SBTypeToSWIGWrapper (unsigned int* c_int) template <> PyObject* +SBTypeToSWIGWrapper (lldb::SBEvent* event_sb) +{ + return SWIG_NewPointerObj((void *) event_sb, SWIGTYPE_p_lldb__SBEvent, 0); +} + +template <> +PyObject* SBTypeToSWIGWrapper (lldb::SBProcess* process_sb) { return SWIG_NewPointerObj((void *) process_sb, SWIGTYPE_p_lldb__SBProcess, 0); @@ -59,6 +66,13 @@ SBTypeToSWIGWrapper (lldb::SBThread* thread_sb) template <> PyObject* +SBTypeToSWIGWrapper (lldb::SBThreadPlan* thread_plan_sb) +{ + return SWIG_NewPointerObj((void *) thread_plan_sb, SWIGTYPE_p_lldb__SBThreadPlan, 0); +} + +template <> +PyObject* SBTypeToSWIGWrapper (lldb::SBTarget* target_sb) { return SWIG_NewPointerObj((void *) target_sb, SWIGTYPE_p_lldb__SBTarget, 0); diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig index 646323a21cd..c3812df8110 100644 --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -419,6 +419,118 @@ LLDBSwigPythonCreateSyntheticProvider Py_RETURN_NONE; } +SWIGEXPORT void* +LLDBSwigPythonCreateScriptedThreadPlan +( + const char *python_class_name, + const char *session_dictionary_name, + const lldb::ThreadPlanSP& thread_plan_sp +) +{ + PyObject* retval = NULL; + + if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) + Py_RETURN_NONE; + + // I do not want the SBThreadPlan to be deallocated when going out of scope because python + // has ownership of it and will manage memory for this object by itself + lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp); + + PyObject *ThreadPlan_PyObj = SBTypeToSWIGWrapper(tp_value); + + if (ThreadPlan_PyObj == NULL) + Py_RETURN_NONE; + + { + PyErr_Cleaner py_err_cleaner(true); + + PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name, session_dictionary_name); + + if (!pfunc) + return retval; + + Py_INCREF(ThreadPlan_PyObj); + + PyObject* session_dict = NULL; + session_dict = FindSessionDictionary(session_dictionary_name); + retval = pfunc(tp_value, session_dict); + + // FIXME: At this point we should check that the class we found supports all the methods + // that we need. + + Py_XINCREF (session_dict); + + Py_XINCREF(retval); + } + + if (retval) + return retval; + else + Py_RETURN_NONE; +} + +SWIGEXPORT bool +LLDBSWIGPythonCallThreadPlan +( + void *implementor, + const char *method_name, + lldb_private::Event *event, + bool &got_error +) +{ + bool ret_val = false; + got_error = false; + + + PyErr_Cleaner py_err_cleaner(false); + + PyCallable pfunc = PyCallable::FindWithMemberFunction((PyObject *) implementor, method_name); + + if (!pfunc) + { + return ret_val; + } + + PyObject* py_return = Py_None; + + if (event != NULL) + { + lldb::SBEvent sb_event(event); + + PyObject *py_obj_event = SBTypeToSWIGWrapper(sb_event); + + py_return = pfunc(py_obj_event); + } + else + { + py_return = pfunc(); + } + + if (PyErr_Occurred()) + { + got_error = true; + printf ("Return value was neither false nor true for call to %s.\n", method_name); + PyErr_Print(); + } + else + { + if (py_return == Py_True) + ret_val = true; + else if (py_return == Py_False) + ret_val = false; + else + { + // Somebody returned the wrong thing... + got_error = true; + printf ("Wrong return value type for call to %s.\n", method_name); + } + } + + Py_XDECREF(py_return); + + return ret_val; +} + // wrapper that calls an optional instance member of an object taking no arguments static PyObject* LLDBSwigPython_CallOptionalMember |