From aa7f2ba60524ba9005d7d0ad0198ead799f72130 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Fri, 8 Mar 2024 12:09:09 -0500 Subject: [PATCH] Segfault fixes. Switching scenes broke some assumptions. All PyObject calls from userspace now handle (discard) exceptions and return values. --- src/GameEngine.cpp | 11 ++++++++++- src/McRFPy_API.cpp | 11 ++++++++++- src/PyScene.cpp | 11 ++++++++++- src/Scene.cpp | 1 + src/Timer.cpp | 11 ++++++++++- 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/GameEngine.cpp b/src/GameEngine.cpp index ccb5805..1e18194 100644 --- a/src/GameEngine.cpp +++ b/src/GameEngine.cpp @@ -162,7 +162,16 @@ void GameEngine::sUserInput() else if (currentScene()->key_callable != NULL && currentScene()->key_callable != Py_None) { PyObject* args = Py_BuildValue("(ss)", ActionCode::key_str(event.key.code).c_str(), actionType.c_str()); - PyObject_Call(currentScene()->key_callable, args, NULL); + PyObject* retval = PyObject_Call(currentScene()->key_callable, args, NULL); + if (!retval) + { + std::cout << "key_callable has raised an exception. It's going to STDERR and being dropped:" << std::endl; + PyErr_Print(); + PyErr_Clear(); + } else if (retval != Py_None) + { + std::cout << "key_callable returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; + } } else { diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index cbda5a4..47f0cbd 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -240,7 +240,16 @@ void McRFPy_API::doAction(std::string actionstr) { return; } //std::cout << " (" << PyUnicode_AsUTF8(PyObject_Repr(callbacks[actionstr])) << ")" << std::endl; - PyObject_Call(callbacks[actionstr], PyTuple_New(0), NULL); + PyObject* retval = PyObject_Call(callbacks[actionstr], PyTuple_New(0), NULL); + if (!retval) + { + std::cout << "doAction has raised an exception. It's going to STDERR and being dropped:" << std::endl; + PyErr_Print(); + PyErr_Clear(); + } else if (retval != Py_None) + { + std::cout << "doAction returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; + } } /* diff --git a/src/PyScene.cpp b/src/PyScene.cpp index 66571fc..3b5a872 100644 --- a/src/PyScene.cpp +++ b/src/PyScene.cpp @@ -27,7 +27,16 @@ void PyScene::do_mouse_input(std::string button, std::string type) if (target) { PyObject* args = Py_BuildValue("(iiss)", mousepos.x, mousepos.y, button.c_str(), type.c_str()); - PyObject_Call(target->click_callable, args, NULL); + PyObject* retval = PyObject_Call(target->click_callable, args, NULL); + if (!retval) + { + std::cout << "click_callable has raised an exception. It's going to STDERR and being dropped:" << std::endl; + PyErr_Print(); + PyErr_Clear(); + } else if (retval != Py_None) + { + std::cout << "click_callable returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; + } } } } diff --git a/src/Scene.cpp b/src/Scene.cpp index 4137514..8567e61 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -4,6 +4,7 @@ //Scene::Scene() { game = 0; std::cout << "WARN: default Scene constructor called. (game = " << game << ")" << std::endl;}; Scene::Scene(GameEngine* g) { + key_callable = Py_None; game = g; ui_elements = std::make_shared>>(); } diff --git a/src/Timer.cpp b/src/Timer.cpp index 88eb597..3547488 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -15,7 +15,16 @@ bool Timer::test(int now) { last_ran = now; PyObject* args = Py_BuildValue("(i)", now); - PyObject_Call(target, args, NULL); + PyObject* retval = PyObject_Call(target, args, NULL); + if (!retval) + { + std::cout << "timer has raised an exception. It's going to STDERR and being dropped:" << std::endl; + PyErr_Print(); + PyErr_Clear(); + } else if (retval != Py_None) + { + std::cout << "timer returned a non-None value. It's not an error, it's just not being saved or used." << std::endl; + } return true; } return false;