segfault when calling Python from C thread

Greg Chapman glc at well.com
Sun Feb 20 09:58:59 EST 2005


Travis Berg wrote:

> 
> I'm running into a problem when trying to perform a callback to a
> Python function from a C extension.  Specifically, the callback is
> being made by a pthread that seems to cause the problem.  If I call
> the callback from the parent process, it works fine.  The PyObject is
> static, and holds the same value in both Parent and thread, so I'm at
> a loss as to what would be different in the pthread from the parent
> that would cause a segfault on the callback.  The machine specifics
> are an x86 intel processor with RedHat linux.
> 
> 
> /* calling callback */
> void callback(char * str) {
>     PyObject *arglist;
>     PyObject *result;
>     if(str == NULL)
>         return;
> 
>     if(my_callback == NULL) {
>         printf("no callback function provided, returning...\n");
>         return;
>     }
> 
>     /* Time to call the callback */
>     arglist = Py_BuildValue("(s)", str);
>     result = PyEval_CallObject(my_callback, arglist);
>     Py_DECREF(arglist);
>     if(result == NULL)
>         return;
>     Py_DECREF(result);
> }

Your callback function needs to hold the Python GIL (and have a vaild
threadstate) before it calls any Python C-API functions.  Change the
last part of it to:

    PyGILState_STATE state;

    /* ... */

    /* Time to call the callback */

    state = PyGILState_Ensure();

    arglist = Py_BuildValue("(s)", str);
    result = PyEval_CallObject(my_callback, arglist);
    Py_DECREF(arglist);
    if(result == NULL)
        return;
    Py_DECREF(result);

    PyGILState_Release(state);
}

Also, somewhere in your main thread you should call PyEval_InitThreads
before any of the callback threads execute.  (This call is made
automatically if you are creating new threads using Python's thread
module, but if the new threads are created by some C code, you need to
call it yourself.)

---
Greg Chapman



More information about the Python-list mailing list