segmentation fault - core dump in python C-extension -


i writing c-extension python. can see below, aim of code calculate euclidean-dist of 2 vectors. first param n dimension of vectors, second , third param 2 list of float.

i call function in python this:

import cutil cutil.c_euclidean_dist(2,[1.0,1,0],[0,0]) 

and worked well, return right result. if more 100 times(the dimension 1*1000), cause segmentation fault - core dump:

#!/usr/bin/env python #coding:utf-8 import cutil import science import time = [] b = [] d = 0.0  x in range(2500):     a.append([float(i+x) in range(1000)])     b.append([float(i-x) in range(1000)])  t1 = time.time() x in range(500):     d += cutil.c_euclidean_dist(1000,a[x],b[x]) print time.time() - t1 print d 

the c code here:

#include <python2.7/python.h> #include <math.h>  static pyobject* cutil_euclidean_dist(pyobject* self, pyobject* args) {     pyobject *seq_a, *seq_b;     int n;     float * array_a,* array_b;     pyobject *item;      pyarg_parsetuple(args,"ioo", &n , &seq_a, &seq_b);     if (!pysequence_check(seq_a) || !pysequence_check(seq_b)) {        pyerr_setstring(pyexc_typeerror, "expected sequence");        return null;     }      array_a =(float *)malloc(sizeof(float)*n);     array_b =(float *)malloc(sizeof(float)*n);        if (null == array_a || null == array_b){         pyerr_setstring(pyexc_typeerror, "malloc failed!");         py_decref(seq_a);         py_decref(seq_b);         return null;     }      int i;     for(i=0;i<n;i++){         item = pysequence_getitem(seq_a,i);          if (!pyfloat_check(item)) {             free(array_a);  /* free memory before leaving */             free(array_b);             py_decref(seq_a);             py_decref(seq_b);             py_decref(item);             pyerr_setstring(pyexc_typeerror, "expected sequence of float");             return null;         }         array_a[i] = pyfloat_asdouble(item);          py_decref(item);          item = pysequence_getitem(seq_b,i);         if(!pyfloat_check(item)) {             free(array_a);             free(array_b);             py_decref(seq_a);             py_decref(seq_b);             py_decref(item);             pyerr_setstring(pyexc_typeerror, "expected sequence of float");              return null;         }         array_b[i] = pyfloat_asdouble(item);         py_decref(item);     }      double sum = 0;     for(i=0;i<n;i++){         double delta = array_a[i] - array_b[i];         sum += delta * delta;     }      free(array_a);     free(array_b);     py_decref(seq_a);     py_decref(seq_b);      return py_buildvalue("d",sqrt(sum)); }  static pymethoddef cutil_methods[] = {     {"c_euclidean_dist",(pycfunction)cutil_euclidean_dist,meth_varargs,null},     {null,null,0,null} };  pymodinit_func initcutil(void) {     py_initmodule3("cutil", cutil_methods, "liurui's c extension python"); }  

the error msg:

segmentation fault - core dump: 

the c-extension compiled cutil.so, not know how see dump. looked through c code many times,and can not find problem..

may a memory problem?

it should simple piece of c code, what's wrong it? need help~ lot !

here result of gdb /usr/bin/python2.7 ./core:

root@ubuntu:/home/rrg/workspace/opencvtest/test# gdb /usr/bin/python2.7 ./core  gnu gdb (ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 copyright (c) 2014 free software foundation, inc. license gplv3+: gnu gpl version 3 or later <http://gnu.org/licenses/gpl.html> free software: free change , redistribute it. there no warranty, extent permitted law.  type "show copying" , "show warranty" details. gdb configured "x86_64-linux-gnu". type "show configuration" configuration details. bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. find gdb manual , other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. help, type "help". type "apropos word" search commands related "word"... reading symbols /usr/bin/python2.7...reading symbols /usr/lib/debug//usr/bin/python2.7...done. done.  warning: core file may not match specified executable file. [new lwp 13787] [new lwp 13789] [new lwp 13790] [thread debugging using libthread_db enabled] using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". core generated `python py.py'. program terminated signal sigsegv, segmentation fault. #0  0x00000000005398b3 in list_dealloc.16846 (op=0x7f688b2faa28) @ ../objects/listobject.c:309 309 ../objects/listobject.c: no such file or directory #0  0x00000000005398b3 in list_dealloc.16846 (op=0x7f688b2faa28) @ ../objects/listobject.c:309 #1  0x00000000004fdb96 in insertdict_by_entry (value=<optimized out>, ep=0x1777fa8, hash=<optimized out>, key='b', mp=0x7f68a8dbb168) @ ../objects/dictobject.c:519 #2  insertdict (value=<optimized out>, hash=<optimized out>, key='b', mp=0x7f68a8dbb168) @ ../objects/dictobject.c:556 #3  dict_set_item_by_hash_or_entry (value=<optimized out>, ep=0x0, hash=<optimized out>, key='b',      op={'a': none, 'x': none, 'c': none, 'b': none, 'd': <float @ remote 0x4480b30>, '__builtins__': <module @ remote 0x7f68a8de6b08>, 'science': <module @ remote 0x7f68a8ce4088>, '__package__': none, 'i': 999, 'cutil': <module @ remote 0x7f68a8cdfbb0>, 'time': <module @ remote 0x7f68a640ea28>, '__name__': '__main__', 't1': <float @ remote 0xd012708>, '__doc__': none}) @ ../objects/dictobject.c:765 #4  pydict_setitem (     op=op@entry={'a': none, 'x': none, 'c': none, 'b': none, 'd': <float @ remote 0x4480b30>, '__builtins__': <module @ remote 0x7f68a8de6b08>, 'science': <module @ remote 0x7f68a8ce4088>, '__package__': none, 'i': 999, 'cutil': <module @ remote 0x7f68a8cdfbb0>, 'time': <module @ remote 0x7f68a640ea28>, '__name__': '__main__', 't1': <float @ remote 0xd012708>, '__doc__': none}, key=key@entry='b',      value=<optimized out>) @ ../objects/dictobject.c:818 #5  0x000000000055a9e1 in _pymodule_clear (m=<optimized out>) @ ../objects/moduleobject.c:139 #6  0x00000000004f2ad4 in pyimport_cleanup () @ ../python/import.c:473 #7  0x000000000042fa89 in py_finalize () @ ../python/pythonrun.c:459 #8  0x000000000046ac10 in py_main (argc=<optimized out>, argv=0x7fff3958d058) @ ../modules/main.c:665 #9  0x00007f68a8665ec5 in __libc_start_main (main=0x46ac3f <main>, argc=2, argv=0x7fff3958d058, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff3958d048)     @ libc-start.c:287 #10 0x000000000057497e in _start () 

edit: comment last 2 sentences near last return:

py_decref(seq_a); py_decref(seq_b);   

and seems work well. feel very strange... purpose of 2 sentence free(or release) 2 pyobject, why works without 2 sentences think necessary?

the c-extension compiled cutil.so, not know how see dump.

to solve this, i'm going cite gnu radio's gdb/python debugging mini-tutorial:

luckily, there's feature called core dumping allows state of program stored in file, allowing later analysis. usually, feature disabled; can enable by:

ulimit -c unlimited 

note works processes spawned shell used ulimit in. happens here maximum size of core dump set unlimited (the original value 0 in cases).

now, core dump file lays in current execution directory of program crashed. in our case, that's build/python/, since core dumps should have name core., can use little find magic:

marcus> find -type f -cmin 5 -name 'core.[0-9]*' 

./build/python/core.22608

because find _f_iles, changed/created within last _5 min_utes, having name matches.

using gdb core dump

having found build/python/core.22608, can launch gdb:

gdb programname coredump 

i.e.

gdb /usr/bin/python2 build/python/core.22608 

a lot of information might scroll by.

at end, you're greeted gdb prompt:

(gdb)  

getting backtrace

typically, you'd backtrace (or shorter, bt). backtrace hierarchy of functions called.

 (gdb)bt 

[...] skipped,

frame #2 , following they're part of python implementation -- sounds bad, because gdb doesn't know how debug python, luckily, there's extension that. can try use py-bt:

(gdb) py-bt 

if undefined command error, must stop here , make sure python development package installed (python-devel on redhatoids, python2.7-dev on debianoids); systems, should append content of /usr/share/doc/{python-devel,python2.7-dev}/gdbinit[.gz] ~/.gdbinit, , re-start gdb.

the output of py-bt states python lines correspond stack frame (skipping stack frames hidden python, because in external libraries or python-implementation routines)

...


Comments

Popular posts from this blog

c# - SharpSsh Command Execution -

python - Specify path of savefig with pylab or matplotlib -

How to run C# code using mono without Xamarin in Android? -