导入时,Python 3 C扩展导致分段错误

时间:2017-06-20 00:31:46

标签: python c python-3.x segmentation-fault porting

我正在尝试移植此Python extension以使用Python 3.Python 3对Python C / C ++ API进行了许多更改,这需要修改旧模块的初始化和参数传递函数。到目前为止,我已经使用了旧的Python 2代码:

#include <Python.h>
#include <openssl/crypto.h>

static PyObject* SecureString_clearmem(PyObject *self, PyObject *str) {
    char *buffer;
    Py_ssize_t length;

    if (PyString_AsStringAndSize(str, &buffer, &length) != -1) {
        OPENSSL_cleanse(buffer, length);
    }
    return Py_BuildValue("");
}

static PyMethodDef SecureStringMethods[] = {
    {"clearmem", SecureString_clearmem, METH_O,
        PyDoc_STR("clear the memory of the string")},
    {NULL, NULL, 0, NULL},
};

PyMODINIT_FUNC initSecureString(void)
{
    (void) Py_InitModule("SecureString", SecureStringMethods);
}

我在this example之后做了这个:

#define PY_SSIZE_T_CLEAN

#include <Python.h>
#include <openssl/crypto.h>

static PyObject* SecureString_clearmem(PyObject *self, PyObject *args) {
    char *buffer;
    Py_ssize_t length;

    if(!PyArg_ParseTuple(args, "s#", &buffer, &length)) {
        return NULL;
    }
    OPENSSL_cleanse(buffer, length);
    Py_RETURN_NONE;
}

static PyMethodDef SecureStringMethods[] = {
    {"SecureString_clearmem", SecureString_clearmem, METH_VARARGS, "clear the memory of the string"},
    {NULL, NULL, 0, NULL},
};

static struct PyMethodDef SecureStringDef = {
    PyModuleDef_HEAD_INIT,
    "SecureString",
    NULL,
    -1,
    SecureStringMethods,
};

PyMODINIT_FUNC PyInit_SecureString(void) {
    Py_Initialize(); 
    return PyModule_Create(&SecureStringDef);
}

理论上,这应遵循模块初始化,参数传递和字符串大小变量的新Python 3规则。它成功编译和安装(我使用与项目一起分发的相同setup.py),但是当我尝试导入它时:

import SecureString

我遇到了分段错误:

Segmentation fault: 11

我曾尝试附加gdb来检查C代码,但gdb在我的计算机上无法使用Python C模块。我也试过评论OpenSSL代码,看看这是否是问题的根源,但无济于事。我的Python3安装运行其他不使用此库的程序。有人可以看看这个,并建议我应该在哪里看看或接下来应该尝试什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

段错误很可能是由于您将模块结构定义为PyMethodDef而不是PyModuleDef引起的:

static struct PyModuleDef SecureStringDef 

除此之外。我不确定你为什么在初始化函数中调用Py_Initialize。调用它是一个无操作(因为你在调用它时已经在初始化的解释器中运行了。)

顺便说一下,没有必要提出要点,Python已经有information关于如何从2移植到3。