From LISTSERV.FUNET.FI!owner-ixemul Sun Aug 20 10:12:00 1995
Return-Path: <owner-ixemul@LISTSERV.FUNET.FI>
Received: from ciistr1.ist.utl.pt by amigalib.com with smtp
	(Smail3.1.28.1 #64) id m0skB6T-0004nYC; Sun, 20 Aug 95 10:11 EDT
Received: from fiport.funet.fi by ciistr1.ist.utl.pt; (5.65v3.0/1.1.8.2/24Jul95-0207PM)
	id AA00496; Sun, 20 Aug 1995 16:10:04 GMT
Received: from LISTSERV.FUNET.FI (LISTSERV@FIPORT)
 by FIPORT.FUNET.FI (PMDF V5.0-3 #2494)
 id <01HUAY3U6Y4W000BOX@FIPORT.FUNET.FI>; Sun, 20 Aug 1995 17:11:20 +0200 (EET)
Received: from LISTSERV.FUNET.FI by LISTSERV.FUNET.FI (LISTSERV release 1.8b)
 with NJE id 2864 for IXEMUL@LISTSERV.FUNET.FI; Sun, 20 Aug 1995 17:11:17 +0200
Received: from sun4nl.NL.net by FIPORT.FUNET.FI (PMDF V5.0-3 #2494)
 id <01HUAY3MWYA8000EDN@FIPORT.FUNET.FI> for ixemul@listserv; Sun,
 20 Aug 1995 17:11:15 +0200 (EET)
Received: from hgatenl by sun4nl.NL.net via EUnet id AA24213 (5.65b/CWI-3.3)
 ; Sun, 20 Aug 1995 16:10:17 +0200
Received: from wyst.hobby.nl by hgatenl.hobby.nl with uucp (Smail3.1.28.1 #11)
 id m0skAVB-000FaHC; Sun, 20 Aug 1995 15:33 +0100 (MET)
Received: by wyst.hobby.nl (V1.17-beta/Amiga) id <08v4@wyst.hobby.nl>; Sun,
 20 Aug 1995 11:34:12 +0100 (CET)
Date: Sun, 20 Aug 1995 11:34:10 +0000
From: Hans Verkuil <hans@wyst.hobby.nl>
Subject: Fixed bug in execve.c, resident make now works
Sender: OWNER-IXEMUL@LISTSERV.FUNET.FI
To: Multiple recipients of list IXEMUL <IXEMUL@LISTSERV.FUNET.FI>
Reply-To: "Amigados ixemul.library; library development discussion"
 <IXEMUL@LISTSERV.FUNET.FI>
Message-Id: <9508201034.08v4@wyst.hobby.nl>
Content-Type: text
Content-Transfer-Encoding: 7BIT
Comments: To: fnf@amigalib.com
Status: RO

Hi all,

By applying the patch below to ixemul-41.1/stdlib/execve.c a serious bug
involving the signal handling is fixed. This bug is the reason why a make
that was compiled with -resident would cause bus errors.

Given the following makefile:

        a.o:    a.c
                echo >a.o

'make' parses the makefile and discovers that it should execute the command
'/bin/sh -c "echo >a.o"'.

'make' installs a signal handler for the SIGCHLD signal. Then it vforks and
uses execve to start '/bin/sh -c "echo >a.o"' to handle the current
command. The vfork'ed make inherits the signal handler from its parent.
execve resets several things, but NOT the signal handler array!

So the shell also vfork's, does execve for 'echo', 'echo' runs OK, and when
'echo' is finished a SIGCHLD signal is send to the parent (that is the
shell started by the vfork'ed make). Note that the shell has NO signal
handler for SIGCHLD installed. Now the ixemul.library starts to handle
the signal, sees a valid signal handler and calls that handler. However,
the handler is still the handler from 'make', which was never reset. It
should have been the default handler SIG_DFL.  Instead, it calls the make
signal handler.

This means that a make compiled non-resident receives TWO SIGCHLD signals,
one spurious, one real (when the shell started from make ends). This is
fairly harmless, at least in this case. A resident make, however, is in
trouble: just before calling the handler, the ixemul library sets the a4
register, which belongs to the process whose handler will be called, to let
the handler access its base-relative data.  However, the library thinks the
handler was installed by the shell, but in fact it was installed by make.
Therefore a4 is filled with the wrong value (namely, the one for the
shell). The signal handler is called and it tries to access a variable that
is part of 'make' using an a4 base address that really is the base address
from the shell. That address is invalid and a bus error is generated.

Luckily the patch is very simple: just reset all handlers to SIG_DFL in
execve.

Note that this specific case fails on the SIGCHLD signal, but this bug
involves *all* signals.  Maybe this patch will also fix occasional problems
with ^C. Again, this bug means that signal handlers may be called
spuriously whether or not the programs involved were compiled resident.
Because of the a4 problem it just crashes sooner when using resident
programs.

A final note: the comment after the line 'u.p_sigcatch = 0;' suggests that
this is sufficient to reset all handlers to SIG_DLF. This is not true, the
handlers themselves also need to be reset.

It took me several days in the course of several weeks to debug, donations
are welcome :-)

                                        Hans

------------- cut here ----------
*** e.c Sun Aug 20 10:39:44 1995
--- execve.c    Sun Aug 20 10:40:16 1995
***************
*** 285,288 ****
--- 285,289 ----
    u.u_sigintr    = 0; /* default = don't interrupt syscalls */
    u.p_sigcatch   = 0; /* no signals caught by user -> SIG_DFL */
+   memset(&u.u_signal[0], 0, sizeof(u.u_signal)); /* reset signalhandlers to SIG_DFL */

    /* what happens when we execute execve() from a signal handler
------------- cut here ----------


--
 Hans Verkuil, Frederik van Eedenplaats 185, 2902 VD  Capelle a/d IJssel,
      The Netherlands -- Tel: 010-4585745, email: hans@wyst.hobby.nl

"...and the princesses were beautiful as the day is long and so noble they
 could pee through a dozen mattresses --"                (Terry Pratchett)

