我有一段Python代码在我的开发环境(Ubuntu 12.04)上可以正常工作,但在我的生产环境(运行CentOS的Linode)上却会发生内存崩溃。
*** glibc detected *** python2.7: double free or corruption (out): 0x090cba60 ***
======= Backtrace: =========
/lib/i686/nosegneg/libc.so.6(+0x717b1)[0xb763d7b1]
/lib/i686/nosegneg/libc.so.6(+0x73f01)[0xb763ff01]
/home/michael/libsvm-3.16/python/../libsvm.so.2(svm_free_model_content+0xe2)[0xb6e0c6b2]
/home/michael/libsvm-3.16/python/../libsvm.so.2(svm_free_and_destroy_model+0x2c)[0xb6e0c70c]
/home/michael/lib/python2.7/lib-dynload/_ctypes.so(ffi_call_SYSV+0x17)[0xb71e375f]
/home/michael/lib/python2.7/lib-dynload/_ctypes.so(ffi_call+0x5b)[0xb71e35ab]
/home/michael/lib/python2.7/lib-dynload/_ctypes.so(_ctypes_callproc+0x32d)[0xb71d82ad]
/home/michael/lib/python2.7/lib-dynload/_ctypes.so(+0x703e)[0xb71d003e]
python2.7(PyObject_Call+0x4a)[0x805d90a]
python2.7(PyEval_EvalFrameEx+0x3c0a)[0x80e04ba]
python2.7(PyEval_EvalCodeEx+0x7bb)[0x80e2c1b]
python2.7[0x813ee2a]
python2.7(PyObject_Call+0x4a)[0x805d90a]
python2.7[0x80657f1]
python2.7(PyObject_Call+0x4a)[0x805d90a]
python2.7(PyEval_CallObjectWithKeywords+0x42)[0x80db852]
python2.7[0x80af616]
python2.7[0x80a928e]
python2.7[0x808e024]
python2.7[0x8067c5b]
python2.7[0x808c079]
python2.7(PyDict_SetItem+0x87)[0x808cfa7]
python2.7(_PyModule_Clear+0x123)[0x8090693]
python2.7(PyImport_Cleanup+0x175)[0x80f2ca5]
python2.7(Py_Finalize+0x10c)[0x80ffacc]
python2.7(Py_Main+0x53d)[0x8058c1d]
python2.7(main+0x1b)[0x805839b]
/lib/i686/nosegneg/libc.so.6(__libc_start_main+0xe6)[0xb75e2ce6]
python2.7[0x80582e1]
======= Memory map: ========
08048000-0817d000 r-xp 00000000 ca:00 430104 /home/michael/bin/python2.7
0817d000-081ab000 rw-p 00134000 ca:00 430104 /home/michael/bin/python2.7
081ab000-081b4000 rw-p 00000000 00:00 0
...
这种情况经常发生,但并非总是如此。此外,如果我删除libsvm子目录中的*.pyc文件,则似乎可以无故障运行,但一旦重新生成*.pyc文件(在第一次运行后),它倾向于再次崩溃。
此外,如果我尝试将标准错误输出到文件中,则永远不会崩溃。
以下是一些可能相关的信息:
- 安装Python 2.7后才出现该问题。在Python 2.6中没有出现过。 - Python2.7安装在我的主目录中(从源代码安装,因为CentOS没有python2.7软件包)。
我应该如何解决这个问题?问题最可能出现在哪里?是在libsvm源代码中还是在Python包装器中?我相当确定不是在我的Python源代码中,因为我不应该能够导致解释器像那样崩溃。
编辑:我在生产环境上重新训练了模型,问题似乎已经消失了。供参考,以下是我正在使用的两个模型在开发和生产环境之间的差异。
第一个模型的头文件差异:
4,7c4,7
< total_sv 8858
< rho -0.500251 -0.215012 2.99972 -0.00159202 0.000223509 1.00003
< label 3 2 1 0
< nr_sv 549 6095 587 1627
---
> total_sv 8782
> rho -2.99981 0.000329574 -1.00015 -0.335094 -0.999424 -0.66958
> label 0 3 2 1
> nr_sv 1586 535 6083 578
-bash-4.1$ diff model.svm model2.svm | head -n 20
4,7c4,7
< total_sv 8858
< rho -0.500251 -0.215012 2.99972 -0.00159202 0.000223509 1.00003
< label 3 2 1 0
< nr_sv 549 6095 587 1627
标题差异第二模型:
4,7c4,7
< total_sv 116
< rho 2.30068 -0.145028 0.169511 -1.09344 0.723723 -0.865381
< label 3 0 2 1
< nr_sv 18 32 34 32
---
> total_sv 132
> rho 0.72381 -2.00473 -0.220492 -0.962109 0.998243 -0.14499
> label 0 1 3 2
> nr_sv 43 35 18 36
svm_free_model_content
函数,你会发现它有两个保护条件:if(model_ptr->free_sv && model_ptr->l > 0 && model_ptr->SV != NULL)
和if(model_ptr->sv_coef)
,这让我认为你实际上有一个不一致的svm_model
传递到了这个函数中,而这个svm_model
并不是NULL,因为svm_free_and_destroy_model
检查了这种情况。在崩溃之前,你是否得到了预期的预测结果,或者是在其他地方崩溃了? - Mihai Todor