2011-07-20 41 views
1

我想打電話給使用Py_CompileString()PyEval_EvalCode()一些Python代碼。它工作正常,但是當Python代碼包含錯誤Py_Finalize() craches。Py_Finalize()錯誤後崩潰在Python

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(); 

的輸出爲預期:

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

但隨後在調用Py_Finalize() crashes.If我改線3

PyObject* code = Py_CompileString("print('Hello World')", "", Py_file_input); 

程序運行和終止罰款程序。這裏有什麼問題?

如果我在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 
+0

你爲什麼不檢查每個步驟的結果? –

+0

我沒有檢查,因爲我認爲m&d不會改變,因爲他們沒有連接到代碼。這是真的:它們都不會返回錯誤。 –

回答

5

實際的原因,這個失敗是不是你調用Py_DECREF爲時尚早。這就是你在打電話!

PyImport_AddModule返回一個借來的參考。這意味着你不準叫Py_DECREF水平,除非你有(通過增加引用計數通過Py_INCREF例如)實際採取的控制權。

Python會自動垃圾收集Py_Finalize模塊引用。不需要額外的行動。

1
if (!r) { 
    PyErr_Print(); 
    PyErr_Clear(); 
} 

會清除錯誤並且讓你成功調用Py_Finalize()

+0

沒有代碼仍然崩潰。 –

+0

如果加上'PyErr_Print(0)會發生什麼;'後'PyErr_Print()行;'?如果這不起作用,請編輯您的帖子以提供實際的崩潰信息。 – agf

+0

'功能太多的參數'無效PyErr_Print()''。我正在運行Windows如何獲取實際崩潰信息?該程序只是關閉一個對話框「test.exe不再工作」。 –

0

好,我現在已經找到了自己的錯誤。在評估代碼並檢查錯誤之後,您只能致電Py_DECREF(m)。因此,工作程序是這樣的:

Py_Initialize(); 

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

Py_Finalize();