[comp.bugs.4bsd] /bin/sh "longjmp botch" upon logout

scs@adam.mit.edu (Steve Summit) (08/04/90)

Under some versions of the Bourne shell, the traditional logout
script, requested with

	trap '. $HOME/.eliforp; exit' 0

instead causes the shell to generate a longjmp botch, and leave
an annoying core file in whatever had been the current directory,
upon logout.  The logout script .eliforp does not execute.  I
have seen this bug come and go on various systems I've used;
strings on the one I'm using now reveals that main.c is version
4.3 from 3/19/85 and word.c is version 4.6 from 10/31/85.  (The
rest of the SCCS ID's are older, most from 1983.)

The bug is reminiscent of one I once tracked down in adb on a
Sequent Balance 8000.  The BSD-derived adb used an undocumented
and hitherto-unknown-to-me setjmp/longjmp variant (names long
since forgotten) which did the usual establish-context-at-top-
level upon startup and revert-to-it after an error.  (Why these
routines existed at all, when they appeared to be a special case
of setjmp/longjmp, is beyond me.)  The problem was that someone
at Sequent had almost-cleverly implemented this pair in terms of
setjmp and longjmp; I unwittingly pulled these "Berkeley
compatibility" routines out of Sequent's libc.a when compiling
adb.  Attractive though it may have seemed, setjmp is not a
building block out of which you can build something like setjmp.
A context-saving routine which calls setjmp to save the context
and then returns has just invalidated that context.

I mention this because something like it may be going on inside sh.

I would track this down myself except that I do not have source
access at the moment.  Has anyone else seen it or tracked it
down?  (There must be one or two sh users left in the country.)
Is it fixed in the current BSD release, indicating that I've
simply been saddled with an obsolete copy?

                                            Steve Summit
                                            scs@adam.mit.edu

chris@mimsy.umd.edu (Chris Torek) (08/06/90)

In article <1990Aug3.230130.7347@athena.mit.edu> scs@adam.mit.edu
(Steve Summit) writes:
>The bug is reminiscent of one I once tracked down in adb on a
>Sequent Balance 8000.  The BSD-derived adb used an undocumented
>and hitherto-unknown-to-me setjmp/longjmp variant (names long
>since forgotten)

`setexit' and `reset'.

>(Why these routines existed at all, when they appeared to be a
>special case of setjmp/longjmp, is beyond me.)

Age.  setjmp and longjmp were generalizations of setexit and reset
(setexit and reset do not take a `jmp_buf', so there can only be one
reset-point).

>The problem was that someone at Sequent had almost-cleverly implemented
>this pair in terms of setjmp and longjmp;

This is a remarkably popular mistake.  Setexit and reset cannot be done
as routines, because reset will then attempt to jump to a stack frame
that no longer exists:

frame	what:
depth:
-----	-----
2	foo calls setexit
3		setexit calls setjmp(static_jmpbuf)
4			setjmp saves frame 3
3		setexit returns to foo
2	foo runs for a while
2	something calls reset
3		reset calls longjmp(static_jmpbuf)
4			jump is not upward (3 is not greater than 3)
			hence is invalid
4			longjmp calls longjmperr
5				longjmperr aborts

>Attractive though it may have seemed, setjmp is not a
>building block out of which you can build something like setjmp.
>A context-saving routine which calls setjmp to save the context
>and then returns has just invalidated that context.

(right)

>I mention this because something like it may be going on inside sh.

No, this is a different problem.  sh's `.' command is failing (`no
such file or directory') and sh is doing a longjmp to a removed frame.
main() calls done() which calls execexp() which calls execute() which
calls failed() which calls exitsh() which decides the shell is (still)
interactive and calls longjmp to return to a routine which has already
returned to main().

The simplest fix is probably to add

	flag &= ~ttyflg;

to done() before it calls execute().


-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris
	(New campus phone system, active sometime soon: +1 301 405 2750)