Python 3 C扩展导入时出现段错误

Python 3 C Extension Causes Segmentation Fault When Imported

我正在尝试移植此 Python extension 以与 Python 3 一起使用。Python 3 对 Python C/C++ API 需要修改遗留模块的初始化和参数传递函数。至此,我取了旧的Python2码:

#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 安装运行其他不使用此库的程序。有人可以看看这个并建议我应该看哪里或下一步应该尝试什么吗?

谢谢!

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

static struct PyModuleDef SecureStringDef 

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

顺便说一句,不需要要点,Python 已经 information 关于如何从 2 移植到 3。