brucee@runxtsa.runx.oz.au (Bruce Evans) (06/04/90)
In article <90151.170153SA44@LIVERPOOL.AC.UK> SA44@LIVERPOOL.AC.UK (Kevin Maguire) writes: > - pressed INT no joy > - pressed INT again... no joy > - banged INT a few times and waited????? no joy > - CTRL-ALT-F10 to SIGKILL all processes (I don't use half measures ;-)) > - still no joy even SIGKILL didn't work!!!!!! > - just kept banging the INT key... after a few seconds the ST just reset?? This happens when a process leader has exited but some of its children are still alive. New shells do not get a process group. The bug used to be exercised by cron. Enclosed is a simple program to demonstrate the bug, and relevant extracts from my old bug reports. The program must be run with "exec ./sigbug" and not "./sigbug" so it becomes the process group leader. #! /bin/sh # Contents: sigbug.c cron.notes # Wrapped by src@besplex on Mon Jun 4 22:44:56 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'sigbug.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sigbug.c'\" else echo shar: Extracting \"'sigbug.c'\" \(824 characters\) sed "s/^X//" >'sigbug.c' <<'END_OF_FILE' X#include <stdio.h> X Xmain() X{ X int pid; X X switch (pid = fork()) X { X case -1: X perror("cannot fork"); X exit(1); X case 0: X break; X default: X printf("Parent closing stdio and exiting.\n"); X printf("Use kill -1 %d to kill the child.\n\n", pid); X fclose(stdin); X fclose(stdout); X fclose(stderr); X exit(0); X } X sleep(2); X printf("\n\nChild sleeping for 1 hour.\n"); X printf("If the parent was a process group leader, the child has lost\n"); X printf("its process group, so is immune to signals from the keyboard.\n"); X printf("Is this right?\n\n"); X printf("While the child holds the tty open, new processes opening it\n"); X printf("are not given a process group, so are immune to signals from\n"); X printf("the keyboard.\n"); X printf("This cannot be right!\n\n"); X sleep(3600); X} END_OF_FILE if test 824 -ne `wc -c <'sigbug.c'`; then echo shar: \"'sigbug.c'\" unpacked with wrong size! fi # end of 'sigbug.c' fi if test -f 'cron.notes' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cron.notes'\" else echo shar: Extracting \"'cron.notes'\" \(2969 characters\) sed "s/^X//" >'cron.notes' <<'END_OF_FILE' Xcommands/cron.c, fs/device.c: (A TANGLED WEB) X I changed cron around 1.4.5 to fclose the standard streams X instead of closing their fileno()s, except fclose(stdout) is X commented out because later code does a printf. The fcloses X were correct for the old cron but don't do what is wanted now. X The code appears to be re-plumbing stdio so children get X /dev/null for input and LOGFILE for output and error output. X Stdio should not be trusted to do this. It would be safest for X cron not to use stdio at all. It doesn't use it for much and a X lot of space would be saved (but watch out for the new ctime - X apart from being big itself, it uses sprintf which drags in X stdio). Another way (which also saves space) is to require cron X to be started with X X cron < /dev/null > LOGFILE 2>&1 X X The printf I was worried about may actually be OK. It should X print to LOGFILE if stdout is fclosed at the start. So why do X other printfs go to cronlog? Cronlog is likely to be identical X to stdout but that is hard to guarantee. X X The killer bug in this web was that signal chars stopped X working when the version of cron without fclose(stdout) was X run. The process group handling has been broken by the line at X the start of dev_open(). Now the dmap open routine is not X called if the device is already open. Without the fclose, X /dev/tty0 stayed open. When the process group leader (the shell X interpreting /etc/rc I think) exits, the process group X variables in FS and TTY are cleared. New process groups are X supposed to be attached by the dmap open (tty_open()), but that X never gets called. X X I don't know what the correct behaviour for process groups is. X It is strange to disconnect the cron attached to /dev/tty0 just X because the leader dies. This cuts it off from signal chars to X start with. Then the next process to open the device becomes X the leader. This is a race. Maybe signal characters should not X be related to process groups, and cause signals to all X processes which have the tty open. X Xcommands/cron.c, version 1.5.6: X There are too many changes for me to understand quickly, but X the unportable combination of closes, fopens and opens is X back in full (it wasn't quite gone in 1.5.6). Why not open X everything on the command line in /etc/rc? Cron will probably X still tickle the pgrp bug in FS. I put in a hack around 1.5.2 X (of not closing everything) to try to get around this. If the X files are opened in /etc/rc, there will be no ttys involved and X the bug is sure to be avoided. It may also be worth putting the X "&" on the command line, if this avoids memory fragmentation. X BTW init might do update to save some more room (and avoid X update getting killed by Ctrl-F9 :-) and init might be taken X out of the system by doing an execl("/etc/init", ...) X somewhere. Alternatively, the system init might be tiny and do X little more that execl("/etc/init"). This saves people who X want complicated login handling from having to change the X system. END_OF_FILE if test 2969 -ne `wc -c <'cron.notes'`; then echo shar: \"'cron.notes'\" unpacked with wrong size! fi # end of 'cron.notes' fi echo shar: End of shell archive. exit 0