Pyr_SetString上的分段错误

2024-09-28 22:23:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为pythonctype导出的函数实现正确的错误处理。如果我理解正确,我应该调用PyErr_SetString()并返回NULL。但是调用PyErr_SetString()segfaults。我错过了什么?在

C代码:

#include <assert.h>
#include "Python.h"
PyObject *test_error(int x)
{
    assert(0==NULL);
    printf("x=%d\n",x);
    switch(x)
    {
        case  0:  Py_RETURN_NONE; // works
        case  1:  return PyString_FromString("Hello, World!"); // works
        case  2:  return PyInt_FromLong(123); // works
        case  3:  return PyFloat_FromDouble(123.4); // works
        default:
            printf("Setting error message.\n");
            PyErr_SetString(PyExc_ValueError,"This is my error!"); // segfault!
            printf("return\n"); // never reach this line
            return 0;
    }
    assert(0);
}

Python代码:

^{pr2}$

编译(在Linux[raspberry pi with gcc-4.6,gcc-4.8]和Mac[core2duo notebook,gcc-5.1.0],Linux amd ubuntu[gcc.5.1和一个额外的链接器选项-fPIC]): gcc`python2.7-config--includes--libs--ldflags`-shared-o李白e、 c

运行:

$ python e.py
test_error(0)
x=0
None

test_error(1)
x=1
Hello, World!

test_error(2)
x=2
123

test_error(3)
x=3
123.4

test_error(4)
x=4
Setting error message.
Segmentation fault: 11

Linux AMD节点上的valgrind错误:

test_error(4)
x=4
Setting error message.
==4839== Invalid read of size 8
==4839==    at 0x518A8D: PyErr_SetString (in /usr/bin/python2.7)
==4839==    by 0x6833A09: test_error (in /home/zvyagin/Projects/learning/python/c-api/libe.so)
==4839==    by 0x6630ADB: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.1)
==4839==    by 0x663040B: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.1)
==4839==    by 0x641E5FD: _ctypes_callproc (in /usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so)
==4839==    by 0x641FF9D: ??? (in /usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so)
==4839==    by 0x52CC1F: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==4839==    by 0x52CF31: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==4839==    by 0x55C593: PyEval_EvalCodeEx (in /usr/bin/python2.7)
==4839==    by 0x5B7391: PyEval_EvalCode (in /usr/bin/python2.7)
==4839==    by 0x469662: ??? (in /usr/bin/python2.7)
==4839==    by 0x4699E2: PyRun_FileExFlags (in /usr/bin/python2.7)
==4839==  Address 0x48 is not stack'd, malloc'd or (recently) free'd
==4839== 
==4839== 
==4839== Process terminating with default action of signal 11 (SIGSEGV)
==4839==  Access not within mapped region at address 0x48
==4839==    at 0x518A8D: PyErr_SetString (in /usr/bin/python2.7)
==4839==    by 0x6833A09: test_error (in /home/zvyagin/Projects/learning/python/c-api/libe.so)
==4839==    by 0x6630ADB: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.1)
==4839==    by 0x663040B: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.1)
==4839==    by 0x641E5FD: _ctypes_callproc (in /usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so)
==4839==    by 0x641FF9D: ??? (in /usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so)
==4839==    by 0x52CC1F: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==4839==    by 0x52CF31: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==4839==    by 0x55C593: PyEval_EvalCodeEx (in /usr/bin/python2.7)
==4839==    by 0x5B7391: PyEval_EvalCode (in /usr/bin/python2.7)
==4839==    by 0x469662: ??? (in /usr/bin/python2.7)
==4839==    by 0x4699E2: PyRun_FileExFlags (in /usr/bin/python2.7)

Tags: intestgnubybinsolinuxlib