Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!sdd.hp.com!ucsd!pacbell.com!ames!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.bugs.4bsd Subject: Re: /bin/sh "longjmp botch" upon logout Message-ID: <25911@mimsy.umd.edu> Date: 6 Aug 90 14:15:39 GMT References: <1990Aug3.230130.7347@athena.mit.edu> Distribution: usa Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 65 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)