SourceForge has been redesigned. Learn more.

#8 check whether/where we need to acquire GIL

Other (1)
Knut Franke

This is a follow-up on bug #2686283. The problem was calling some API functions (namely,*(), except for newGraph() and newTable("name")) from Python scripts would lead to segmentation faults on two Arch Linux systems (using Python 2.6 and SIP 4.7.9). Tilman reported that he sees no crashes using Python 2.5 and SIP 4.7.9.

While I've managed to fix the immediate problem by acquiring the GIL around calls into the Python API in PythonScripting::setQObject(), I don't understand why this should need to be done in a single-threaded application, whether this is where the problem should be fixed, and if so, whether we need to acquire the GIL also in other places. So, in the interest of not running into a similar problem in the future, this deserves further investigation.

Using debug builds of Python 2.6.2 and SIP, I've managed to find out the following:

- The crashes occur when trying to export the new Table/Matrix/Note instances to Python, which is done by the ScriptEdit instances contained in their views.

- The call to sipConvertFromInstance() in setQObject() leads to sip_api_convert_from_instance() and sipWrapSimpleInstance() to be call, neither of which manipulate the GIL (other SIP functions do so, conditional on the compile-time macro WITH_THREAD).

- A wrapper object is created by using PyObject_Call on the wrapper type. The crash occurs within the macro Py_EnterRecursiveCall in PyObject_Call, where PyThreadState_GET() returns 0. In other words, the pointer to the state information for the current thread gets reset; without apparent reason, since we only have one thread.

I've tried to create a minimal example exhibiting the problem, so far without success - PyThreadState_GET() always returns a valid pointer.


Log in to post a comment.