Memory corruption around PyGObjectData->closures list causes segfault (+patch)
The memory corruption occurs because of the race while accessing PyGObjectData->closures list.
It happens only when GC is running from a different thread than the g_signal_handle_disconnect code. See the attached traceback.
A brief explanation of what is happening. GC iterates PyGObjectData->closures list inside pygobject_traverse holding the GIL. At the same time, the other thread calls g_signal_handle_disconnect, which results in the pygobject_unwatch_closure call (not holding GIL) that modifies the list.
The proposed patch fixes the race by protecting access to the list by GIL inside pygobject_unwatch_closure.