【问题标题】:Python 3 C Extension Causes Segmentation Fault When ImportedPython 3 C 扩展在导入时导致分段错误
【发布时间】:2017-11-22 08:09:55
【问题描述】:

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

谢谢!

【问题讨论】:

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


    【解决方案1】:

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

    static struct PyModuleDef SecureStringDef 
    

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

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

    【讨论】:

    • 感谢您的提示!顺便说一句,我在我的问题中添加了概述/摘要,以尝试使其尽可能清晰和具有描述性,以帮助人们稍后查看此问题。在这里皱眉吗?
    • 你的问题完全没问题,就像@SquawkBirdies一样。在这个问题上,seg故障是否仍然出现?
    • 实施了建议,段错误消失了。初步测试看起来显示了预期的行为。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多