Py_Finalize()在Python中出错后崩溃

Luk*_*sen 1 c python

我正在尝试使用Py_CompileString()和调用一些python代码PyEval_EvalCode().它工作正常,但当Python代码包含错误Py_Finalize()时.

Py_Initialize();

PyObject* code = Py_CompileString("pprint('Hello World')", "", Py_file_input);
PyObject* m = PyImport_AddModule("__main__");
PyObject* d = PyModule_GetDict(m);
Py_DECREF(m);
PyObject* r = PyEval_EvalCode(code, d, d);
Py_DECREF(d);
if (!r)
    PyErr_Print();
Py_DECREF(code);

Py_Finalize();
Run Code Online (Sandbox Code Playgroud)

输出符合预期:

Traceback (most recent call last):
  File "", line 1, in <module>
NameError: name 'pprint' is no defined
Run Code Online (Sandbox Code Playgroud)

但是在调用Py_Finalize()程序崩溃的时候.如果我将第3行更改为

PyObject* code = Py_CompileString("print('Hello World')", "", Py_file_input);
Run Code Online (Sandbox Code Playgroud)

程序运行并终止正常.这里出了什么问题?

如果我在gdb中运行该程序,我得到这个输出:

Windows:
Program received signal SIGSEGV, Segmentation fault.
0x1e01a030 in python32!PyType_IsSubtype () from C:\Windows\SysWOW64\python32.dll

Linux:
Program received signal SIGSEGV, Segmentation fault.
0xb7ef17bb in visit_decref (op=0xb78c87ec, data=0x0) at Modules/gcmodule.c:321
321     Modules/gcmodule.c: File or Directory not found.
        in Modules/gcmodule.c
Run Code Online (Sandbox Code Playgroud)

小智 5

这种失败的实际原因并不是你Py_DECREF太早打电话.这就是你要打电话的!

PyImport_AddModule返回一个借来的引用.这意味着Py_DECREF除非您实际控制了它(例如通过增加引用计数Py_INCREF),否则根本不允许您进行调用.

Python会自动垃圾收集模块引用Py_Finalize.无需采取其他行动.