SWIG崩溃Python

2024-09-24 10:21:57 发布

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

我有一个最简单的测试用例:

%module test
%{

static char* MyExceptionName = "_test.MyException";
static PyObject* MyException = NULL;

%}

%inline %{

static PyObject* Foo()
{
    PyErr_SetNone(MyException);
    return NULL;
}

%}

%init
{
    MyException = PyErr_NewException(MyExceptionName, NULL, NULL);
}

这是设置.py脚本:

^{pr2}$

当我按如下方式构建和测试它时,我得到:

 swig -python -threads test.i
 python_d -c "import test; test.Foo()"
 Fatal Python error: PyThreadState_Get: no current thread

我得到的回溯是

python27_d.dll!Py_FatalError(const char * msg=0x000000001e355a00)  Line 1677    C
python27_d.dll!PyThreadState_Get()  Line 330    C
python27_d.dll!PyErr_Restore(_object * type=0x00000000020d50b8, _object * value=0x0000000000000000, _object * traceback=0x0000000000000000)  Line 27 + 0x5 bytes    C
python27_d.dll!PyErr_SetObject(_object * exception=0x00000000020d50b8, _object * value=0x0000000000000000)  Line 58 C
python27_d.dll!PyErr_SetNone(_object * exception=0x00000000020d50b8)  Line 64   C
_test_d.pyd!Foo()  Line 2976    C

环境:

  • Win 7 64位
  • Python 2.7.3(默认值,2012年8月15日,18:18:52)[MSCV.1500 64位(AMD64)]在win32上
  • 2.0.7瑞士法郎

Tags: testobjectfoolinestaticnullpyobjectdll
1条回答
网友
1楼 · 发布于 2024-09-24 10:21:57

错误的原因是,当-threads通过

swig -threads -python test.i

我们得到这样的结果(多余的代码已被修订):

^{pr2}$

看,当Foo()被调用时,全局解释器锁已经被释放了。Foo()不应该再进行任何PythonAPI调用。在

解决方案是使用SWIG_Python_SetErrorObj,它在调用pythoncapi之前获取全局解释器锁。在

static PyObject* Foo()
{
    SWIG_Python_SetErrorObj(MyException, Py_None);
    return NULL;
}

另一种方法是使用SWIG_PYTHON_THREAD_BEGIN_块和SWIG_PYTHON_THREAD_END_块

static PyObject* Foo()
{
    SWIG_PYTHON_THREAD_BEGIN_BLOCK; 

    PyErr_SetNone(MyException);

    SWIG_PYTHON_THREAD_END_BLOCK;
    return NULL;
}

相关问题 更多 >