Python 的 C 扩展中的 SIGSEGV

SIGSEGV in C extension for Python

我有一个 Python 的 C 扩展模块,它使用函数 _xdr_read_xtc 读取 xtc 轨迹。

该模块毫无问题地内置到 .so 库中,并且大部分时间都运行良好。但是,有时我会得到 '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;
    }
}

使用 Valgrind 调试时,我得到 'Process terminating with default action of signal 11 (SIGSEGV). Access not within mapped region at address 0x195688988' 行:

int status = read_xtc(xd, natoms, &step, &time, box, x, &prec);

代码有什么明显的错误吗?也许是一个无效的指针?或者可能是内存问题?

谢谢!

您在 xd 中分配内存以容纳 XDRFILE。然后你将 xd 移动到 dummy,解析一个整数(文件句柄?)并放入 xd/dummy。然后通过释放 dummy 来释放 xd。然后你调用 read_xtc(xd, ... 将访问空闲的内存。如果你的内存分配器决定放弃那个页面,你会得到一个 SIGSEGV。

free(dummy) 移动到您实际上不再需要内存的地方。