grossman@polya.Stanford.EDU (Stu Grossman) (03/28/89)
Symptom: Try reading a really big file (~15mb or so) under any BSD derivative Unix. You get the message 'Memory exhausted', and then emacs hangs. Even ^G won't bring it back to life! Diagnosis: Failure from sbrk() not handled properly in morecore (malloc.c). In particular, the signal mask is not being restored upon exit from morecore(). Cure: Restore the signal mask before doing the return after a failing sbrk(). Also, ensure that some variables are altered only when sbrk() succeeds. I also excluded SIGILL from the signal mask, as it somehow seemed to interfere with gdb. *** malloc.c.orig Mon Feb 13 02:37:16 1989 --- malloc.c Tue Mar 28 00:03:02 1989 *************** *** 317,323 **** #ifdef BSD #ifndef BSD4_1 ! oldmask = sigsetmask (-1); #endif #endif --- 317,323 ---- #ifdef BSD #ifndef BSD4_1 ! oldmask = sigsetmask (-1 & ~(1 << SIGILL)); /* Don't touch SIGILL. Keeps gdb happy. */ #endif #endif *************** *** 343,350 **** */ cp = sbrk (0); siz = cp - data_space_start; - malloc_sbrk_used = siz; - malloc_sbrk_unused = lim_data - siz; if (warnfunction) switch (warnlevel) --- 343,348 ---- *************** *** 383,389 **** nblks = 1 << ((siz = 8) - nu); if ((cp = sbrk (1 << (siz + 3))) == (char *) -1) ! return; /* no more room! */ #ifndef VMS if ((int) cp & 7) { /* shouldn't happen, but just in case */ --- 381,398 ---- nblks = 1 << ((siz = 8) - nu); if ((cp = sbrk (1 << (siz + 3))) == (char *) -1) ! { /* no more room! */ ! #ifdef BSD ! #ifndef BSD4_1 ! sigsetmask (oldmask); /* Restore signals */ ! #endif ! #endif ! return; /* And give up */ ! } ! ! malloc_sbrk_used = siz; ! malloc_sbrk_unused = lim_data - siz; ! #ifndef VMS if ((int) cp & 7) { /* shouldn't happen, but just in case */