c python扩展导致python脚本由于垃圾收集错误而退出segfault

Posted

技术标签:

【中文标题】c python扩展导致python脚本由于垃圾收集错误而退出segfault【英文标题】:c python extension causes python script to exit with segfault due to garbage collection error 【发布时间】:2015-03-25 08:44:49 【问题描述】:

我在 C 中有以下例程,用于将字符串数组转换为 python 字符串列表

PyObject* build_pylist(char** strings, unsigned int string_cnt)

    PyObject* list = PyList_New(string_cnt);
    int i;
    for(i = 0; i < string_cnt; i++)

        PyObject* pystring = PyString_FromStringAndSize(
            (const char*) strings[i], 
            (Py_ssize_t) strlen(strings[i])
        );

        #per http://www.kbs.twi.tudelft.nl/Documentation/Programming/python-2.1/ext/thinIce.html
        #apparently the inc/dec is necessary...doesn't seem
        #to make a difference

        Py_INCREF(pystring);
        PyList_SET_ITEM(
            list, 
            (Py_ssize_t) i, 
            pystring
        );
        Py_DECREF(pystring);

        free(strings[i]);
    

    free(strings);
    return list;

PyString_FromStringAndSize 函数会复制给定字符串,因此我在复制不必要的字符串时释放它们,然后释放这些字符串指针的容器。这一切似乎都很好。 python 列表返回到脚本,所有字符串看起来都不错,当通过sys.getrefcount 对列表中的字符串和列表本身进行检查时,引用计数看起来也不错。

所有引用计数都返回 2,这似乎是正确的,因为对 getrefcount 的调用会导致临时增加 1。我很确定这与基于核心转储分析的引用计数有关

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   org.python.python               0x000000010abfc52a collect + 482
1   org.python.python               0x000000010abfc33f PyGC_Collect + 35
2   org.python.python               0x000000010abea056 Py_Finalize + 290
3   org.python.python               0x000000010abfbe9b Py_Main + 3143
4   libdyld.dylib                   0x00007fff8843a7e1 start + 1

错误发生在脚本退出时,您可以清楚地看到垃圾收集器中正在发生崩溃。对于这个错误,我唯一能想到的就是错误的引用计数。

有什么想法吗?

【问题讨论】:

【参考方案1】:

与垃圾回收没有直接关系,但您使用的编译器与构建您的 python 版本时使用的编译器相同吗?有时这很重要。我曾经调试了几个星期的段错误,直到我用 Microsoft Visual C++ Compiler for python 替换 MinGW 时才消失。

【讨论】:

不走运。不确定我的 python 是用哪个编译器编译的,所以我尝试了所有的编译器并得到了相同的结果。

以上是关于c python扩展导致python脚本由于垃圾收集错误而退出segfault的主要内容,如果未能解决你的问题,请参考以下文章

python的微信收红包自动化测试脚本

python的微信收红包自动化测试脚本

python如何调用扩展模块

python04:垃圾回收用户交互运算符

由于 SSL 导致的 Python 代码执行瓶颈 - 如何优化?

如何重新加载 Python3 C 扩展模块?