Bug 53394

Summary: sigaction (SIGRTMIN) fails when linking with librt
Product: [Retired] Red Hat Linux Reporter: Trevin Beattie <trevin>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED ERRATA QA Contact: Aaron Brown <abrown>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.1CC: fweimer
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-09-14 15:53:31 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Trevin Beattie 2001-09-07 20:31:10 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.78 [en] (X11; U; Linux 2.4.3-12 i586)

Description of problem:
If you try to set up a signal handler for the real-time signals
(SIGRTMIN+x), sigaction will fail with error code "Invalid argument" if the
program was linked with librt.  If you don't link with librt, the call
succeeds (but you can't call any POSIX.4 timer functions, or the program
won't even link).


Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. Create the following file:

cat > sigaction_error.c << EOF
#include <signal.h>
#include <stdio.h>

void catch_signal (int signum) { return; }

int main () {
  struct sigaction handler;
  int status;

  handler.sa_handler = catch_signal;
  sigemptyset (&handler.sa_mask);
  handler.sa_flags = SA_RESTART;
  status = sigaction (SIGRTMIN, &handler, NULL);
  if (status)
    perror ("sigaction(SIGRTMIN)");
  else
    puts ("SIGRTMIN signal handler successfully installed.");
  return status;
}
EOF

2. Compile as follows:
gcc -g -lrt -o sigaction_error sigaction_error.c

3. Run.



Actual Results:  sigaction(SIGRTMIN): Invalid argument


Expected Results:  2b. Compile as follows:
gcc -g -o sigaction_error sigaction_error.c

3. Run.
SIGRTMIN signal handler successfully installed.


Additional info:

I thought the error might have occurred because I was installing a regular
one-argument signal handler instead of the newer three-argument version,
even though the POSIX standard does not impose such a restriction. 
However, adding the flag SA_SIGINFO does not alter the results.

Comment 1 Jakub Jelinek 2001-09-08 07:48:32 UTC
The thing is that -lpthread (which -lrt uses because kernel lacks
native aio support) uses SIGRTMIN..SIGRTMIN+2 for thread bookkeeping,
so you obviously cannot use already used signals.
I don't think any standard requires full range of SIGRTMIN..SIGRTMAX
to be available for the application's use.

Comment 2 Trevin Beattie 2001-09-09 15:17:55 UTC
I disagree.  The very rationale for the existence of SIGRTMIN through SIGRTMAX
was to have a larger set of signals for application use.  I don't have the 1993
(94?) version of the POSIX.4 standard, but I do have two other standards for
reference:

In the Single Unix Specification Version 2 ("UNIX98"), under <signal.h>:

"This header also declares the macros SIGRTMIN and SIGRTMAX, which evaluate to
integral expressions and, if the Realtime Signals Extension option is supported,
specify a range of signal numbers that are reserved for application use and for
which the realtime signal behaviour specified in this specification is
supported. The signal numbers in this range do not overlap any of the signals
specified in the following table. 

"The range SIGRTMIN through SIGRTMAX inclusive includes at least RTSIG_MAX
signal numbers."

And in the April 2001 draft of POSIX (p1003.1-200x), again under <signal.h>:

"This header shall also declare the macros SIGRTMIN and SIGRTMAX, which evaluate
to integer expressions, and specify a range of signal numbers that are reserved
for application use and for which the realtime signal behavior specified in this
volume of IEEE Std 1003.1-200x is supported. The signal numbers in this range do
not overlap any of the signals specified in the following table.

"The range SIGRTMIN through SIGRTMAX inclusive shall include at least
{RTSIG_MAX} signal numbers."

If the system needs additional signals for its own purposes, fine; you can
define a set of implementation-defined signals.  But don't use the signals that
are reserved for application use.  Instead, you could simply adjust the values
of SIGRTMIN and/or SIGRTMAX so that there is no conflict.  As long as there are
still at least 8 values from SIGRTMIN to SIGRTMAX, that will satisfy the
standard.

And remember that SIGRTMIN is evaluated at run-time, not compile-time, so its
value can change according to the system's needs.  Isn't that why you have it
defined as a function call?


Comment 3 Jakub Jelinek 2001-09-09 19:23:26 UTC
I'll talk with Ulrich what can be done about this.
The issue is that as -lpthread is only DT_NEEDED of -lrt, not anything
else, -lc comes earlier in search scope than -lpthread and thus
__libc_current_sigrtmin is used from -lc, not -lpthread.
One solution would be using
GROUP ( /lib/librt.so.1 /lib/libpthread.so.0 )
as /usr/lib/librt.so,
another having a copy of allocrtsig.c in linuxthreads which would
make glibc examine some pthread weak symbol and adjust if pthread
was found, another have a separate __libc_current_sigrtmin in
-lrt which would transfer control to -lpthread's __libc_current_sigrtmin.

Comment 4 Jakub Jelinek 2001-09-14 15:53:27 UTC
Actually, it is fixed in yet different way.
librt.so.* has DT_FILTER libpthread.so.0 (in GNU DT_FILTER semantics),
meaning libpthread.so.0 will come earlier than librt.so.1 in search path
(which means earlier than libc.so.6 too).

Comment 5 Jakub Jelinek 2001-10-18 09:03:50 UTC
As GLIBC DT_FILTER semantics is horribly broken, Ulrich decided a librt.so
linker script is the way to go for now.
It should be fixed in 2.2.4-19.