2017-06-28 58 views
0

我有一個Python的C擴展模塊,它使用函數_xdr_read_xtc讀取xtc軌跡。用於Python的C擴展中的SIGSEGV

該模塊內置於.so庫中,沒有問題,大部分時間運行良好。但是,有時我會得到'分段錯誤(核心轉儲)'。

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進行調試時,我得到'進程以信號11(SIGSEGV)的默認動作終止。訪問不在地址0x195688988映射區域內':

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

代碼中是否有任何明顯錯誤?一個無效的指針可能?或者它可能是一個記憶問題?

謝謝!

+0

會[此答案在SO](https://stackoverflow.com/a/42154502/8051589)有幫助嗎?我認爲'xd'(第一個參數)必須是用'xdrfile_open'打開的文件,'natoms'(第二個參數)必須由'read_xtc_natoms'初始化。 –

+0

感謝您的回覆!我已經檢查過這個帖子,並且我傳遞的xd和natoms參數是xdrfile_open和read_xtc_natoms函數的結果 –

回答

0

您在xd中分配內存以保存XDRFILE。然後,您將xd移動到dummy,解析整數(文件句柄?)並將其放入xd/dummy。然後通過釋放dummy免費xd。然後你打電話read_xtc(xd, ...,這將訪問free'd內存。如果你的內存分配器決定放開那個頁面,你會得到一個SIGSEGV。

free(dummy)移至實際不再需要內存的位置。

+0

感謝您的回覆! 我試圖做的是假的是修復內存泄漏,我實際上並沒有使用它(或者至少我不是故意的)。如果我打印出變量的地址,我得到如下: XD的malloc後:0000000000572910 假:ParseTuple後0000000000572910 XD:ParseTuple後0000000000572790 假:0000000000572910 我會盡量把免費的(虛擬),但我不不認爲這是造成問題的原因。 –

+0

'xd'在'x = malloc(...'的錯誤路徑中泄露,並且'if(status ...'的兩個部分都被泄露,不要僅僅將'xd'的值複製到'dummy'然後釋放'dummy' - 你實際上將釋放'xd'。你需要使用'xdrfile_open()'來打開文件,它將返回一個'XDRFILE',這反過來肯定不是一個你可以通過的整數'ParseTuple'。你可能會發現[this](http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/Trajectory/formats/Gromacs/_gromacs/_gromacsmodule.cpp)有幫助。 – user2722968

+0

我接受這個答案,因爲鏈接是非常有幫助的! –