|Anonymous | Login||2023-12-07 11:06 UTC|
|Main | My View | View Issues | Change Log | Docs|
|Viewing Issue Simple Details|
|ID||Category||Severity||Type||Date Submitted||Last Update|
|0000906||[1003.1(2013)/Issue7+TC1] System Interfaces||Editorial||Clarification Requested||2014-12-18 02:10||2022-07-19 14:08|
|Priority||normal||Resolution||Accepted As Marked|
|Final Accepted Text||Note: 0005851|
|Summary||0000906: Ambiguity of abort() behavior racing with sigaction|
The abort function is specified to cause abnormal program termination with status indicating SIGABRT "unless the signal SIGABRT is being caught and the signal handler does not return", but the phrase "is being caught" is ambiguous with respect to concurrent changes to the signal disposition for SIGABRT from other threads. Moreover, the normal way of implementing the abnormal termination when a signal handler is installed is to reset the disposition to SIG_DFL if raising SIGABRT did not terminate the process already, but such an operation can contend with a call to sigaction from another thread that reinstalls a signal handler, thereby causing more than one signal handler to run as a result of the call to abort. Two implementations I examined (GNU and OpenBSD) use such an implementation approach and fail to address this in any meaningful way. Further, such implementations seem to be non-conforming since abort is not specified to change the signal disposition for SIGABRT (except possibly in the case where it's ignored, since abort "shall override blocking or ignoring") and an application could observe (from another thread) the change in signal disposition.
The only ways I can see to implement abort which are consistent with the current text of the standard are either:
1. With a mechanism to "stop the world" (halt all other threads) before actually performing the operations involved to implement abort in terms of well-known primitives like raise and sigaction, OR
2. With a system call that performs the equivalent of _exit but faking termination by signal.
Since I'm not aware of any historical implementations that use either method 1 or 2 above, I am inclined to think that the current requirements are contrary to existing practice and perhaps unintentional.
Relax the requirements of abort to agree with current practice, something along the lines of:
"If the signal disposition for SIGABRT is changed during the execution of abort(), it is unspecified whether or how many times SIGABRT is delivered, the disposition of SIGABRT during abort() is unspecified, and implementation-defined abnormal program termination shall occur unless SIGABRT is caught and the signal handler does not return."
Language should also be added allowing the abort() to reset the disposition of SIGABRT to SIG_DFL.
Don Cragun (manager)
edited on: 2022-06-16 16:23
We had planned to forward this to the ISO C Committee for consideration, but have since determined that the C Standard currently says that the behavior is undefined when signal() is used in a multi-threaded application. Therefore we do need to address this issue in POSIX.
edited on: 2022-06-17 14:24
Page and line numbers are for the 2018 edition.
On page 565 line 19766 section abort(), change:
unless the signal SIGABRT is being caught and the signal handler does not return.to:
unless a SIGABRT signal that it generates is caught and the signal handler does not return.
On page 565 line 19771 section abort(), change:
The SIGABRT signal shall be sent to the calling process as if by means of raise() with the argument SIGABRT.to:
The SIGABRT signal shall be sent to the calling [CX]thread[/CX] as if by means of raise() with the argument SIGABRT. [CX]If this signal does not terminate the process (for example, if the signal is caught and the handler returns), abort() may change the disposition of SIGABRT to SIG_DFL and send the signal (in the same way) again. If a second signal is sent and it does not terminate the process, the behavior is unspecified, except that the abort() call shall not return.[/CX]
On page 565 line 19785 section abort(), insert at the start of RATIONALE:
Historically, abort() has been implemented by calling other signal manipulation functions such as raise(), sigaction(), and pthread_sigmask(). This means that its operation can be affected by concurrent actions in other threads. For example, if abort() attempts to terminate the process by calling sigaction() to change the disposition for SIGABRT to SIG_DFL and then calling raise(), another thread could change the disposition in between those two calls, resulting in the process not being terminated. If this happens, the only requirement is that abort() does not return. An implementation could call those functions in a loop (which could in theory then execute indefinitely), or could terminate the process by calling _exit() (which would ensure termination but result in the wrong wait status). To avoid these issues, implementations are encouraged to implement abort() in a manner such that its operation cannot be affected by concurrent actions in other threads. For example, it could first halt the execution of all other threads, or it could terminate the process using a ``terminate as if by a signal'' system call instead of by raising (a second) SIGABRT.
On page 566 line 19805 section abort(), change FUTURE DIRECTIONS from:
A future version of this standard may require abort() to be implemented in a manner such that its operation cannot be affected by concurrent actions in other threads.
|2014-12-18 02:10||dalias||New Issue|
|2014-12-18 02:10||dalias||Name||=> Rich Felker|
|2014-12-18 02:10||dalias||Organization||=> musl libc|
|2014-12-18 02:10||dalias||Section||=> abort|
|2014-12-18 02:10||dalias||Page Number||=> unknown|
|2014-12-18 02:10||dalias||Line Number||=> unknown|
|2015-03-26 15:38||Don Cragun||Note Added: 0002607|
|2015-03-26 15:41||Don Cragun||Page Number||unknown => 560|
|2015-03-26 15:41||Don Cragun||Line Number||unknown => 19406-19414|
|2015-03-26 15:41||Don Cragun||Interp Status||=> ---|
|2022-05-12 15:29||geoffclare||Tag Attached: c99|
|2022-06-16 16:15||geoffclare||Tag Detached: c99|
|2022-06-16 16:22||Don Cragun||Note Edited: 0002607|
|2022-06-16 16:23||Don Cragun||Note Edited: 0002607|
|2022-06-17 14:22||geoffclare||Note Added: 0005851|
|2022-06-17 14:24||geoffclare||Note Edited: 0005851|
|2022-06-23 15:23||geoffclare||Final Accepted Text||=> Note: 0005851|
|2022-06-23 15:23||geoffclare||Status||New => Resolved|
|2022-06-23 15:23||geoffclare||Resolution||Open => Accepted As Marked|
|2022-06-23 15:23||geoffclare||Tag Attached: tc3-2008|
|2022-07-19 14:08||geoffclare||Status||Resolved => Applied|
|Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group|