I have a C extension module for Python that reads an xtc trajectory using the function _xdr_read_xtc.
The module is built into a .so library without problems and it runs fine most of the time. However, sometimes I get 'Segmentation fault (core dumped)'.
static PyObject * _xdr_read_xtc(PyObject *self, PyObject *args)
{
int natoms;
XDRFILE *xd;
xd = (XDRFILE *) malloc(sizeof(XDRFILE));
if (xd == NULL){
return NULL;}
XDRFILE *dummy;
dummy = xd;
if (!PyArg_ParseTuple(args, "ii", &xd, &natoms)){
return NULL;
}
free(dummy);
int step = 0;
float time;
float prec;
matrix box;
rvec *x;
x = malloc(natoms * sizeof(*x));
if (x == NULL){
return NULL;}
// read frame
int status = read_xtc(xd, natoms, &step, &time, box, x, &prec);
if (status == 0 | status == 11){
npy_intp dims[2]= {natoms, 3};
PyArrayObject *matout = (PyArrayObject *) PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, x);
PyArray_ENABLEFLAGS(matout, NPY_ARRAY_OWNDATA);
PyObject *Frame = Py_BuildValue("Oii", matout, status, step);
Py_DECREF(matout);
return Frame;
}
else{
free(x);
return NULL;
}
}
When debugging with Valgrind I get 'Process terminating with default action of signal 11 (SIGSEGV). Access not within mapped region at address 0x195688988' in line:
int status = read_xtc(xd, natoms, &step, &time, box, x, &prec);
Is there anything obviously wrong with the code? An invalid pointer maybe? Or could it be a memory issue?
Thanks!
You allocate memory in xd
to hold an XDRFILE
. Then you move xd
to dummy
, parse an integer (file handle ?) and put in into xd
/dummy
. Then you free xd
by freeing dummy
. Then you call read_xtc(xd, ...
which will access the free'd memory. In case your memory allocator decided to let go of that page, you get a SIGSEGV.
Move the free(dummy)
to where you actually no longer need the memory.