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>