Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lldb/bindings/python/python-swigsafecast.swig
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ PythonObject SWIGBridge::ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp) {
SWIGTYPE_p_lldb__SBBreakpoint);
}

PythonObject SWIGBridge::ToSWIGWrapper(Status status) {
PythonObject SWIGBridge::ToSWIGWrapper(Status&& status) {
return ToSWIGHelper(new lldb::SBError(std::move(status)), SWIGTYPE_p_lldb__SBError);
}

Expand Down
195 changes: 25 additions & 170 deletions lldb/bindings/python/python-wrapper.swig
Original file line number Diff line number Diff line change
Expand Up @@ -229,176 +229,6 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject
return pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger_sp)), dict);
}

PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args_impl,
const lldb::BreakpointSP &breakpoint_sp) {

if (python_class_name == NULL || python_class_name[0] == '\0' ||
!session_dictionary_name)
return PythonObject();

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())
return PythonObject();

PythonObject result =
pfunc(SWIGBridge::ToSWIGWrapper(breakpoint_sp), SWIGBridge::ToSWIGWrapper(args_impl), dict);
// FIXME: At this point we should check that the class we found supports all
// the methods that we need.

if (result.IsAllocated()) {
// Check that __callback__ is defined:
auto callback_func = result.ResolveName<PythonCallable>("__callback__");
if (callback_func.IsAllocated())
return result;
}
return PythonObject();
}

unsigned int lldb_private::python::SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
void *implementor, const char *method_name,
lldb_private::SymbolContext *sym_ctx) {
PyErr_Cleaner py_err_cleaner(false);
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
auto pfunc = self.ResolveName<PythonCallable>(method_name);

if (!pfunc.IsAllocated())
return 0;

PythonObject result = sym_ctx ? pfunc(SWIGBridge::ToSWIGWrapper(*sym_ctx)) : pfunc();

if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
return 0;
}

// The callback will return a bool, but we're need to also return ints
// so we're squirrelling the bool through as an int... And if you return
// nothing, we'll continue.
if (strcmp(method_name, "__callback__") == 0) {
if (result.get() == Py_False)
return 0;
else
return 1;
}

long long ret_val = unwrapOrSetPythonException(As<long long>(result));

if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
return 0;
}

return ret_val;
}

PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedStopHook(
lldb::TargetSP target_sp, const char *python_class_name,
const char *session_dictionary_name, const StructuredDataImpl &args_impl,
Status &error) {
if (python_class_name == NULL || python_class_name[0] == '\0') {
error = Status::FromErrorString("Empty class name.");
return PythonObject();
}
if (!session_dictionary_name) {
error = Status::FromErrorString("No session dictionary");
return PythonObject();
}

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()) {
error = Status::FromErrorStringWithFormat("Could not find class: %s.",
python_class_name);
return PythonObject();
}

PythonObject result =
pfunc(SWIGBridge::ToSWIGWrapper(target_sp), SWIGBridge::ToSWIGWrapper(args_impl), dict);

if (result.IsAllocated()) {
// Check that the handle_stop callback is defined:
auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
if (callback_func.IsAllocated()) {
if (auto args_info = callback_func.GetArgInfo()) {
size_t num_args = (*args_info).max_positional_args;
if (num_args != 2) {
error = Status::FromErrorStringWithFormat(
"Wrong number of args for "
"handle_stop callback, should be 2 (excluding self), got: %zu",
num_args);
return PythonObject();
} else
return result;
} else {
error = Status::FromErrorString(
"Couldn't get num arguments for handle_stop "
"callback.");
return PythonObject();
}
return result;
} else {
error = Status::FromErrorStringWithFormat(
"Class \"%s\" is missing the required "
"handle_stop callback.",
python_class_name);
}
}
return PythonObject();
}

bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp,
lldb::StreamSP stream) {
// handle_stop will return a bool with the meaning "should_stop"...
// If you return nothing we'll assume we are going to stop.
// Also any errors should return true, since we should stop on error.

PyErr_Cleaner py_err_cleaner(false);
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
auto pfunc = self.ResolveName<PythonCallable>("handle_stop");

if (!pfunc.IsAllocated())
return true;

std::shared_ptr<lldb::SBStream> sb_stream = std::make_shared<lldb::SBStream>();
PythonObject sb_stream_arg = SWIGBridge::ToSWIGWrapper(sb_stream);
PythonObject result =
pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);

if (PyErr_Occurred()) {
stream->PutCString("Python error occurred handling stop-hook.");
PyErr_Print();
PyErr_Clear();
return true;
}

// Now add the result to the output stream. SBStream only
// makes an internally help StreamString which I can't interpose, so I
// have to copy it over here.
stream->PutCString(sb_stream->GetData());
sb_stream_arg.release();

if (result.get() == Py_False)
return false;
else
return true;
}

// wrapper that calls an optional instance member of an object taking no
// arguments
static PyObject *LLDBSwigPython_CallOptionalMember(
Expand Down Expand Up @@ -652,6 +482,18 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject * dat
return sb_ptr;
}

void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject * data) {
lldb::SBSymbolContext *sb_ptr = nullptr;

int valid_cast =
SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBSymbolContext, 0);

if (valid_cast == -1)
return NULL;

return sb_ptr;
}

void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
lldb::SBValue *sb_ptr = NULL;

Expand All @@ -677,6 +519,19 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyOb
return sb_ptr;
}

void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *
data) {
lldb::SBExecutionContext *sb_ptr = NULL;

int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
SWIGTYPE_p_lldb__SBExecutionContext, 0);

if (valid_cast == -1)
return NULL;

return sb_ptr;
}

bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommand(
const char *python_function_name, const char *session_dictionary_name,
lldb::DebuggerSP debugger, const char *args,
Expand Down
Loading