2013-09-25 18:37:32 +08:00
|
|
|
%header %{
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
PyObject *
|
|
|
|
SBTypeToSWIGWrapper (T* item);
|
|
|
|
|
|
|
|
class PyErr_Cleaner
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PyErr_Cleaner(bool print=false) :
|
|
|
|
m_print(print)
|
|
|
|
{
|
|
|
|
}
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
~PyErr_Cleaner()
|
|
|
|
{
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
{
|
2014-02-19 04:00:20 +08:00
|
|
|
if(m_print && !PyErr_ExceptionMatches(PyExc_SystemExit))
|
2013-09-25 18:37:32 +08:00
|
|
|
PyErr_Print();
|
|
|
|
PyErr_Clear();
|
|
|
|
}
|
|
|
|
}
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
private:
|
|
|
|
bool m_print;
|
|
|
|
};
|
|
|
|
|
|
|
|
%}
|
|
|
|
|
|
|
|
%wrapper %{
|
|
|
|
|
|
|
|
// resolve a dotted Python name in the form
|
|
|
|
// foo.bar.baz.Foobar to an actual Python object
|
|
|
|
// if pmodule is NULL, the __main__ module will be used
|
|
|
|
// as the starting point for the search
|
|
|
|
|
|
|
|
|
|
|
|
// This function is called by lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...)
|
|
|
|
// and is used when a script command is attached to a breakpoint for execution.
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
2015-03-14 16:06:56 +08:00
|
|
|
LLDBSwigPythonBreakpointCallbackFunction
|
2013-09-25 18:37:32 +08:00
|
|
|
(
|
|
|
|
const char *python_function_name,
|
|
|
|
const char *session_dictionary_name,
|
2015-03-14 16:06:56 +08:00
|
|
|
const lldb::StackFrameSP& frame_sp,
|
2013-09-25 18:37:32 +08:00
|
|
|
const lldb::BreakpointLocationSP& bp_loc_sp
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
lldb::SBFrame sb_frame (frame_sp);
|
|
|
|
lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
bool stop_at_breakpoint = true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-11-13 00:23:16 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
2015-11-12 05:07:29 +08:00
|
|
|
return stop_at_breakpoint;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame));
|
|
|
|
PythonObject bp_loc_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_bp_loc));
|
|
|
|
PythonObject result = pfunc(frame_arg, bp_loc_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (result.get() == Py_False)
|
2015-11-12 05:07:29 +08:00
|
|
|
stop_at_breakpoint = false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
return stop_at_breakpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This function is called by lldb_private::ScriptInterpreterPython::WatchpointCallbackFunction(...)
|
|
|
|
// and is used when a script command is attached to a watchpoint for execution.
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
2015-03-14 16:06:56 +08:00
|
|
|
LLDBSwigPythonWatchpointCallbackFunction
|
2013-09-25 18:37:32 +08:00
|
|
|
(
|
|
|
|
const char *python_function_name,
|
|
|
|
const char *session_dictionary_name,
|
2015-03-14 16:06:56 +08:00
|
|
|
const lldb::StackFrameSP& frame_sp,
|
2013-09-25 18:37:32 +08:00
|
|
|
const lldb::WatchpointSP& wp_sp
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
lldb::SBFrame sb_frame (frame_sp);
|
|
|
|
lldb::SBWatchpoint sb_wp(wp_sp);
|
|
|
|
|
|
|
|
bool stop_at_watchpoint = true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
2015-11-12 05:07:29 +08:00
|
|
|
return stop_at_watchpoint;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame));
|
|
|
|
PythonObject wp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_wp));
|
|
|
|
PythonObject result = pfunc(frame_arg, wp_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (result.get() == Py_False)
|
2015-11-12 05:07:29 +08:00
|
|
|
stop_at_watchpoint = false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
return stop_at_watchpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PyObjectToString (PyObject* object,
|
|
|
|
std::string& retval)
|
|
|
|
{
|
|
|
|
retval.clear();
|
|
|
|
bool was_ok = false;
|
|
|
|
if (object != NULL && object != Py_None)
|
|
|
|
{
|
|
|
|
if (PyString_Check(object))
|
|
|
|
{
|
|
|
|
retval.assign(PyString_AsString(object));
|
|
|
|
was_ok = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PyObject* value_as_string = PyObject_Str(object);
|
|
|
|
if (value_as_string && value_as_string != Py_None && PyString_Check(value_as_string))
|
|
|
|
{
|
|
|
|
retval.assign(PyString_AsString(value_as_string));
|
|
|
|
was_ok = true;
|
|
|
|
}
|
|
|
|
Py_XDECREF(value_as_string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return was_ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
2015-03-14 16:06:56 +08:00
|
|
|
LLDBSwigPythonCallTypeScript
|
2013-09-25 18:37:32 +08:00
|
|
|
(
|
|
|
|
const char *python_function_name,
|
|
|
|
const void *session_dictionary,
|
|
|
|
const lldb::ValueObjectSP& valobj_sp,
|
|
|
|
void** pyfunct_wrapper,
|
2014-11-22 08:02:47 +08:00
|
|
|
const lldb::TypeSummaryOptionsSP& options_sp,
|
2013-09-25 18:37:32 +08:00
|
|
|
std::string& retval
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 03:42:35 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
lldb::SBValue sb_value (valobj_sp);
|
2014-11-22 08:02:47 +08:00
|
|
|
lldb::SBTypeSummaryOptions sb_options(options_sp.get());
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
retval.clear();
|
|
|
|
|
|
|
|
if (!python_function_name || !session_dictionary)
|
|
|
|
return false;
|
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PyObject *pfunc_impl = nullptr;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
if (pyfunct_wrapper && *pyfunct_wrapper && PyFunction_Check (*pyfunct_wrapper))
|
|
|
|
{
|
|
|
|
pfunc_impl = (PyObject*)(*pyfunct_wrapper);
|
|
|
|
if (pfunc_impl->ob_refcnt == 1)
|
|
|
|
{
|
|
|
|
Py_XDECREF(pfunc_impl);
|
|
|
|
pfunc_impl = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-12 03:42:35 +08:00
|
|
|
PyObject *py_dict = (PyObject*)session_dictionary;
|
|
|
|
if (!PythonDictionary::Check(py_dict))
|
|
|
|
return true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 03:42:35 +08:00
|
|
|
PythonDictionary dict(PyRefType::Borrowed, py_dict);
|
2013-12-26 15:21:41 +08:00
|
|
|
|
2015-11-12 03:42:35 +08:00
|
|
|
PyErr_Cleaner pyerr_cleanup(true); // show Python errors
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonCallable pfunc(PyRefType::Borrowed, pfunc_impl);
|
|
|
|
|
|
|
|
if (!pfunc.IsAllocated())
|
2015-11-12 03:42:35 +08:00
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
|
|
|
if (!pfunc.IsAllocated())
|
2013-09-25 18:37:32 +08:00
|
|
|
return false;
|
2015-11-13 00:23:16 +08:00
|
|
|
|
|
|
|
if (pyfunct_wrapper)
|
2015-11-12 03:42:35 +08:00
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
*pyfunct_wrapper = pfunc.get();
|
|
|
|
Py_XINCREF(pfunc.get());
|
2015-11-12 03:42:35 +08:00
|
|
|
}
|
|
|
|
}
|
2014-11-22 08:02:47 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result;
|
|
|
|
auto argc = pfunc.GetNumArguments();
|
2015-11-12 03:42:35 +08:00
|
|
|
// if the third argument is supported, or varargs are allowed
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject value_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value));
|
|
|
|
PythonObject options_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_options));
|
|
|
|
if (argc.count == 3 || argc.has_varargs)
|
|
|
|
result = pfunc(value_arg,dict,options_arg);
|
2015-11-12 03:42:35 +08:00
|
|
|
else
|
2015-11-13 00:23:16 +08:00
|
|
|
result = pfunc(value_arg,dict);
|
2015-11-12 03:42:35 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PyObjectToString(result.get(), retval);
|
2015-11-12 03:42:35 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT void*
|
2015-03-14 16:06:56 +08:00
|
|
|
LLDBSwigPythonCreateSyntheticProvider
|
2013-09-25 18:37:32 +08:00
|
|
|
(
|
|
|
|
const char *python_class_name,
|
|
|
|
const char *session_dictionary_name,
|
|
|
|
const lldb::ValueObjectSP& valobj_sp
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
|
|
|
|
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name,dict);
|
|
|
|
|
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
// 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::SBValue *sb_value = new lldb::SBValue(valobj_sp);
|
|
|
|
sb_value->SetPreferSyntheticValue(false);
|
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject val_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value));
|
|
|
|
if (!val_arg.IsAllocated())
|
2013-09-25 18:37:32 +08:00
|
|
|
Py_RETURN_NONE;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result = pfunc(val_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (result.IsAllocated())
|
|
|
|
return result.release();
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
Py_RETURN_NONE;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
2015-03-13 10:20:41 +08:00
|
|
|
SWIGEXPORT void*
|
|
|
|
LLDBSwigPythonCreateCommandObject
|
|
|
|
(
|
|
|
|
const char *python_class_name,
|
|
|
|
const char *session_dictionary_name,
|
|
|
|
const lldb::DebuggerSP debugger_sp
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2015-03-13 10:20:41 +08:00
|
|
|
|
|
|
|
if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-11-13 00:23:16 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return nullptr;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
lldb::SBDebugger debugger_sb(debugger_sp);
|
|
|
|
PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
|
|
|
|
PythonObject result = pfunc(debugger_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (result.IsAllocated())
|
|
|
|
return result.release();
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
Py_RETURN_NONE;
|
2015-03-13 10:20:41 +08:00
|
|
|
}
|
|
|
|
|
2014-09-30 07:17:18 +08:00
|
|
|
SWIGEXPORT void*
|
|
|
|
LLDBSwigPythonCreateScriptedThreadPlan
|
|
|
|
(
|
|
|
|
const char *python_class_name,
|
|
|
|
const char *session_dictionary_name,
|
|
|
|
const lldb::ThreadPlanSP& thread_plan_sp
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2014-09-30 07:17:18 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return nullptr;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(tp_value));
|
2014-09-30 07:17:18 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!tp_arg.IsAllocated())
|
|
|
|
Py_RETURN_NONE;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result = pfunc(tp_arg, dict);
|
2015-11-12 05:07:29 +08:00
|
|
|
// FIXME: At this point we should check that the class we found supports all the methods
|
|
|
|
// that we need.
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (result.IsAllocated())
|
|
|
|
return result.release();
|
|
|
|
Py_RETURN_NONE;
|
2014-09-30 07:17:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSWIGPythonCallThreadPlan
|
|
|
|
(
|
|
|
|
void *implementor,
|
|
|
|
const char *method_name,
|
|
|
|
lldb_private::Event *event,
|
|
|
|
bool &got_error
|
|
|
|
)
|
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
using namespace lldb_private;
|
2014-09-30 07:17:18 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
got_error = false;
|
2014-09-30 07:17:18 +08:00
|
|
|
|
|
|
|
PyErr_Cleaner py_err_cleaner(false);
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
|
|
|
|
auto pfunc = self.ResolveName<PythonCallable>(method_name);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return false;
|
2014-09-30 07:17:18 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result;
|
|
|
|
if (event != nullptr)
|
2014-09-30 07:17:18 +08:00
|
|
|
{
|
|
|
|
lldb::SBEvent sb_event(event);
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event));
|
|
|
|
result = pfunc(event_arg);
|
2014-09-30 07:17:18 +08:00
|
|
|
}
|
|
|
|
else
|
2015-11-13 00:23:16 +08:00
|
|
|
result = pfunc();
|
2014-09-30 07:17:18 +08:00
|
|
|
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
{
|
|
|
|
got_error = true;
|
|
|
|
printf ("Return value was neither false nor true for call to %s.\n", method_name);
|
|
|
|
PyErr_Print();
|
2015-11-13 00:23:16 +08:00
|
|
|
return false;
|
2014-09-30 07:17:18 +08:00
|
|
|
}
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (result.get() == Py_True)
|
|
|
|
return true;
|
|
|
|
else if (result.get() == Py_False)
|
|
|
|
return false;
|
2014-09-30 07:17:18 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
// Somebody returned the wrong thing...
|
|
|
|
got_error = true;
|
|
|
|
printf ("Wrong return value type for call to %s.\n", method_name);
|
|
|
|
return false;
|
2014-09-30 07:17:18 +08:00
|
|
|
}
|
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
// wrapper that calls an optional instance member of an object taking no arguments
|
|
|
|
static PyObject*
|
|
|
|
LLDBSwigPython_CallOptionalMember
|
|
|
|
(
|
2015-11-13 00:23:16 +08:00
|
|
|
PyObject* implementor,
|
2013-09-25 18:37:32 +08:00
|
|
|
char* callee_name,
|
|
|
|
PyObject* ret_if_not_found = Py_None,
|
|
|
|
bool* was_found = NULL
|
|
|
|
)
|
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
using namespace lldb_private;
|
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(false);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
|
|
|
|
auto pfunc = self.ResolveName<PythonCallable>(callee_name);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
2013-09-25 18:37:32 +08:00
|
|
|
{
|
|
|
|
if (was_found)
|
|
|
|
*was_found = false;
|
|
|
|
Py_XINCREF(ret_if_not_found);
|
|
|
|
return ret_if_not_found;
|
|
|
|
}
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
if (was_found)
|
|
|
|
*was_found = true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result = pfunc();
|
|
|
|
return result.release();
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
2015-03-17 03:01:33 +08:00
|
|
|
SWIGEXPORT size_t
|
2013-09-25 18:37:32 +08:00
|
|
|
LLDBSwigPython_CalculateNumChildren
|
|
|
|
(
|
2015-10-22 03:28:08 +08:00
|
|
|
PyObject *implementor,
|
|
|
|
uint32_t max
|
2013-09-25 18:37:32 +08:00
|
|
|
)
|
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject self(PyRefType::Borrowed, implementor);
|
|
|
|
auto pfunc = self.ResolveName<PythonCallable>("num_children");
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return 0;
|
2015-10-22 03:28:08 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result;
|
2015-10-22 03:28:08 +08:00
|
|
|
auto argc = pfunc.GetNumArguments();
|
2015-11-13 00:23:16 +08:00
|
|
|
if (argc.count == 1)
|
|
|
|
result = pfunc();
|
|
|
|
else if (argc.count == 2)
|
|
|
|
result = pfunc(PythonInteger(max));
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!result.IsAllocated())
|
|
|
|
return 0;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonInteger int_result = result.AsType<PythonInteger>();
|
|
|
|
if (!int_result.IsAllocated())
|
|
|
|
return 0;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
size_t ret_val = int_result.GetInteger();
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
if (PyErr_Occurred())
|
|
|
|
{
|
|
|
|
PyErr_Print();
|
|
|
|
PyErr_Clear();
|
|
|
|
}
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (argc.count == 1)
|
2015-11-13 01:01:48 +08:00
|
|
|
ret_val = std::min(ret_val, static_cast<size_t>(max));
|
2015-10-22 03:28:08 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
return ret_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT PyObject*
|
|
|
|
LLDBSwigPython_GetChildAtIndex
|
|
|
|
(
|
|
|
|
PyObject *implementor,
|
|
|
|
uint32_t idx
|
|
|
|
)
|
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject self(PyRefType::Borrowed, implementor);
|
|
|
|
auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return nullptr;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result = pfunc(PythonInteger(idx));
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!result.IsAllocated())
|
|
|
|
return nullptr;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
lldb::SBValue* sbvalue_ptr = nullptr;
|
|
|
|
if (SWIG_ConvertPtr(result.get(), (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
|
|
|
|
return nullptr;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (sbvalue_ptr == nullptr)
|
|
|
|
return nullptr;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
return result.release();
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT int
|
|
|
|
LLDBSwigPython_GetIndexOfChildWithName
|
|
|
|
(
|
|
|
|
PyObject *implementor,
|
|
|
|
const char* child_name
|
|
|
|
)
|
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject self(PyRefType::Borrowed, implementor);
|
|
|
|
auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
2013-09-25 18:37:32 +08:00
|
|
|
return UINT32_MAX;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject result = pfunc(PythonString(child_name));
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!result.IsAllocated())
|
2013-09-25 18:37:32 +08:00
|
|
|
return UINT32_MAX;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonInteger int_result = result.AsType<PythonInteger>();
|
|
|
|
if (!int_result.IsAllocated())
|
|
|
|
return UINT32_MAX;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
int64_t retval = int_result.GetInteger();
|
2013-09-25 18:37:32 +08:00
|
|
|
if (retval >= 0)
|
|
|
|
return (uint32_t)retval;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSwigPython_UpdateSynthProviderInstance
|
|
|
|
(
|
|
|
|
PyObject *implementor
|
|
|
|
)
|
|
|
|
{
|
|
|
|
bool ret_val = false;
|
|
|
|
|
|
|
|
static char callee_name[] = "update";
|
|
|
|
|
|
|
|
PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name);
|
|
|
|
|
|
|
|
if (py_return == Py_True)
|
|
|
|
ret_val = true;
|
|
|
|
|
|
|
|
Py_XDECREF(py_return);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
return ret_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSwigPython_MightHaveChildrenSynthProviderInstance
|
|
|
|
(
|
|
|
|
PyObject *implementor
|
|
|
|
)
|
|
|
|
{
|
|
|
|
bool ret_val = false;
|
|
|
|
|
|
|
|
static char callee_name[] = "has_children";
|
|
|
|
|
|
|
|
PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_True);
|
|
|
|
|
|
|
|
if (py_return == Py_True)
|
|
|
|
ret_val = true;
|
|
|
|
|
|
|
|
Py_XDECREF(py_return);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
return ret_val;
|
|
|
|
}
|
|
|
|
|
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
|
|
|
SWIGEXPORT PyObject*
|
|
|
|
LLDBSwigPython_GetValueSynthProviderInstance
|
|
|
|
(
|
|
|
|
PyObject *implementor
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PyObject* ret_val = nullptr;
|
|
|
|
|
|
|
|
static char callee_name[] = "get_value";
|
|
|
|
|
|
|
|
PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_None);
|
|
|
|
|
|
|
|
if (py_return == Py_None || py_return == nullptr)
|
|
|
|
ret_val = nullptr;
|
|
|
|
|
|
|
|
lldb::SBValue* sbvalue_ptr = NULL;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
|
|
|
if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
|
|
|
|
ret_val = nullptr;
|
|
|
|
else if (sbvalue_ptr == NULL)
|
|
|
|
ret_val = nullptr;
|
|
|
|
else
|
|
|
|
ret_val = py_return;
|
|
|
|
|
|
|
|
Py_XDECREF(py_return);
|
|
|
|
return ret_val;
|
|
|
|
}
|
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
SWIGEXPORT void*
|
|
|
|
LLDBSWIGPython_CastPyObjectToSBValue
|
|
|
|
(
|
|
|
|
PyObject* data
|
|
|
|
)
|
|
|
|
{
|
|
|
|
lldb::SBValue* sb_ptr = NULL;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
|
|
|
|
|
|
|
|
if (valid_cast == -1)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return sb_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Currently, SBCommandReturnObjectReleaser wraps a unique pointer to an
|
|
|
|
// lldb_private::CommandReturnObject. This means that the destructor for the
|
|
|
|
// SB object will deallocate its contained CommandReturnObject. Because that
|
|
|
|
// object is used as the real return object for Python-based commands, we want
|
|
|
|
// it to stay around. Thus, we release the unique pointer before returning from
|
|
|
|
// LLDBSwigPythonCallCommand, and to guarantee that the release will occur no
|
|
|
|
// matter how we exit from the function, we have a releaser object whose
|
|
|
|
// destructor does the right thing for us
|
|
|
|
class SBCommandReturnObjectReleaser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SBCommandReturnObjectReleaser (lldb::SBCommandReturnObject &obj) :
|
|
|
|
m_command_return_object_ref (obj)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~SBCommandReturnObjectReleaser ()
|
|
|
|
{
|
|
|
|
m_command_return_object_ref.Release();
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
lldb::SBCommandReturnObject &m_command_return_object_ref;
|
|
|
|
};
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
2015-03-14 16:06:56 +08:00
|
|
|
LLDBSwigPythonCallCommand
|
2013-09-25 18:37:32 +08:00
|
|
|
(
|
|
|
|
const char *python_function_name,
|
|
|
|
const char *session_dictionary_name,
|
|
|
|
lldb::DebuggerSP& debugger,
|
|
|
|
const char* args,
|
2014-10-02 05:47:29 +08:00
|
|
|
lldb_private::CommandReturnObject& cmd_retobj,
|
|
|
|
lldb::ExecutionContextRefSP exe_ctx_ref_sp
|
2013-09-25 18:37:32 +08:00
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
lldb::SBCommandReturnObject cmd_retobj_sb(&cmd_retobj);
|
|
|
|
SBCommandReturnObjectReleaser cmd_retobj_sb_releaser(cmd_retobj_sb);
|
|
|
|
lldb::SBDebugger debugger_sb(debugger);
|
2014-10-02 05:47:29 +08:00
|
|
|
lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-11-13 00:23:16 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return false;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
// pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
|
|
|
|
// see comment above for SBCommandReturnObjectReleaser for further details
|
2015-11-13 00:23:16 +08:00
|
|
|
auto argc = pfunc.GetNumArguments();
|
|
|
|
PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
|
|
|
|
PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
|
|
|
|
PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb));
|
2014-10-02 05:47:29 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (argc.count == 5 || argc.has_varargs)
|
|
|
|
pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict);
|
2015-11-12 05:07:29 +08:00
|
|
|
else
|
2015-11-13 00:23:16 +08:00
|
|
|
pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
return true;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
2015-03-13 10:20:41 +08:00
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSwigPythonCallCommandObject
|
|
|
|
(
|
|
|
|
PyObject *implementor,
|
|
|
|
lldb::DebuggerSP& debugger,
|
|
|
|
const char* args,
|
|
|
|
lldb_private::CommandReturnObject& cmd_retobj,
|
|
|
|
lldb::ExecutionContextRefSP exe_ctx_ref_sp
|
|
|
|
)
|
|
|
|
{
|
2015-11-13 00:23:16 +08:00
|
|
|
using namespace lldb_private;
|
2015-03-13 10:20:41 +08:00
|
|
|
lldb::SBCommandReturnObject cmd_retobj_sb(&cmd_retobj);
|
|
|
|
SBCommandReturnObjectReleaser cmd_retobj_sb_releaser(cmd_retobj_sb);
|
|
|
|
lldb::SBDebugger debugger_sb(debugger);
|
|
|
|
lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
|
|
|
|
|
2015-03-17 11:32:21 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject self(PyRefType::Borrowed, implementor);
|
|
|
|
auto pfunc = self.ResolveName<PythonCallable>("__call__");
|
2015-03-13 10:20:41 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
2015-03-17 11:32:21 +08:00
|
|
|
return false;
|
2015-03-13 10:20:41 +08:00
|
|
|
|
2015-03-17 11:32:21 +08:00
|
|
|
// pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
|
|
|
|
// see comment above for SBCommandReturnObjectReleaser for further details
|
2015-11-13 00:23:16 +08:00
|
|
|
PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
|
|
|
|
PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
|
|
|
|
PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb));
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 00:23:16 +08:00
|
|
|
pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-03-17 11:32:21 +08:00
|
|
|
return true;
|
2015-03-13 10:20:41 +08:00
|
|
|
}
|
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
SWIGEXPORT void*
|
|
|
|
LLDBSWIGPythonCreateOSPlugin
|
|
|
|
(
|
|
|
|
const char *python_class_name,
|
|
|
|
const char *session_dictionary_name,
|
|
|
|
const lldb::ProcessSP& process_sp
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
Py_RETURN_NONE;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
// I do not want the SBProcess 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);
|
|
|
|
PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(process_sb));
|
|
|
|
if (!process_arg.IsAllocated())
|
|
|
|
Py_RETURN_NONE;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto result = pfunc(process_arg);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (result.IsAllocated())
|
|
|
|
return result.release();
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
Py_RETURN_NONE;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
2013-10-15 05:39:38 +08:00
|
|
|
SWIGEXPORT void*
|
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 08:14:28 +08:00
|
|
|
LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
|
2013-10-15 05:39:38 +08:00
|
|
|
{
|
2015-11-13 04:11:02 +08:00
|
|
|
using namespace lldb_private;
|
2013-10-15 05:39:38 +08:00
|
|
|
|
|
|
|
if (!module || !setting)
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
|
|
|
PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
|
|
|
|
auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
Py_RETURN_NONE;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
lldb::SBTarget target_sb(target_sp);
|
|
|
|
PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_sb));
|
|
|
|
auto result = pfunc(target_arg, PythonString(setting));
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
return result.release();
|
2013-10-15 05:39:38 +08:00
|
|
|
}
|
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSWIGPythonRunScriptKeywordProcess
|
|
|
|
(const char* python_function_name,
|
|
|
|
const char* session_dictionary_name,
|
|
|
|
lldb::ProcessSP& process,
|
|
|
|
std::string& output)
|
|
|
|
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
lldb::SBProcess process_sb(process);
|
|
|
|
PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(process_sb));
|
|
|
|
auto result = pfunc(process_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (PyObjectToString(result.get(), output))
|
|
|
|
return true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSWIGPythonRunScriptKeywordThread
|
|
|
|
(const char* python_function_name,
|
|
|
|
const char* session_dictionary_name,
|
|
|
|
lldb::ThreadSP& thread,
|
|
|
|
std::string& output)
|
|
|
|
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
lldb::SBThread thread_sb(thread);
|
|
|
|
PythonObject thread_arg(PyRefType::Owned, SBTypeToSWIGWrapper(thread_sb));
|
|
|
|
auto result = pfunc(thread_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (PyObjectToString(result.get(), output))
|
|
|
|
return true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSWIGPythonRunScriptKeywordTarget
|
|
|
|
(const char* python_function_name,
|
|
|
|
const char* session_dictionary_name,
|
|
|
|
lldb::TargetSP& target,
|
|
|
|
std::string& output)
|
|
|
|
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
lldb::SBTarget target_sb(target);
|
|
|
|
PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_sb));
|
|
|
|
auto result = pfunc(target_arg, dict);
|
|
|
|
if (PyObjectToString(result.get(),output))
|
|
|
|
return true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSWIGPythonRunScriptKeywordFrame
|
|
|
|
(const char* python_function_name,
|
|
|
|
const char* session_dictionary_name,
|
2013-11-04 17:33:30 +08:00
|
|
|
lldb::StackFrameSP& frame,
|
2013-09-25 18:37:32 +08:00
|
|
|
std::string& output)
|
|
|
|
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
lldb::SBFrame frame_sb(frame);
|
|
|
|
PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(frame_sb));
|
|
|
|
auto result = pfunc(frame_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (PyObjectToString(result.get(),output))
|
|
|
|
return true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2014-10-29 05:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
|
|
|
LLDBSWIGPythonRunScriptKeywordValue
|
|
|
|
(const char* python_function_name,
|
|
|
|
const char* session_dictionary_name,
|
|
|
|
lldb::ValueObjectSP& value,
|
|
|
|
std::string& output)
|
|
|
|
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2014-10-29 05:07:00 +08:00
|
|
|
|
|
|
|
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (!pfunc.IsAllocated())
|
|
|
|
return false;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
lldb::SBValue value_sb(value);
|
|
|
|
PythonObject value_arg(PyRefType::Owned, SBTypeToSWIGWrapper(value_sb));
|
|
|
|
auto result = pfunc(value_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
if (PyObjectToString(result.get(), output))
|
|
|
|
return true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
return false;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SWIGEXPORT bool
|
2015-03-14 16:06:56 +08:00
|
|
|
LLDBSwigPythonCallModuleInit
|
2013-09-25 18:37:32 +08:00
|
|
|
(
|
|
|
|
const char *python_module_name,
|
|
|
|
const char *session_dictionary_name,
|
|
|
|
lldb::DebuggerSP& debugger
|
|
|
|
)
|
|
|
|
{
|
2015-11-12 05:07:29 +08:00
|
|
|
using namespace lldb_private;
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
std::string python_function_name_string = python_module_name;
|
|
|
|
python_function_name_string += ".__lldb_init_module";
|
|
|
|
const char* python_function_name = python_function_name_string.c_str();
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-12 05:07:29 +08:00
|
|
|
PyErr_Cleaner py_err_cleaner(true);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
|
|
|
|
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
// This method is optional and need not exist. So if we don't find it,
|
|
|
|
// it's actually a success, not a failure.
|
|
|
|
if (!pfunc.IsAllocated())
|
2015-11-12 05:07:29 +08:00
|
|
|
return true;
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
lldb::SBDebugger debugger_sb(debugger);
|
|
|
|
PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
|
|
|
|
pfunc(debugger_arg, dict);
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2015-11-13 04:11:02 +08:00
|
|
|
return true;
|
2013-09-25 18:37:32 +08:00
|
|
|
}
|
|
|
|
%}
|
|
|
|
|
|
|
|
|
|
|
|
%runtime %{
|
|
|
|
// Forward declaration to be inserted at the start of LLDBWrapPython.h
|
|
|
|
#include "lldb/API/SBDebugger.h"
|
|
|
|
#include "lldb/API/SBValue.h"
|
2015-03-14 16:06:56 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
SWIGEXPORT lldb::ValueObjectSP
|
|
|
|
LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
|
|
|
|
{
|
|
|
|
lldb::ValueObjectSP valobj_sp;
|
|
|
|
if (data)
|
|
|
|
{
|
|
|
|
lldb::SBValue* sb_ptr = (lldb::SBValue *)data;
|
|
|
|
valobj_sp = sb_ptr->GetSP();
|
|
|
|
}
|
|
|
|
return valobj_sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
%}
|
|
|
|
|
|
|
|
%wrapper %{
|
2014-01-28 07:43:24 +08:00
|
|
|
|
2013-09-25 18:37:32 +08:00
|
|
|
|
|
|
|
// For the LogOutputCallback functions
|
|
|
|
void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
|
|
|
|
if (baton != Py_None) {
|
|
|
|
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
|
|
|
|
PyObject_CallFunction(reinterpret_cast<PyObject*>(baton), const_cast<char*>("s"), str);
|
|
|
|
SWIG_PYTHON_THREAD_END_BLOCK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
%}
|