Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 35 |
Nodes: | 6 (1 / 5) |
Uptime: | 18:35:30 |
Calls: | 321 |
Calls today: | 1 |
Files: | 957 |
Messages: | 82,382 |
Lawrence D'Oliveiro <ldo@nz.invalid> gabbled:
On Fri, 31 Jan 2025 09:15:39 -0000 (UTC), Muttley wrote:
All this confusion and complexity is why I always recommend that in a
multithreaded program if you must use signals then all signals should be >>> blocked with a single thread dedicated to sitting in sigwait() and handling >>> whatever comes along.
Or use signalfd(2) <https://manpages.debian.org/signalfd(2)>.
I never knew about that, very useful! Unfortunately it appears to be linux only.
Rainer Weikusat <rweikusat@talktalk.net> writes:
Up to and including The Open Group Base Specifications Issue 6, the >>following program was a correct way of using signal handlers:
----
----
As the only requirement for functions not listed as async-signal-safe
was
In the presence of signals, all functions defined by this volume
of IEEE Std 1003.1-2001 shall behave as defined when called from
or interrupted by a signal-catching function, with a single
exception: when a signal interrupts an unsafe function and the
signal-catching function calls an unsafe function, the behavior
is undefined.
Since version 7, its behaviour is undefined because the following >>requirement was added:
If the process is multi-threaded, or if the process is
single-threaded and a signal handler is executed other than as
the result of:
once multithreading was introduced, the stdio library functions were
required to synchronize access to the underlying FILE buffers between threads. As those are library functions which invoke kernel system
calls, unless they mask signals, they can be interrupted while they
own exclusive access to the stream.
Subsequent accesses from a signal handler to that stream
will block indefinitely.
Up to and including The Open Group Base Specifications Issue 6, the
following program was a correct way of using signal handlers:
----
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void alarmed(int unused)
{
puts("I was alarmed!");
alarm(2);
}
static void interrupted(int unused)
{
puts("I was interrupted!");
exit(0);
}
int main(void)
{
struct sigaction sa;
sigset_t omask;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGALRM);
sigaddset(&sa.sa_mask, SIGINT);
sa.sa_flags = 0;
sigprocmask(SIG_BLOCK, &sa.sa_mask, &omask);
sa.sa_handler = alarmed;
sigaction(SIGALRM, &sa, NULL);
sa.sa_handler = interrupted;
sigaction(SIGINT, &sa, NULL);
alarm(2);
while (1) sigsuspend(&omask);
return 0;
}
----
As the only requirement for functions not listed as async-signal-safe
was
In the presence of signals, all functions defined by this volume
of IEEE Std 1003.1-2001 shall behave as defined when called from
or interrupted by a signal-catching function, with a single
exception: when a signal interrupts an unsafe function and the signal-catching function calls an unsafe function, the behavior
is undefined.
Since version 7, its behaviour is undefined because the following
requirement was added:
If the process is multi-threaded, or if the process is
single-threaded and a signal handler is executed other than as
the result of:
despite the statement from version 6 was retained as is. These two requirements seem to contradict each other. It would also be
[I think this should be reported as a defect but there doesn't seem to
be a way to do that or at least no obvious way.]
Rainer Weikusat <rweikusat@talktalk.net> writes:
If the process is multi-threaded, or if the process is
single-threaded and a signal handler is executed other than as
the result of:
While Geoff may chime in with the definitive answer, once
multithreading was introduced, the stdio library functions
were required to synchronize access to the underlying
FILE buffers between threads.
As those are library functions
which invoke kernel system calls, unless they mask signals, they can
be interrupted while they own exclusive access to the stream.
Subsequent accesses from a signal handler to that stream
will block indefinitely.
On 2025-01-30, Rainer Weikusat <rweikusat@talktalk.net> wrote:
despite the statement from version 6 was retained as is. These two
requirements seem to contradict each other. It would also be
The older requirement can be interpreted as saying that if a signal goes
off, and the only functions in the interrupted call stack are async-safe >functions, then the handler may call async-unsafe functions.
This situation is outside of the conditions for undefined behavior
given in that requirement (handler calling unsafe, while interrupting >unsafe).
The newer requirement seems to say that if an asynchronous signal goes
off, the handler may not call async-unsafe functions, regardless of what
is in the call stack. Even if no POSIX function at all has been
interrupted (only the application's own code), the behavior is undefined
if an unsafe function is called.
So yes, these requirements conflict.
[I think this should be reported as a defect but there doesn't seem to
be a way to do that or at least no obvious way.]
Austin Group mailing list or whatever.
On 2025-01-30, Scott Lurndal <scott@slp53.sl.home> wrote:
Rainer Weikusat <rweikusat@talktalk.net> writes:
If the process is multi-threaded, or if the process is
single-threaded and a signal handler is executed other than as
the result of:
While Geoff may chime in with the definitive answer, once
multithreading was introduced, the stdio library functions
were required to synchronize access to the underlying
FILE buffers between threads.
But the requirement applies to a single-threaded program in
which an asynchronous signal occurs.
The multi-threaded case seems to say that if the program is MT,
then if a signal occurs even as a result of the program
calling raise, etc, it is effectivecly an async signal
(since it happens as the result of a thread executing
asynchronously with regard to whatever thread catches the signal
via a handler.)
After some digging I found the source of the change,
which was this bug:
https://austingroupbugs.net/view.php?id=66
It updated some text on the signal() page and then copied it into
XSH 2.4.3.
So the conflict Rainer has identified was already there in Issue 6,
but only for signal handlers installed using signal(), not sigaction(). Obviously it made no sense for there to be different signal handler
rules depending on which function installed the handler, hence the
copying.
Geoff Clare wrote:
After some digging I found the source of the change,
which was this bug:
https://austingroupbugs.net/view.php?id=66
It updated some text on the signal() page and then copied it into
XSH 2.4.3.
So the conflict Rainer has identified was already there in Issue 6,
but only for signal handlers installed using signal(), not sigaction().
Obviously it made no sense for there to be different signal handler
rules depending on which function installed the handler, hence the
copying.
I have now reported the problem to the Austin Group. See https://austingroupbugs.net/view.php?id=1905
In article <20250130113438.837@kylheku.com>,
Kaz Kylheku <643-408-1753@kylheku.com> wrote:
On 2025-01-30, Rainer Weikusat <rweikusat@talktalk.net> wrote:
despite the statement from version 6 was retained as is. These two
requirements seem to contradict each other. It would also be
The older requirement can be interpreted as saying that if a signal goes >>off, and the only functions in the interrupted call stack are async-safe >>functions, then the handler may call async-unsafe functions.
This situation is outside of the conditions for undefined behavior
given in that requirement (handler calling unsafe, while interrupting >>unsafe).
The newer requirement seems to say that if an asynchronous signal goes
off, the handler may not call async-unsafe functions, regardless of what
is in the call stack. Even if no POSIX function at all has been
interrupted (only the application's own code), the behavior is undefined
if an unsafe function is called.
So yes, these requirements conflict.
[I think this should be reported as a defect but there doesn't seem to
be a way to do that or at least no obvious way.]
Austin Group mailing list or whatever.
Austin group has a defect tracker; one must be subscribed to the
mailing list to submit an issue.
I don't think this is a defect.
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <20250130113438.837@kylheku.com>,
Kaz Kylheku <643-408-1753@kylheku.com> wrote:
On 2025-01-30, Rainer Weikusat <rweikusat@talktalk.net> wrote:
despite the statement from version 6 was retained as is. These two
requirements seem to contradict each other. It would also be
The older requirement can be interpreted as saying that if a signal goes >>>off, and the only functions in the interrupted call stack are async-safe >>>functions, then the handler may call async-unsafe functions.
This situation is outside of the conditions for undefined behavior
given in that requirement (handler calling unsafe, while interrupting >>>unsafe).
The newer requirement seems to say that if an asynchronous signal goes >>>off, the handler may not call async-unsafe functions, regardless of what >>>is in the call stack. Even if no POSIX function at all has been >>>interrupted (only the application's own code), the behavior is undefined >>>if an unsafe function is called.
So yes, these requirements conflict.
[I think this should be reported as a defect but there doesn't seem to >>>> be a way to do that or at least no obvious way.]
Austin Group mailing list or whatever.
Austin group has a defect tracker; one must be subscribed to the
mailing list to submit an issue.
I don't think this is a defect.
Mandating that functions defined by the standard behave as documented
when either called by a signal handler or interrupted by a signal unless
the signal handler interrupted an unsafe function and calls an unsafe >function while declaring that the behaviour is undefined if the signal >actually calls an unsafe function at least doesn't make any sense: How's
an unsafe function supposed to behave as documentend when called by a
signal handler if the behaviour is undefined when a signal handler
actually calls such a function?
All this confusion and complexity is why I always recommend that in a multithreaded program if you must use signals then all signals should be blocked with a single thread dedicated to sitting in sigwait() and handling whatever comes along.
On Fri, 31 Jan 2025 09:15:39 -0000 (UTC), Muttley wrote:
All this confusion and complexity is why I always recommend that in a
multithreaded program if you must use signals then all signals should be
blocked with a single thread dedicated to sitting in sigwait() and handling >> whatever comes along.
Or use signalfd(2) <https://manpages.debian.org/signalfd(2)>.
Rainer Weikusat <rweikusat@talktalk.net> writes:
Up to and including The Open Group Base Specifications Issue 6, the >>following program was a correct way of using signal handlers:
As the only requirement for functions not listed as async-signal-safe
was
In the presence of signals, all functions defined by this volume
of IEEE Std 1003.1-2001 shall behave as defined when called from
or interrupted by a signal-catching function, with a single
exception: when a signal interrupts an unsafe function and the
signal-catching function calls an unsafe function, the behavior
is undefined.
Since version 7, its behaviour is undefined because the following >>requirement was added:
If the process is multi-threaded, or if the process is
single-threaded and a signal handler is executed other than as
the result of:
While Geoff may chime in with the definitive answer, once
multithreading was introduced, [...]