Seg fault in python extension module

John Machin sjmachin at lexicon.net
Fri Jun 2 22:12:20 EDT 2006


On 3/06/2006 9:51 AM, Luke Miller wrote:
> Hello,
> 
> I am working on my first python module based on a c program. The
> module builds and installs OK using dist-utils, and imports fine into
> python. However, when I try and use the one wrapper
> ("modgl.glVertex4f(1, 2, 3, 1)") in the module, it seg faults.
> 
> Can anyone spot why this isn't working, or recommend a way to debug
> these things.
> 

> Thanks,
> Luke
> 
> #include <Python.h>
> 
> static PyObject *_wrap_glVertex4f(PyObject *self, PyObject *args) {
>    PyObject *resultobj = NULL;
>    float arg1 ;
>    float arg2 ;
>    float arg3 ;
>    float arg4 ;
>    PyObject * obj0 = 0 ;
>    PyObject * obj1 = 0 ;
>    PyObject * obj2 = 0 ;
>    PyObject * obj3 = 0 ;
> 
>    if(!PyArg_ParseTuple(args,(char
> *)"OOOO:glVertex4f",&obj0,&obj1,&obj2,&obj3)) goto fail;
>    {
>        arg1 = (float)(PyFloat_AsDouble(obj0));

Not testing for an error after an API call is just asking for trouble.


>    }
>    {
>        arg2 = (float)(PyFloat_AsDouble(obj1));
>    }
>    {
>        arg3 = (float)(PyFloat_AsDouble(obj2));
>    }
>    {
>        arg4 = (float)(PyFloat_AsDouble(obj3));
>    }


You are making it really hard for yourself. Try this:
  if(!PyArg_ParseTuple(args,"ffff:glVertex4f",&arg1,&arg2 etc etc

The batteries are already included. Using the code for the precise type 
that you want gives you checking for type mismatches, a with sensible 
error message.


>    glVertex4f(arg1,arg2,arg3,arg4);

You don't declare this function before calling it. That's dangerous.

> 
>    Py_INCREF(Py_None); resultobj = Py_None;
>    return resultobj;
>    fail:
>    return NULL;
> };
> 
> 
> static PyMethodDef modglMethods[] = {
>      { (char *)"glVertex4f", _wrap_glVertex4f, METH_VARARGS, NULL},
>      { NULL, NULL, 0, NULL }
> };
> 
> 
> PyMODINIT_FUNC modgl(void)

I can't see how you were able to import the module. For "import modgl" 
to work, your initialisation function should be called "initmodgl".

> {
>    (void) Py_InitModule("modgl", modglMethods);
> };
> 
> 

You are writing an extension, not embedding Python. You don't need a 
main(). Lose it.

> int
> main(int argc, char *argv[])
> {
>    /* Pass argv[0] to the Python interpreter */
>    Py_SetProgramName(argv[0]);
> 
>    /* Initialize the Python interpreter.  Required. */
>    Py_Initialize();
> 
>    /* Add a static module */
>    initmodgl();
>     return 0;
> };

Below is a cutdown version of your module, that returns a value so that 
you can see that it is working. You might like to use that as a base. 
Here it is working:

|>>> import modgl
|>>> modgl.glVertex4f(1, 2, 3, 4)
10.0
|>>> modgl.glVertex4f(1, 2, "three", 4)
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
TypeError: a float is required
|>>>

HTH,
John



8<---
#include <Python.h>

static PyObject *
_wrap_glVertex4f(PyObject *self, PyObject *args) {
     PyObject *resultobj = NULL;
     float arg1, arg2, arg3, arg4;

 
if(!PyArg_ParseTuple(args,"ffff:glVertex4f",&arg1,&arg2,&arg3,&arg4)) 
goto fail;
     /* glVertex4f(arg1,arg2,arg3,arg4); */

     /* Py_INCREF(Py_None); resultobj = Py_None; */

     resultobj = Py_BuildValue("d", (double)(arg1 + arg2 + arg3 + arg4));

     return resultobj;
     fail:
     return NULL;

};

static PyMethodDef modglMethods[] = {
          { (char *)"glVertex4f", _wrap_glVertex4f, METH_VARARGS, NULL},
          { NULL, NULL, 0, NULL }
};

PyMODINIT_FUNC
initmodgl(void)
{
     (void) Py_InitModule("modgl", modglMethods);
};
8<---



More information about the Python-list mailing list