實作一個功能,根據輸入的引數,每次呼叫python腳本執行函式,發現PyObject_CallObject或者Py_Finalize會出現coredump。
int search(PyObject *pDict, char* line)
{
int i = 0, j = 0, l_size = 0;
char *str;
PyObject *pFunc, *pArgs, *pRetVal, *item;
pFunc = PyDict_GetItemString(pDict, "search_str");
if ( !pFunc || !PyCallable_Check(pFunc) ) {
printf("Call python function failed\n");
return -1;
}
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "name"));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("s", line));
pRetVal = PyObject_CallObject(pFunc, pArgs);
if (PyList_Check(pRetVal)) {
l_size = PyList_Size(pRetVal);
for (j = 0; j < l_size; j++) {
item = PyList_GetItem(pRetVal, j);
PyArg_Parse(item, "s", &str);
Py_XDECREF(item);
}
}
Py_XDECREF(pRetVal);
Py_XDECREF(pArgs);
Py_XDECREF(pFunc);
return 0;
}
int main(int argc, char** argv)
{
int i;
PyObject *pModule, *pDict;
Py_Initialize();
if ( !Py_IsInitialized() ) {
printf("Init python failed.\n");
return -1;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
pModule = PyImport_Import(PyUnicode_FromString("search")); /* import search.py */
if ( !pModule ) {
printf("Can't find search.py.\n");
return -1;
}
pDict = PyModule_GetDict(pModule);
if ( !pDict ) {
printf("Getdict form python failed.\n");
return -1;
}
for (i = 1; i < argc; i++) {
search(pDict, argv[i]);
}
Py_XDECREF(pDict);
Py_XDECREF(pModule);
Py_Finalize();
return 0;
}
python腳本(search.py )
#!/usr/bin/python3
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
bucket = "xxx"
token = "xxx"
org = "xxx"
client = InfluxDBClient(url="http://localhost:8086", token=token, org=org)
write_api = client.write_api(write_options=SYNCHRONOUS)
query_api = client.query_api()
def search(db, dest_ip):
result_list = []
result_list.append("str1")
result_list.append("str2")
return result_list
程式是單執行緒跑,沒有多執行緒執行;
第一次能運行正常,輸入后第二個字串后,發生coredump,堆疊如下:
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./log_analytics'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055f8d71ac050 in search (pDict=0x7fb70bfb1480, line=0x7fffd2c0e6d0 "2.2.2.2") at log_analytics.c:31
31 if (PyList_Check(pRetVal)) {
(gdb) p pRetVal
$1 = (PyObject *) 0x0
(gdb)
這個是什么原因?代碼看起來好像沒看出什么問題。目前懷疑是因為釋放Object出現的問題。
如果注釋掉search函式中最后幾個Py_XDECREF,如下
Py_XDECREF(pRetVal);
Py_XDECREF(pArgs);
Py_XDECREF(pFunc);
程式在退出后,呼叫Py_Finalize()的時候也會發生coredump,堆疊如下:
(gdb) bt full
#0 0x0000000000000002 in ?? ()
No symbol table info available.
#1 0x00007f121e81ebff in ?? () from /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
No symbol table info available.
#2 0x00007f121e91f899 in ?? () from /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
No symbol table info available.
#3 0x00007f121e8220b5 in ?? () from /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
No symbol table info available.
#4 0x00007f121e82306d in PyGC_Collect () from /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
No symbol table info available.
#5 0x00007f121e84b763 in Py_FinalizeEx () from /usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
No symbol table info available.
#6 0x0000556a6a0b7341 in main (argc=7, argv=0x7ffc41e00588) at log_analytics.c:116
i = 7
pModule = 0x7f121ca5fe58
pDict = 0x7f121cad9480
(gdb)
這里也看不出來為什么會coredump?
Py_XDECREF這個本來就是減物件參考并且釋放的,如果這里不呼叫會有記憶體泄露吧?(看python官網說明這里是需要減物件參考的)
如果不呼叫,最后Py_Finalize釋放python解釋器怎么也會core掉?
求助各位大神幫忙看看,有沒有什么不對的地方,麻煩告訴我下。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/285150.html
上一篇:python爬取維基百科失敗,弄了半天了 求助!!!!!
下一篇:學python實戰第一天