From: gjm@gserv1.dl.ac.uk (g.j.milne)
Newsgroups: comp.os.os9
Subject: Re: Strange problem with setjmp()/longjmp()
Date: 3 Sep 92 09:17:32 GMT
Reply-To: gjm@gserv1.dl.ac.uk
Organization: Daresbury Laboratory, UK

In article <87473@netnews.upenn.edu> mark@ginger.biophys.upenn.edu (Mark Elliott) writes:
>	I am programming in OS-9 v2.3 and cannot get setjmp()/longjmp() to
>behave. I would like my signal handling routine to call longjmp() to branch
>to a location in my main() routine as set by setjmp(). The branch occurs, but
>shortly there after I get a Bus Trap error. The curious thing is that the
>Bus Trap error occurs a different places in the code, even in subroutines
>that have been successfully executed several times since the branch.
>	I know that this sounds like a pure programming error in my code (it
>probably is!) but I have made every attempt to figure it out. My question is:
>
>>********************************************************************************
>>Does any one out there know about some known problem/bug with setjmp()/longjmp()?
>>********************************************************************************

The problem is due to OS9 executing an F$RTE at the end of the signal
handling routine. Unlike UNIX the interrupt handling routine for an OS9
program is "special" which is why the routine uses 70 bytes on the
user's stack when it is called (registers and state information being
saved) and why it should (usually) set a flag and then return.

The OS9 technical manual states (OS9 System Calls - F$Icpt) that "the
intercept routine should be short and fast, setting a flag in the
processes's data area. Avoid complicated system calls (such I/O)". I'm
sure that most people would agree that longjmp() is a "complicated"
system call (or at least resembles one) and should not be called from
an intercept routine.

If you disassemble the intercept() function you get the following
code:

intercep            >4E550000         link.w a5,#0
_sigint+0x4         >48E76080         movem.l d1-d2/a0,-(a7)
_sigint+0x8         >41FA0012         lea.l _sigint+0x1C(pc),a0
_sigint+0xC         >2D408072         move.l d0,_srqsiz+0x4(a6)
_sigint+0x10        >6602             bne.b _sigint+0x14->
_sigint+0x12        >2040             movea.l d0,a0
_sigint+0x14        >4E400009         os9 F$Icpt
_sigint+0x18        >600000A2         bra.w _sysret
_sigint+0x1C        >2001             move.l d1,d0
_sigint+0x1E        >206E8072         movea.l _srqsiz+0x4(a6),a0
_sigint+0x22        >4E90             jsr (a0)
_sigint+0x24        >4E40001E         os9 F$RTE

Intercept() is the routine that installs the signal handling routine.
Note, the entry point to the user's routine is stored at
_srqsiz+0x4(a6).

The "real" intercept routine is entered at _sigint+0x1C. Here d1 (which
contains the signal code) is copied into d0 so that it is the first
agrument of a C routine; the stored entry point is then loaded into a0
(movea.l _srqsiz+0x4(a6),a0) and the routine jumps to that routine.
Once that routine exists, an F$RTE is executed to "fix-up" the user's
stack.

Ciao.

Gordon
S.E.R.C. Daresbury Laboratory, Warrington, WA4 4AD, United Kingdom.
e-mail     : g.j.milne@dl.ac.uk (INTERNET)  g.j.milne@uk.ac.daresbury (JANET)
Opinions expressed are my own, not necessarily those of my employer!
Newsgroups: comp.os.os9