#3794 assigned defect

Initial POSIX Signals Mask Incorrect

Reported by: Joel Sherrill Owned by: Joel Sherrill
Priority: normal Milestone: 5.1
Component: posix Version: 5
Severity: normal Keywords: POSIX, signals, compliance
Cc: Blocked By:
Blocking:

Description

RTEMS initial signal mask for the "process" does not match the behavior of Linux, FreeBSD, and Cygwin.

There are some subtle rules which need to be followed for the value of the created thread's signal mask. Because signals are part of C99 and enhanced by POSIX, both Classic API tasks and POSIX threads have to have them enabled.

  1. Internal system threads should have no signals enabled. They have no business executing user signal handlers -- especially IDLE.
  1. The initial signal mask for other threads needs to follow the implication of a pure C99 environment which only has the methods raise() and signal(). This implies that all signals are unmasked until the thread explicitly uses a POSIX methods to block some. This applies to both Classic tasks and POSIX threads created as initalization tasks/threads (e.g. before the system is up).
  1. After the initial threads are created, the signal mask should be inherited from the creator. This can be done based on system state.

RTEMS behavior was incorrect by blocking all signals initially and for Classic API tasks.

Notes:

  • The default signal mask does not matter for any application that does not use POSIX signals.
  • It is assumed that Classic API tasks should provide a compliant C run-time environment. Hence the defalt signal mask state matters.

Impact on Applications and Tests
================================
In general, an application should always explicitly block or unmask any signals that it intends to process. If there is concern about which thread may process it, then it should be blocked in all threads that are not intended to process it. The following code can be used to block all signals. This method can be used in the initialization task/thread to mimic historical behavior:

static void block_all_signals(void)
{
  int               sc;
  sigset_t          mask;

  sc = sigfillset( &mask );
  // check sc == 0

  sc = pthread_sigmask( SIG_BLOCK, &mask, NULL );
  // check sc == 0
}

Change History (0)

Note: See TracTickets for help on using tickets.