Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!ima!imd!david From: david@imd.UUCP Newsgroups: net.lang.c Subject: Re: setjmp/longjmp Message-ID: <1@imd.UUCP> Date: Thu, 1-Nov-84 00:28:15 EST Article-I.D.: imd.1 Posted: Thu Nov 1 00:28:15 1984 Date-Received: Fri, 2-Nov-84 05:08:36 EST Lines: 100 Nf-ID: #R:decwrl:-399400:imd:3300001:000:4276 Nf-From: imd!david Oct 31 01:24:00 1984 >***** imd:net.lang.c / brl-tgr!gwyn / 9:56 am Oct 30, 1984 >I agree with Dennis Ritchie that longjmp should resume after the call >to setjmp with all accessible data containing values as of the time of >the longjmp. This can always be implemented, although some C run-time >designs seem to have not saved enough information on the call stack to >support longjmp. Such implementations need to be changed. Any system >where a subroutine call saves all the non-scratch registers (e.g., PDP-11, >Gould) is in good shape, as is any system where the number of registers >actually saved is recorded in the call frame (e.g. VAX). Other systems >may have to have their calling sequences re-engineered, but that is what >they deserve for taking shortcuts. Perhaps setjmp/longjmp can always be implemented. However its correct implementation is at the expense of performance. However, I would disagree that the "pdp-11 is in good shape". Either it works 100% of the time, or it should not be relied on. The following bugs indicate to me that it would be a lot of work to get setjmp/longjmp to work ALL THE TIME on the pdp11. The following code shows a problem with setjmp/longjmp in that if a routine does not follow proper register saving conventions, then longjmp cannot know that a register was saved temporarily. Our (system 3, I believe) ritchie pdp11 C compiler (C rel 2.3; UTS rel 1.3) generates a push and restore of register 2 around structure copies. If a longjmp is needed during the structure copy, longjmp will have no idea that this register was temporarily used for the structure copy. In the following code, the register variables are set to -1, and never used. Hence after a longjmp, they should all be -1. However, longjmp does not realize that register 2 was saved on the stack for the structure copy (as it was not done via csav). Hence, when the longjmp occurs, register variable 'k' is restored to an incorrect value (which I believe is the number of words left for the structure copy). [Note that the following code works correctly with a pdp11 pcc compiler, but fails with the ritchie compiler, since the code that pcc is generating is so silly]. struct { char array[16000]; } astruct, bstruct; int jmpbuf[32]; int alarmrtn (); main () { register int i, j, k; for (;;) { i = j = k = -1; /* set all register vars to -1. */ if (setjmp (jmpbuf) == 0) break; printf ("i = %d, j = %d, k = %d\n", i, j, k); } signal (14, alarmrtn); /* cause longjmp after 1 second. */ alarm (1); /* set alarm higher for a busy */ for (;;) /* system to be sure gets into loop.*/ astruct = bstruct; /* structure copy of 16000 bytes. */ } alarmrtn () { longjmp (jmpbuf, 1); } A similar problem occurs in libc.a or other assembly language routines that do not use proper csav subroutine linkage. For example our Strncmp(3) in libc.a [which may not be the distributed strncmp] is written in assembler, and again saves and restores register 2. However, even if one fixes these problems, one has to fix csav! Our csav is setting up a new frame (r5) prior to saving the registers, hence if one longjmps from an intr/alarm from 2 instructions inside csav, [easiest way is with a debugger] all register variables get clobbered! Also, it is possible on the pdp11 to leave the floating point in the wrong int/long (seti/setl) mode after a longjmp. This is probably worse than registers getting clobbered. This can be caused by a similar longjmp occuring during an intr/alarm of the C code: long = double; This bug can give core dumps! Unfortunately, the obvious fix requires putting in floating point into programs that have setjmp, even if they do not use floating point. [Which may break "ed" on pdp's without floating point when one hits ]. So, even though I use setjmp/longjmp when I have to, didn't your mother ever tell you to stay away from setjmps/longjmps? :-) These views are my own, and are probably wrong! David Marx ima!imd!david