[comp.sys.next] NeXT alloca

cpenrose@ucsd.edu (Christopher Penrose) (01/24/91)

--text follows this line--
Oh no! Not again!

Ok.  I spoke too soon.  I have discovered what appears to be a
alloca() bug within NeXT 2.0 gcc 1.36.  The problem could also be a
bug with ld, as the release notes have indicated that it was
completely overhauled.  Basically, arbitrary arrays allocated by
malloc() lose their integrity -- the addresses that malloc() provides
change without program assignment.  These bugs are very pernicious; I
have experienced them with Sun's cc.  I have a remedy; but it is not a
fix.  I will first summarize my experience.  I could have saved my
terminal session with gdb, but I really didn't feel like playing with
it anymore.  It was also extremely big.

I have several signal processing programs which share a similar
program structure.  Buffered input is read from the standard input,
processed, and output through the standard output.  After playing the
new include file dance, I managed to get most of these programs to
work.  However, one particular program, that shares most of the
functions of the others, persistently crashed from segmentation
violations.  Using gdb, I found a ridiculous integer pointer index.
It took a while to trace the index (which had worked through many
earlier iterations of the function) back to two NaN valued floats that
were obtained by the fread() function.  I checked the data fread() was
reading -- the entire segment (32 floats) were all zeros.  Of the 32,
fread() obtained two NaN values.  Also, earlier iterations of the
function successfully read buffers containing only zero valued floats.
Very scary -- how can the machine run with system call bugs like
these?  Well, it didn't take me long to conclude that UNIX could not
run with a bug in fread().  I then discovered that the memory
locations of my input array had changed mysteriously.  Anyway, this
behavior reminded me all too much of some of the games I had to play
with Sun's malloc() routines.  I had a few unused functions linked
with the program, so I removed them.  Then I grabbed my universal
malloc() remedy: space().  It saved me from the Sun malloc() hoax --
and it is painfully simple:

#define allc_min 4096

char *space( sz, obsz )
int sz, obsz;
{
    char	*p;

    if ( (sz * obsz) < allc_min ) {
	if ( (p = (char *) malloc( allc_min )) == NULL ) {
	    fprintf(stderr,"No Memory!\n");
	    exit(-1);
	}
    }
    else {
	if ( (p = (char *) malloc( sz * obsz )) == NULL ) {
	    fprintf(stderr,"No Memory!\n");
	    exit(-1);
	}
    }
    return p;
}

space() allocates memory normally if the requested size is greater or
equal to the threshold allc_min.  If the requested size is less than
allc_min, then size allc_min is allocated instead.  I tend to choose
powers of two for allc_min.  I was considering a space() function that
allocated the next power of two after size, if size were greater than
the threshold.  This was unnecessary, as this space() function
remedied the emphemeral memory hoax. 

I had hoped that I wouldn't run into these problems again.  Oh well, 
I seem to be able to live with them.
 

Christopher Penrose
jesus!penrose

cpenrose@sdcc13.ucsd.edu (Christopher Penrose) (02/01/91)

In article <15929@sdcc6.ucsd.edu> cpenrose@ucsd.edu (Christopher Penrose) writes:
>--text follows this line--
>Ok.  I spoke too soon.  I have discovered what appears to be a
>alloca() bug within NeXT 2.0 gcc 1.36.

Before I am corrected by the net, I posted this article over a week ago.
It just surfaced.  Anyway, first of all, alloca() has nothing to do
with the problems that I was having.  NeXT has added some zone features
to malloc(), and a few bugs may have crept out.  Two NeXT representatives
were very helpful as well as Scott Hess.  Thanks people!  There was one
monothink unit that kept telling me that nothing was wrong with malloc()
and that obviously my code was messed up.  I offered him the code and also
told him that the same code worked fine on my 68030 NeXT 1.0a machine,
a sparcstation, a sun 4/330, a Vax 11/780, a dec 5400 et al.  Sorry for
complaining.  I solved my problem by using a minimum malloc() size 
threshold.  My experiences with malloc_debug() indicated that my pointers
were infact getting munched beneath my program code.  Anyway, I am sure
that NeXT is working hard on improving their new malloc() features.

One more thing:  NeXT deserves applause.  I read in the release notes
that objective-c now supports runtime loading of objects.  Good work!

Christopher Penrose
jesus!penrose