Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!sun-barr!lll-winken!elroy.jpl.nasa.gov!swrinde!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!oddjob!carlo From: carlo@oddjob.uchicago.edu (Carlo Graziani) Newsgroups: comp.lang.fortran Subject: Re: IEEE exceptions Message-ID: <1991Feb27.205044.18345@midway.uchicago.edu> Date: 27 Feb 91 20:50:44 GMT References: <91963@lll-winken.LLNL.GOV> Sender: news@midway.uchicago.edu (News Administrator) Reply-To: carlo@oddjob.uchicago.edu (Carlo Graziani) Distribution: usa Organization: U of Chicago - Astronomy & Astrophysics Lines: 104 In article mcdowell@xanth.msfc.nasa.gov (Jonathan McDowell) writes: >Sun fortran lets you divide by zero and other fun things during your program >and only lets you know at the end. I actually find this quite useful as I use >the NaN (Not a Number) value (obtained by y=0./0.) as a null value for missing >data, to avoid the nastiness of using -999.9 etc. But not letting you know until > >the end of the program is silly. Hi. The following method is the one to which I have had to resort in order to track down floating point exceptions on a Sun Sparcstation. It's a bit of a kludge, but at least it allows identification of the routine within which the exception occurred, and the problem can usually be identified using dbx: program foobawooba external handler common /debug1/nlevel common /debug2/ stack(20) character stack*25 data nlevel/1/stack/'main',19*''/ ieeer=ieee_handler('set','common',handler) c 'common' handles invalid, overflow, and division exceptions --- see c "man ieee_handler". handler is an external routine shown at the end c of this example. This line will call handler whenever a 'common' c exception occurs. . . . call haha1 . . . stop end subroutine haha1 common /debug1/nlevel common /debug2/ stack(20) character stack*25 nlevel=nlevel+1 stack(nlevel)='haha1' . . . call haha2 . . . stack(nlevel)='' nlevel=nlevel-1 return end subroutine haha2 common /debug1/nlevel common /debug2/ stack(20) character stack*25 nlevel=nlevel+1 stack(nlevel)='haha2' . . . stack(nlevel)='' nlevel=nlevel-1 return end integer function handler ( sig, code, sigcontext ) common /debug1/nlevel common /debug2/ stack(20) character stack*25 integer sig integer code integer sigcontext(5) write(6,*) 'Bomb! Here comes a stack dump:' do 1 i=1,nlevel write(6,*) stack(i) 1 continue write(6,*) 'Number of levels:',nlevel call abort end The effect of all these (admittedly ugly and machine specific) gymnastics is that the routine in which the exception occurred is pinpointed by the array 'stack' and the variable 'nlevel'. Since execution is halted by means of 'call abort', all the debugging information is still available, and the problem may be identified (if the debugger was active) by examining the guilty routine. The ass paining part of all this is that the lines affecting 'stack' and 'nlevel' must be included at the beginning of every routine in the program, as well as before every return statement. I'm not that happy with it, but it's the best I've been able to do. One might wish that it would dawn on the *%&#!@!? C programmers who developed Fortran for the Sun that for the purposes of scientific programming, failure to *automatically* halt on division by zero is a bug, not a feature :-(> . Carlo Graziani.