[comp.sources.bugs] "less" dumps core when you change window sizes too fast

eggert@sm.unisys.com (Paul Eggert) (10/07/88)

less version 97 dumps core if it gets too many signals too fast on my Sun-3
running SunOS 4.0, because it longjmp()s into a stack frame that no longer
exists.  Here's a fix, formatted so that line numbers don't change:


*** old/os.c	Thu Oct  6 12:22:38 1988
--- new/os.c	Thu Oct  6 12:16:03 1988
***************
*** 125,135 ****
  {
  	register int n;
  
! 	if (setjmp(read_label))
! 		/*
! 		 * We jumped here from intread.
! 		 */
  		return (READ_INTR);
  
  	flush();
  	reading = 1;
--- 125,135 ----
  {
  	register int n;
  
! 	if (setjmp(read_label)) {
! 		/* We jumped here from intread. */
! 		reading = 0;
  		return (READ_INTR);
+ 	}
  
  	flush();
  	reading = 1;


Here's a detailed scenario.

1.  iread() calls setjmp(read_label) and then read().

2.  Before typing a character, you change a window's size.

3.  The SIGWINCH interrupt calls winch(), which calls intread(), which calls
longjmp(read_label,1), which pops the C stack back to iread()'s stack frame.

4.  iread() returns READ_INTR.

5.  less starts to redraw the screen.

6.  You change the window's size again.

7.  As in step (3), the SIGWINCH interrupt calls winch(), which calls
intread(), which calls longjmp(read_label,1) -- but iread()'s stack frame
no longer exists.

8.  Core dump.


My previous attempts to send email to less's author have got no response, so
I'm posting this bug fix in the hope that he gets it.

There is at least one other bug in less's window resize event handling: less
responds incorrectly to window size changes in a SunView window when run
remotely via rlogin.  The problem is partly due to a bug in Sun's software,
which sends two SIGWINCH interrupts every time you change the window size once
in an rlogin session; but somehow 'less' mostly ignores _both_ interrupts.

-- Paul Eggert <eggert@sm.unisys.com>