home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / std_unix / volume.31 / text0053.txt < prev    next >
Encoding:
Text File  |  1993-07-15  |  5.0 KB  |  154 lines

  1. Submitted-by: gwyn@smoke.brl.mil (Doug Gwyn)
  2.  
  3. In article <1s8s8bINNl4h@ftp.UU.NET> wulkan@vnet.IBM.COM (Mike Wulkan) writes:
  4. >1)  ANSI C Standard Section 4.10.4.1 abort():
  5. >    "...causes abnormal program termination to occur, unless the signal
  6. >    SIGABRT is being caught and the signal handler does not return.  ...
  7. >    is returned to the host environment by means of the function call
  8. >    raise(SIGABRT)."
  9. >2)  Posix .4a Section 2.2.1.136:
  10. >    "Asynchronously generated signal: A signal which is not
  11. >    attributable to a specific thread.  Examples are signals sent via
  12. >    kill(), ..."
  13. >3)  Posix .4a Section 8.4.6.2:
  14. >    "The C standard raise() function...  The effect of this function in
  15. >    a POSIX.4a process shall be equivalent to calling
  16. >    kill(getpid(),sig).  The signal specified shall be asynchronously
  17. >    generated, regardless of the signal number, providing the signal
  18. >    number is valid."
  19. >I think that it is pretty clear from the above that abort() causes an
  20. >asynchronous SIGABRT signal to be generated.
  21.  
  22. Yes, to the extent that "asynchronous" is (re)defined as per POSIX.4a,
  23. where it seems to mean "process global".
  24.  
  25. >So how do you achieve the semantics required by (1) if the SIGABRT signal
  26. >is delivered to a thread other than the one that issued the abort() call?
  27.  
  28. Well, the first thing to note is that the C standard specifies only what
  29. is guaranteed for STRICTLY CONFORMING programs, which excludes any program
  30. that uses POSIX.4a thread facilities.  So, strictly speaking, there is
  31. no standard requirement imposed by (1) in such circumstances.
  32.  
  33. >What you end up with is a race condition between the thread that is
  34. >executing the SIGABRT signal handler and the thread that issued the
  35. >abort() function call terminating the program!
  36.  
  37. Any time you have multiple threads you already have a race.
  38.  
  39. >AND the method of exiting the signal handling function has NO influence
  40. >on whether the program will be terminated.  This is a direct violation
  41. >of ANSI C.
  42.  
  43. I didn't understand that comment at all.  Certainly the POSIX.4a
  44. requirement for the implementation of raise() is compatible with the
  45. requirements of the C standard.  And I saw nothing in the cited specs
  46. that requires that abort() be implemented any differently for POSIX.4a
  47. than for POSIX.1.  I have attached my implementation below for your
  48. perusal.
  49.  
  50. >Even in the case where the SIGABRT signal is delivered to the same
  51. >thread that issued the abort() function call, since the signal is
  52. >asynchronous, there is NO guarantee that it will be delivered before the
  53. >abort() function initiates termination of the program.
  54.  
  55. I think that is simply a misconception of the way that abort() must
  56. operate.  It is the unintercepted SIGABRT, generated by abort(), that
  57. CAUSES (abnormal) program termination.
  58.  
  59. In the comments below, "asynchronous" means "asynchronous", not the
  60. POSIX.4a redefinition of the term.
  61.  
  62. /*
  63.     abort() -- generate an abnormal process termination
  64.  
  65.     public-domain implementation
  66.  
  67.     last edit:    13-Dec-1992    Gwyn@ARL.Army.Mil
  68.  
  69.     complies with the following standards:
  70.         ANSI/ISO 9899:1990[1992] (replaces ANS X3.159-1989)
  71.         ISO/IEC 9945-1 (Replaces IEEE Std 1003.1-1988)
  72.         SVID Issue 3
  73.         XPG Issue 3
  74.         AES Revision A
  75.  
  76.     IMPLEMENTOR NOTE:  abort() must be reentrant for other signals
  77.         that may occur asynchronously, resulting in additional
  78.         calls to abort() from their handler functions.
  79.         Consequently, the STDIO cleanup function must also be
  80.         reentrant or else it must block signals and be serially
  81.         reusable.
  82.  */
  83. #ifdef    __ORCAC__
  84. #pragma lint        -1
  85. #pragma optimize    -1
  86. #pragma noroot
  87. #endif
  88.  
  89. /* IMPORTANT: Define CLEANUP to invoke your STDIO cleanup function: */
  90. #ifdef    unix
  91. extern void    _cleanup();
  92. #define CLEANUP _cleanup();        /* usual invocation through SVR2 */
  93. #else
  94. #ifdef    __ORCAC__
  95. #define SysIOShutdown    SYSIOSHUTDOWN    /* temporary, for ORCA/C 2.0.0 D6 */
  96. extern pascal void    SysIOShutdown( void );
  97. #define CLEANUP SysIOShutdown();    /* ~C_SHUTDOWN undoubtedly better */
  98. #else
  99. #define CLEANUP /* XXX -- define yours here -- XXX */
  100. #endif
  101. #endif
  102.  
  103. #define _POSIX_SOURCE    /* force visibility of POSIX.1 symbols, if any */
  104. #include    <signal.h>
  105.  
  106. typedef void    (*sigf_type)(
  107. #ifdef    __STDC__
  108.                   int
  109. #endif
  110.                 );
  111.  
  112. #ifndef    SIGABRT
  113. #define    SIGABRT    SIGIOT            /* UNIX tradition */
  114. #endif
  115.  
  116. void
  117. abort(
  118. #ifdef    __STDC__
  119.        void
  120. #endif
  121.      )
  122.     {
  123.     register sigf_type     sigfunc = signal( SIGABRT, SIG_IGN );
  124. #ifdef    SIG_BLOCK            /* POSIX.1 support assumed */
  125.     sigset_t        abort_mask;
  126.  
  127.     (void)sigemptyset( &abort_mask );
  128.     (void)sigaddset( &abort_mask, SIGABRT );
  129.     (void)sigprocmask( SIG_UNBLOCK, &abort_mask, (sigset_t *)0 );
  130.     /* If a SIGABRT signal was pending, it has now been discarded. */
  131. #endif
  132.  
  133.     if ( sigfunc == SIG_IGN )
  134.         sigfunc == SIG_DFL;
  135.  
  136.     if ( sigfunc == SIG_DFL )
  137.         CLEANUP         /* flush STDIO buffers etc. */
  138.  
  139.     for ( ; ; )
  140.         {
  141.         (void)signal( SIGABRT, sigfunc );
  142.                     /* SIG_DFL or function */
  143.         (void)raise( SIGABRT );    /* wham? */
  144.  
  145.         /* The program caught SIGABRT and the handler returned. */
  146.  
  147.         sigfunc = SIG_DFL;    /* force bam! */
  148.         }
  149.     }
  150.  
  151.  
  152. Volume-Number: Volume 31, Number 54
  153.  
  154.