[gnu.emacs.bug] Problems with reading really big files

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