问题
I have Python code that works fine on my development environment (Ubuntu 12.04) but dumps core on my production environment (a Linode running CentOS).
*** 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
...
It happens frequently, but not all the time. Furthermore, if I remove *.pyc files in my libsvm subdirectory, then it seems to work without fail, but once the *.pyc files are regenerated (after the first run), it tends to dump core again.
Furthermore, if I attempt to pipe standard error to a file, it never crashes.
Some information that may be relevant:
- It only started happening when I installed Python 2.7. It wasn't happening with Python 2.6
- Python2.7 is installed into my home directory (from source, since there are no python2.7 packages for CentOS)
How should I approach this problem? Where is the problem most likely to be? Is it in the libsvm source or the Python wrapper? I'm pretty sure it's not in my Python source, since I shouldn't be able to crash the interpreter like that.
EDIT
I retrained the models on the production environment and the problem appears to have gone away. For reference, here are the diffs between the dev and production environments for both the models I'm using.
Header diff first model:
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
Header diff second model:
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
回答1:
The cause of the error is an uninitialized pointer in svm_load_model, and an unchecked call to free
. Here's a patch:
misha@misha-diginnos:~$ diff libsvm-3.16/svm.cpp.original libsvm-3.16/svm.cpp -p
*** libsvm-3.16/svm.cpp.original 2013-03-17 17:34:00.235661297 +0900
--- libsvm-3.16/svm.cpp 2013-03-17 17:39:29.677294903 +0900
*************** svm_model *svm_load_model(const char *mo
*** 2747,2752 ****
--- 2747,2753 ----
model->probB = NULL;
model->label = NULL;
model->nSV = NULL;
+ model->sv_indices = NULL;
char cmd[81];
while(1)
*************** void svm_free_model_content(svm_model* m
*** 2973,2980 ****
free(model_ptr->probB);
model_ptr->probB= NULL;
! free(model_ptr->sv_indices);
! model_ptr->sv_indices = NULL;
free(model_ptr->nSV);
model_ptr->nSV = NULL;
--- 2974,2984 ----
free(model_ptr->probB);
model_ptr->probB= NULL;
! if (model_ptr->sv_indices)
! {
! free(model_ptr->sv_indices);
! model_ptr->sv_indices = NULL;
! }
free(model_ptr->nSV);
model_ptr->nSV = NULL;
I've notified the authors. They're aware of the problem and will address it in the next version.
来源:https://stackoverflow.com/questions/15414085/python-libsvm-core-dump