python & c-c++扩展模块案例segmentfault

Posted

技术标签:

【中文标题】python & c-c++扩展模块案例segmentfault【英文标题】:python & c-c++ extended module case segmentfault 【发布时间】:2020-01-07 03:03:36 【问题描述】:

c++代码

extern "C" PyObject * test()
    PyObject *oplist = PyList_New(10000);
    for(uint32_t j = 0; j < 10000; j++)
        PyObject* pTuple = PyTuple_New(3);
        assert(PyTuple_Check(pTuple));
        assert(PyTuple_Size(pTuple) == 3);
        PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "b"));
        PyTuple_SetItem(pTuple, 1, Py_BuildValue("i", 1)); 
        PyTuple_SetItem(pTuple, 2, Py_BuildValue("s", "a"));
        PyList_SetItem(oplist, j, pTuple);
        
    return oplist;

python 代码

LID = ctypes.CDLL('%s/token2map_lib.so' % '.')
LID.test.restype = py_object
LID.test()

构建命令 g++ -fPIC token2map.cpp -I/usr/local/app/service/virtualenvs/NLP/include/python2.7 -shared -o token2map_lib.so 我只是展示了一部分代码,见谅,总代码太长了

问题: 在 c++ 代码中,这个函数返回 res_list 很小,一切正常。永远,结果集超过 215(j = 215) 个 case segmentfalut。我找不到问题,希望现在的朋友能给我一些建议,我将非常感激。

我有办法解决这个问题

extern "C" PyObject * test()
    PyGILState_STATE gstate = PyGILState_Ensure();
    PyObject *oplist = PyTuple_New(10000);
    for(int32_t j = 0; j < 10000; j++)
        PyObject * pTuple = PyTuple_New(3);
        assert(PyTuple_Check(pTuple));
        assert(PyTuple_Size(pTuple) == 3);
        PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "b"));
        PyTuple_SetItem(pTuple, 1, Py_BuildValue("i", 1)); 
        PyTuple_SetItem(pTuple, 2, Py_BuildValue("s", "a"));
        PyTuple_SetItem(oplist, j, pTuple);
        
    PyGILState_Release(gstate);
    return oplist;

但是有没有其他方法可以解决这个问题?我不认为获得 GIL locak 是一种好方法

【问题讨论】:

您永远不会检查这些函数中任何的返回值。如文档所述,您必须始终检查每个 Python API 函数的每个返回值是否返回值 断言不是进行检查的正确方法。 无论如何,这个问题似乎没有minimal reproducible example,甚至没有解释如何调用该函数,因此我投票关闭 【参考方案1】:

我无法解释为什么您的代码会出现段错误。我确实觉得有趣的是,您能够使用不带参数的函数构建您的扩展。但是,我可以提供可以构建和工作的代码:

#define Py_SSIZE_T_CLEAN
#include <Python.h>
#include <inttypes.h>
#ifdef __cplusplus
extern "C" 
#endif

static PyObject *test(PyObject *self, PyObject *ignorethis)

    PyObject *oplist = PyList_New(10000);
    for(uint32_t j = 0; j < 10000; ++j)
        PyObject *pTuple = PyTuple_New(3);
        PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "b"));
        PyTuple_SetItem(pTuple, 1, Py_BuildValue("i", 1));
        PyTuple_SetItem(pTuple, 2, Py_BuildValue("s", "a"));
        PyList_SetItem(oplist, j, pTuple);
    
    return oplist;


static PyMethodDef methods[] = 
    "test", test, METH_NOARGS, "function given by so"
;

static PyModuleDef foobar = 
    PyModuleDef_HEAD_INIT,
    "foobar",
    "so question module",
    -1,
    methods
;

PyMODINIT_FUNC PyInit_foobar(void)
    PyObject *module;
    module = PyModule_Create(&foobar);
    return module;


#ifdef __cplusplus

#endif

您可以使用import foobar 加载此模块,然后使用foobar.test() 运行

【讨论】:

以上是关于python & c-c++扩展模块案例segmentfault的主要内容,如果未能解决你的问题,请参考以下文章

Python任务调度模块APScheduler(内含定点报时案例)

python购物小票的案例

C-C 法混沌时间序列 Matlab与Python代码

python:re模块

CobaltStrike使用-第六篇(域内渗透&横向扩展)

爬虫(十四):Scrapy框架 初识Scrapy第一个案例