c++python扩展中的零星segfault

Sporadic segfault in c++ python extension

本文关键字:segfault 扩展 c++python      更新时间:2023-10-16

我有一个python对象,它通过HTTP访问和下载一些文本。我正在运行这个python对象,并使用c++代码处理该文本。即

/* CPPCode.cxx */
int main(...) {
    for(int i = 0; i < numURLs; i++) {
        // Python method returns a string
        PyObject *pyValue = PyObject_CallMethod(pyObjectInstance, pyFunctionName, par1, par2....);
        string valString = PyString_AsString(pHistValue);   
        // ... process string ... 
    }
} 
/* PyObject.py */
class PyClass:
    def PyFunction(...):
        try: urlSock = urllib.urlopen(urlName)
        except ...
        while(...) :
             dataStr = urlSock.readline()
             # do some basic string processing....
        return dataStr

大多数URL都工作得很好——c++代码得到了正确的字符串,我可以处理它,一切都很好。一些特定的URL看起来(基本上)与浏览器上的其他URL相同,导致PyString_AsString()方法中出现segfault:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00000000000000b2
0x000000010007716d in PyString_AsString ()

如果我打印出python方法应该返回的字符串(上面伪代码中的'dataStr'),它看起来很好!我不知道是什么导致了这个问题——任何关于如何操作的提示都将不胜感激!感谢

~~~~~~

解决方案:

我使用的模板代码调用了

Py_DECREF(pyValue)

在我打电话给之前

PyString_AsString(pyValue)

我不知道为什么它会被某些特定的函数调用释放。正如"Gecco"在下面的评论中所说,

"PyString_AsString文档说:"指针指向字符串的内部缓冲区,而不是副本。数据不能以任何方式修改,除非字符串是使用PyString_FromStringAndSize(NULL,size)创建的。它不能被释放。"

PyString_AsString文档说:"指针指向字符串的内部缓冲区,而不是副本。除非字符串是使用PyString_FromStringAndSize(NULL,size)创建的,否则不能以任何方式修改数据。它不能被释放。"

请确保您不会解除分配此缓冲区

如果使用-g调试标志编译C代码(至少在GCC中),则可以使用gnu调试器gdb:运行python代码

$ gdb /path/to/python/compiled/against 
... blah ...
(gdb) run PyObject.py

你应该抓住你的segfault。

我的猜测是Py_DECREF在某种程度上得到了一个NULL值。