diff options
author | Jim Ingham <jingham@apple.com> | 2014-09-29 23:17:18 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2014-09-29 23:17:18 +0000 |
commit | 2bdbfd50d2c9a80c6132a3f83d1c097b0b0c6ca5 (patch) | |
tree | 08490741e71cb48256f74dc8e42944b6c427d79f /lldb/scripts/Python | |
parent | 8b6fefb3a3b56597e3b1f92539f876c4555e7e2e (diff) | |
download | bcm5719-llvm-2bdbfd50d2c9a80c6132a3f83d1c097b0b0c6ca5.tar.gz bcm5719-llvm-2bdbfd50d2c9a80c6132a3f83d1c097b0b0c6ca5.zip |
This checkin is the first step in making the lldb thread stepping mechanism more accessible from
the user level. It adds the ability to invent new stepping modes implemented by python classes,
and to view the current thread plan stack and to some extent alter it.
I haven't gotten to documentation or tests yet. But this should not cause any behavior changes
if you don't use it, so its safe to check it in now and work on it incrementally.
llvm-svn: 218642
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 |