home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sys / atari / st / tech / 4455 < prev    next >
Encoding:
Text File  |  1992-08-17  |  9.0 KB  |  236 lines

  1. Newsgroups: comp.sys.atari.st.tech
  2. Path: sparky!uunet!mnemosyne.cs.du.edu!nyx!ilepore
  3. From: ilepore@nyx.cs.du.edu (Ian Lepore)
  4. Subject: Re: Using Setexec() [a bit of help needed]
  5. Message-ID: <1992Aug18.002702.7663@mnemosyne.cs.du.edu>
  6. Sender: usenet@mnemosyne.cs.du.edu (netnews admin account)
  7. Organization: University of Denver, Dept. of Math & Comp. Sci.
  8. References: <1992Aug17.083005.6390@aber.ac.uk>
  9. Date: Tue, 18 Aug 92 00:27:02 GMT
  10. Lines: 224
  11.  
  12. Organization: Nyx, Public Access Unix at U. of Denver Math/CS dept.
  13. X-Disclaimer: Nyx is a public access Unix system run by the University
  14.     of Denver for the Denver community.  The University has neither
  15.     control over nor responsibility for the opinions of users.
  16.  
  17.  Using your example code, your call to set the interupt s/b:
  18.  
  19.    Setexc(2, BusError);
  20.  
  21.  But, since BusError() appears later in the code, you'll also need to add
  22. an "extern void BusError();" before the Setexc() call, or move the BusError()
  23. routine earlier in your code.  That handles the C-syntax part of your 
  24. question, but the full answer is longer...
  25.  
  26.  Depending on your compiler (you didn't say which one you're using), you
  27. may need to declare BusError() using a keyword such as _interupt.  If your
  28. compiler doesn't support that keyword, there's a good chance you won't be
  29. able to write the BusError() routine in C.  When the routine gets control,
  30. the machine will be in supervisor mode.  Trying to use printf() in supervisor
  31. mode will probably lead to a crash.
  32.  
  33.  The best fix is to use signal(SIGSEGV, handler_function) if your library 
  34. includes a signal-handling system.  If it doesn't, here's some assembler
  35. code which you should be able to adapt to your purposes:
  36.  
  37. ----------- cut here ----------------
  38. ;*************************************************************************
  39. ;*
  40. ;* EXHANDLR.S - Machine exception handler.
  41. ;*
  42. ;*  This module hooks exception vectors 2, 3, 4, 5, 8, and 102 to catch ^C,
  43. ;*  null pointer de-referencing, and so on.  When an exception occurs, the
  44. ;*  handler routine cleans the exception info off the supervisor stack,
  45. ;*  forces the machine back to user mode, and does a longjmp() through
  46. ;*  the jump buffer specified during the init call.
  47. ;*
  48. ;*  This code can be assembled with MadMac or Sozobon's JAS.  
  49. ;*
  50. ;*  Typical usage is:
  51. ;*
  52. ;*  RESTART_PROGRAM:
  53. ;*
  54. ;*      if (0 != (exception = setjmp(exception_handler))) {
  55. ;*          exh_remove_handler();   /* prevent ugly recursions */
  56. ;*         if (exception > 0)
  57. ;*             printf("Exception %d has been handled.\n", exception);
  58. ;*          else
  59. ;*             printf("Process termination has been handled.\n");
  60. ;*          goto RESTART_PROGRAM;   /* or exit() or Pterm() here */
  61. ;*      }
  62. ;*      exh_init_handler(exception_handler);
  63. ;*
  64. ;*  The salient points are to install the setjmp() before the init_handler
  65. ;*  call, and to be sure and remove the handler as the first thing right
  66. ;*  after a return from longjump, to prevent recursion if another exception
  67. ;*  happens while you're handling the first exception.  If you are going
  68. ;*  to take some restart action instead of terminating the program during
  69. ;*  exception handling, be sure to re-install the setjmp() and the 
  70. ;*  exception handler before getting into your main logic again.
  71. ;*
  72. ;*  Remember that the processor termination handler catches ALL 
  73. ;*  terminations, not just ^C, so if your program has exit() calls all
  74. ;*  over the place, plan to get control if one of them is used to exit
  75. ;*  the program.  As of now, I don't know of a good way of catching only
  76. ;*  ^C terminations but not exit() terminations.  (Other than replacing
  77. ;*  your library exit() routine with something that removes the handlers
  78. ;*  and then continues by calling _exit().  Not all libraries support a
  79. ;*  two-tiered exit/_exit system, dLibs does.)
  80. ;*************************************************************************
  81.  
  82.         .globl  _exh_init_handler       ;* export our name
  83.         .globl  _exh_remove_handler     ;* export our name
  84.         .globl  _longjmp                ;* import name of library routine
  85.  
  86.         .bss
  87.  
  88. oldex2:    .ds.l 1               ;* old exception vector 2 contents
  89. oldex3:    .ds.l 1               ;* old exception vector 3 contents
  90. oldex4:    .ds.l 1               ;* old exception vector 4 contents
  91. oldex5:    .ds.l 1               ;* old exception vector 5 contents
  92. oldex8:    .ds.l 1               ;* old exception vector 8 contents
  93. oldex102:  .ds.l 1               ;* old exception vector 102 contents
  94. ex_jmpbuf: .ds.l 1               ;* pointer to jmp_buf for longjmp
  95.  
  96.         .text
  97.  
  98. ;*****************************************************************************
  99. ;* the exception handlers...
  100. ;*****************************************************************************
  101.  
  102. newex2:                             ;* Exception 2 - address error
  103.         moveq.l #2,d0
  104.         addq.l  #8,sp               ;* (clean extra 8 bytes off the stack)
  105.         bra.b   cleanex
  106. newex3:                             ;* Exception 3 - bus error
  107.         moveq.l #3,d0
  108.         addq.l  #8,sp               ;* (clean extra 8 bytes off the stack)
  109.         bra.b   cleanex
  110.  
  111. newex4:                             ;* Exception 4 - illegal instruction
  112.         moveq.l #4,d0
  113.         bra.b   cleanex
  114.  
  115. newex5:                             ;* Exception 5 - divide by zero
  116.         moveq.l #5,d0
  117.         bra.b   cleanex
  118.  
  119. newex8:                             ;* Exception 8 - privilege violation
  120.         moveq.l #8,d0
  121.         bra.b   cleanex
  122.  
  123. newex102:                           ;* Exception 102 - ^C (Pterm) handler
  124.         move.w  #-32,d0             ;* (DOS uses -32 for a ^C return code,
  125.         bra.b   do_ljump            ;* so we'll do the same.)
  126.  
  127. cleanex:
  128.         addq.l  #6,sp               ;* Remove exception SR and PC,
  129. do_ljump:
  130. ;*      and.w   #$DFFF,sr           ;* force machine back to user mode.
  131.         .dc.w   $027C               ;* JAS doesn't understand the SR reg...
  132.         .dc.w   $DFFF               ;* these two lines are AND.W #$DFFF,SR
  133.         move.w  d0,-(sp)            ;* Stack exception code.
  134.         move.l  ex_jmpbuf,-(sp)     ;* Stack address of jump buffer.
  135.         jsr     _longjmp            ;* Execute longjmp() function.
  136.  
  137. ;*****************************************************************************
  138. ;* the init routine, installs handlers...
  139. ;*****************************************************************************
  140.  
  141. _exh_init_handler:
  142.  
  143.         move.l  4(sp),d0
  144.         beq     punt
  145.         move.l  d0,ex_jmpbuf
  146.  
  147.         pea     newex2
  148.         move.l  #$00050002,-(sp)
  149.         trap    #13                 ;* Setexc(2,&newex2)
  150.         addq.l  #8,sp
  151.         move.l  d0,oldex2           ;* Save old vector.
  152.  
  153.         pea     newex3
  154.         move.l  #$00050003,-(sp)
  155.         trap    #13                 ;* Setexc(3,&newex3)
  156.         addq.l  #8,sp
  157.         move.l  d0,oldex3           ;* Save old vector.
  158.  
  159.         pea     newex4
  160.         move.l  #$00050004,-(sp)
  161.         trap    #13                 ;* Setexc(4,&newex4)
  162.         addq.l  #8,sp
  163.         move.l  d0,oldex4           ;* Save old vector.
  164.  
  165.         pea     newex5
  166.         move.l  #$00050005,-(sp)
  167.         trap    #13                 ;* Setexc(5,&newex5)
  168.         addq.l  #8,sp
  169.         move.l  d0,oldex5           ;* Save old vector.
  170.  
  171.         pea     newex8
  172.         move.l  #$00050008,-(sp)
  173.         trap    #13                 ;* Setexc(8,&newex8)
  174.         addq.l  #8,sp
  175.         move.l  d0,oldex8           ;* Save old vector.
  176.  
  177.         pea     newex102
  178.         move.l  #$00050102,-(sp)
  179.         trap    #13                 ;* Setexc(102,&newex102)
  180.         addq.l  #8,sp
  181.         move.l  d0,oldex102         ;* Save old vector.
  182. punt:
  183.         rts                         ;* All done, return to caller.
  184.  
  185. ;*****************************************************************************
  186. ;* the remove routine, de-installs handlers...
  187. ;*****************************************************************************
  188.  
  189. _exh_remove_handler:
  190.  
  191.         move.l  oldex2,-(sp)
  192.         move.l  #$00050002,-(sp)
  193.         trap    #13                 ;* Setexc(2,oldex2)
  194.         addq.l  #8,sp
  195.  
  196.         move.l  oldex3,-(sp)
  197.         move.l  #$00050003,-(sp)
  198.         trap    #13                 ;* Setexc(3,oldex3)
  199.         addq.l  #8,sp
  200.  
  201.         move.l  oldex4,-(sp)
  202.         move.l  #$00050004,-(sp)
  203.         trap    #13                 ;* Setexc(4,oldex4)
  204.         addq.l  #8,sp
  205.  
  206.         move.l  oldex5,-(sp)
  207.         move.l  #$00050005,-(sp)
  208.         trap    #13                 ;* Setexc(5,oldex5)
  209.         addq.l  #8,sp
  210.  
  211.         move.l  oldex8,-(sp)
  212.         move.l  #$00050008,-(sp)
  213.         trap    #13                 ;* Setexc(8,oldex8)
  214.         addq.l  #8,sp
  215.  
  216.         move.l  oldex102,-(sp)
  217.         move.l  #$00050102,-(sp)
  218.         trap    #13                 ;* Setexc(102,oldex102)
  219.         addq.l  #8,sp
  220.  
  221.         rts
  222.  
  223.         end
  224.  
  225. --------- cut here ----------------
  226.  
  227.  That's the code I use to trap unexpected errors in the HCC compiler piece.
  228. It's appropriate for simple things like issuing a message, closing files,
  229. and exiting the program.  It is *NOT* appropriate for complex handling such
  230. as recovering from the bus error and continuing processing.
  231.  
  232. --
  233. - Ian
  234. (void *) where prohibited by law
  235.  
  236.