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

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

谢谢!

最佳答案

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

static struct PyModuleDef SecureStringDef 

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

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

关于Python 3 C扩展导入时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44641919/

相关文章:

python - 用于约束参数的卡方检验

python - 在 Python 中,在一个字符串中,用一个空格删除多个空格,如果它不是前导多个空格

python - 什么是正确的列表理解语法

python - 属性错误 : 'UUID' object has no attribute 'replace' when using backend-agnostic GUID type

c - 因此,如果我 scanf ("%c",del),在读取字符串之前,它可以工作,但之后就不行了

java - 小端到整数(或 BigInteger)

python - 下拉框中的 GTK3 Python 类型

c++ - 如何通过串行端口发送请求从目录中检索数据?

python - 通过 zip 循环 DataFrame

python - 无法使用 spacy.load ('en' 加载 spacy 的英语语言模块)