Seg fault in python extension module

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Luke Miller

    #1

    Seg fault in python extension module

    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.glVerte x4f(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_glVertex 4f(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_Parse Tuple(args,(cha r
    *)"OOOO:glVerte x4f",&obj0,&obj 1,&obj2,&obj3) ) goto fail;
    {
    arg1 = (float)(PyFloat _AsDouble(obj0) );
    }
    {
    arg2 = (float)(PyFloat _AsDouble(obj1) );
    }
    {
    arg3 = (float)(PyFloat _AsDouble(obj2) );
    }
    {
    arg4 = (float)(PyFloat _AsDouble(obj3) );
    }
    glVertex4f(arg1 ,arg2,arg3,arg4 );

    Py_INCREF(Py_No ne); resultobj = Py_None;
    return resultobj;
    fail:
    return NULL;
    };


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


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


    int
    main(int argc, char *argv[])
    {
    /* Pass argv[0] to the Python interpreter */
    Py_SetProgramNa me(argv[0]);

    /* Initialize the Python interpreter. Required. */
    Py_Initialize() ;

    /* Add a static module */
    initmodgl();
    return 0;
    };
  • John Machin

    #2
    Re: Seg fault in python extension module

    On 3/06/2006 9:51 AM, Luke Miller wrote:[color=blue]
    > 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.glVerte x4f(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.
    >[/color]
    [color=blue]
    > Thanks,
    > Luke
    >
    > #include <Python.h>
    >
    > static PyObject *_wrap_glVertex 4f(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_Parse Tuple(args,(cha r
    > *)"OOOO:glVerte x4f",&obj0,&obj 1,&obj2,&obj3) ) goto fail;
    > {
    > arg1 = (float)(PyFloat _AsDouble(obj0) );[/color]

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

    [color=blue]
    > }
    > {
    > arg2 = (float)(PyFloat _AsDouble(obj1) );
    > }
    > {
    > arg3 = (float)(PyFloat _AsDouble(obj2) );
    > }
    > {
    > arg4 = (float)(PyFloat _AsDouble(obj3) );
    > }[/color]


    You are making it really hard for yourself. Try this:
    if(!PyArg_Parse Tuple(args,"fff f: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.

    [color=blue]
    > glVertex4f(arg1 ,arg2,arg3,arg4 );[/color]

    You don't declare this function before calling it. That's dangerous.
    [color=blue]
    >
    > Py_INCREF(Py_No ne); resultobj = Py_None;
    > return resultobj;
    > fail:
    > return NULL;
    > };
    >
    >
    > static PyMethodDef modglMethods[] = {
    > { (char *)"glVertex4f ", _wrap_glVertex4 f, METH_VARARGS, NULL},
    > { NULL, NULL, 0, NULL }
    > };
    >
    >
    > PyMODINIT_FUNC modgl(void)[/color]

    I can't see how you were able to import the module. For "import modgl"
    to work, your initialisation function should be called "initmodgl" .
    [color=blue]
    > {
    > (void) Py_InitModule(" modgl", modglMethods);
    > };
    >
    >[/color]

    You are writing an extension, not embedding Python. You don't need a
    main(). Lose it.
    [color=blue]
    > int
    > main(int argc, char *argv[])
    > {
    > /* Pass argv[0] to the Python interpreter */
    > Py_SetProgramNa me(argv[0]);
    >
    > /* Initialize the Python interpreter. Required. */
    > Py_Initialize() ;
    >
    > /* Add a static module */
    > initmodgl();
    > return 0;
    > };[/color]

    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.glVertex4 f(1, 2, 3, 4)
    10.0
    |>>> modgl.glVertex4 f(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_glVertex4 f(PyObject *self, PyObject *args) {
    PyObject *resultobj = NULL;
    float arg1, arg2, arg3, arg4;


    if(!PyArg_Parse Tuple(args,"fff f:glVertex4f",& arg1,&arg2,&arg 3,&arg4))
    goto fail;
    /* glVertex4f(arg1 ,arg2,arg3,arg4 ); */

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

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

    return resultobj;
    fail:
    return NULL;

    };

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

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

    Comment

    • sam

      #3
      Re: Seg fault in python extension module

      I recommend that you also replace the NULL after the METH_VARARGS with
      a valid documentations string such as:

      static PyMethodDef modglMethods[] =
      {
      { (char *)"glVertex4f ", _wrap_glVertex4 f, METH_VARARGS, "My
      Doc String"},
      { NULL, NULL, 0, NULL }

      };

      Sam Schulenburg

      Comment

      • John Machin

        #4
        Re: Seg fault in python extension module

        On 3/06/2006 1:38 PM, sam wrote:[color=blue]
        > I recommend that you also replace the NULL after the METH_VARARGS with
        > a valid documentations string such as:
        >
        > static PyMethodDef modglMethods[] =
        > {
        > { (char *)"glVertex4f ", _wrap_glVertex4 f, METH_VARARGS, "My
        > Doc String"},
        > { NULL, NULL, 0, NULL }
        >
        > };
        >[/color]

        Lack of one is unlikely to have anything to do with the OP's segfault.

        |>>> repr(modgl.glVe rtex4f.__doc__)
        'None'
        |>>>

        As to style, etiquette, and good citizenship in module extension
        writing, it might be better to give him some references, rather than
        mention just one point.

        Cheers,
        John

        Comment

        • sam

          #5
          Re: Seg fault in python extension module

          Sorry, From MethodObject.h the 4th parameter is usually documented as
          having a NULL, but is intended to be used for a documentation string
          that will be available to the user under the various GUI IDE's such as
          IDLE or PyWin32. I just wanted to point that out..

          struct PyMethodDef {
          const char *ml_name; /* The name of the built-in function/method */
          PyCFunction ml_meth; /* The C function that implements it */
          int ml_flags; /* Combination of METH_xxx flags, which mostly
          describe the args expected by the C func */
          const char *ml_doc; /* The __doc__ attribute, or NULL */
          };

          Sam Schulenburg

          John Machin wrote:[color=blue]
          > On 3/06/2006 1:38 PM, sam wrote:[color=green]
          > > I recommend that you also replace the NULL after the METH_VARARGS with
          > > a valid documentations string such as:
          > >
          > > static PyMethodDef modglMethods[] =
          > > {
          > > { (char *)"glVertex4f ", _wrap_glVertex4 f, METH_VARARGS, "My
          > > Doc String"},
          > > { NULL, NULL, 0, NULL }
          > >
          > > };
          > >[/color]
          >
          > Lack of one is unlikely to have anything to do with the OP's segfault.
          >
          > |>>> repr(modgl.glVe rtex4f.__doc__)
          > 'None'
          > |>>>
          >
          > As to style, etiquette, and good citizenship in module extension
          > writing, it might be better to give him some references, rather than
          > mention just one point.
          >
          > Cheers,
          > John[/color]

          Comment

          Working...