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 */