segmentation fault when executing PyImport_ImportModule("sys")

Dietrich Bollmann diresu at web.de
Sat Apr 12 09:53:54 EDT 2008


Hi, 

I found the reason for the segmentation fault and hope that my solution
might be helpful for somebody else some day :)

On Tue, 2008-04-08 at 19:31 +0900, Dietrich Bollmann wrote:
Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 0xb046ab90 (LWP 9854)]
> threadstate_getframe (self=0xb7e8a889) at ../Python/pystate.c:154
> 154     ../Python/pystate.c: No such file or directory.
>         in ../Python/pystate.c
> (gdb) bt full
> #0  threadstate_getframe (self=0xb7e8a889) at ../Python/pystate.c:154
> No locals.
> #1  0xb7e8a897 in PyEval_GetGlobals () at ../Python/ceval.c:3340%G%
@
> ...snip...
> #3  0xb7eaede5 in PyImport_ImportModule (name=0x901504b "sys")%G%@
> ...snip...

The segmentation fault was caused by the interaction of my own code
with some changes made to the code base recently which where intended
to make the python functions thread save:

Here come the new additions to the function which starts the Python
interpreter:

  void BPY_start_python( int argc, char **argv )
  {
      PyThreadState *py_tstate = NULL;
  
      ...
  
      /* Initialize thread support (also acquires lock) */
      PyEval_InitThreads();
  
      /* Don'\''t allow the Python Interpreter to release the GIL on
       * its own, to guarantee PyNodes work properly. For Blender this
       * is currently the best default behavior.
       * The following code in C is equivalent in Python to:
       * "import sys; sys.setcheckinterval(sys.maxint)" */
      _Py_CheckInterval = PyInt_GetMax();
  
      ...
  
      py_tstate = PyGILState_GetThisThreadState();
      PyEval_ReleaseThread(py_tstate);
  
      ...
  }

Until recently only one thread accessed python objects and there was
no need for any code making Python thread-save.

This didn't cause any problem with my own code as I only inserted
events in form of python code to execute into a thread save event
queue which was worked off by the only thread accessing python
objects.

With the new python thread code added I had to surround all my code
which accesses python objects with PyGILState_*() in order to solve
the problem:

  PyGILState_STATE gstate;

  /* aquire python thread */
  gstate = PyGILState_Ensure();

  ...access python objects...

  /* release python thread */
  PyGILState_Release(gstate);

The PyGILState_*() functions ensure that a global Python thread lock
is held by the current thread, protecting the Python objects from
being accessed by other threads in the same time.

For more detailed explanations see the chapter "8.1 Thread State and
the Global Interpreter Lock" (http://docs.python.org/api/threads.html)
in the Python/C API Reference Manual.

Thanks for your help,

Dietrich







More information about the Python-list mailing list