Seg fault in python extension module

L

Luke Miller

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));
}
{
arg2 = (float)(PyFloat_AsDouble(obj1));
}
{
arg3 = (float)(PyFloat_AsDouble(obj2));
}
{
arg4 = (float)(PyFloat_AsDouble(obj3));
}
glVertex4f(arg1,arg2,arg3,arg4);

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)
{
(void) Py_InitModule("modgl", modglMethods);
};


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;
};
 
J

John Machin

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<---
 
S

sam

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_glVertex4f, METH_VARARGS, "My
Doc String"},
{ NULL, NULL, 0, NULL }

};

Sam Schulenburg
 
J

John Machin

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_glVertex4f, METH_VARARGS, "My
Doc String"},
{ NULL, NULL, 0, NULL }

};

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

|>>> repr(modgl.glVertex4f.__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
 
S

sam

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 said:
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_glVertex4f, METH_VARARGS, "My
Doc String"},
{ NULL, NULL, 0, NULL }

};

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

|>>> repr(modgl.glVertex4f.__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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,787
Messages
2,569,630
Members
45,335
Latest member
Tommiesal

Latest Threads

Top