[Numpy-discussion] segfault in Numpy esxtension

Kragen Sitaker kragen at pobox.com
Sat Apr 13 00:25:01 EDT 2002

(All of the below is with regard to Numeric 20.2.0.)

For a consulting client, I wrote a extension module that does the
equivalent of sum(take(a, b)), but without the temporary result in
between.  I was surprised that when I tried to .resize() the result of
this routine, I got a segmentation fault and a core dump.

It was crashing at this line in arrayobject.c:
	if (memcmp(self->descr->zero, all_zero, elsize) == 0) {

self->descr, in this case, was the type description for arrays of type
"double".  It seems that self->descr->zero was 0, as in a null
pointer, not a pointer to a location containing (double)0, and this
was causing it to crash.

It looks like the .zero fields of the type descriptions (which live in
arraytypes.c and _numpy.so) are initialized to be null pointers, and
only when the initmultiarray() function in multiarraymodule.c is run
are these pointers set to point to actual zeroes somewhere in
allocated memory.

I guess Numeric.py imports multiarray.so, which calls
initmultiarray(), so the solution for me was to make sure I import
Numeric before importing my module (or at least before resizing arrays
produced by my module).  But, to my mind, this segfault is a bug ---
importing a module that follows all the rules shouldn't put Python in
a state that's so dangerously inconsistent that innocent things like
.resize() can crash it.  Maybe the same .so file that includes the
actual data items should be responsible for initializing them ---
especially since import_array() imports _numpy without importing
multiarray.  (I assume there's a reason it wasn't done this way in the
first place.)  What do other people think?

/* By Kragen Sitaker, http://pobox.com/~kragen/puzzle4.html */
char b[2][10000],*s,*t=b,*d,*e=b+1,**p;main(int c,char**v){int n=atoi(v[1]);
strcpy(d,*p+2);d+=strlen(d);goto x;}*d++=*s;x:}s=t;t=e;e=s;*d++=0;}puts(t);}

More information about the NumPy-Discussion mailing list