Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Execution::SignalHandlerRegistry Class Reference

#include <SignalHandlers.h>

Classes

class  SafeSignalsManager
 

Public Member Functions

nonvirtual Containers::Set< SignalID > GetHandledSignals () const
 
nonvirtual Containers::Set< SignalHandlerGetSignalHandlers (SignalID signal) const
 
nonvirtual void SetSignalHandlers (SignalID signal)
 
nonvirtual void AddSignalHandler (SignalID signal, const SignalHandler &handler)
 
nonvirtual void RemoveSignalHandler (SignalID signal, const SignalHandler &handler)
 
nonvirtual void SetStandardCrashHandlerSignals (SignalHandler handler=SignalHandler{DefaultCrashSignalHandler, SignalHandler::Type::eDirect}, const Containers::Set< SignalID > &forSignals=GetStandardCrashSignals())
 

Static Public Member Functions

static SignalHandlerRegistryGet ()
 
static void DefaultCrashSignalHandler (SignalID signal)
 
static Containers::Set< SignalID > GetStandardCrashSignals ()
 

Static Public Attributes

static const SignalHandler kIGNORED = SignalHandler{SIG_IGN, SignalHandler::Type::eDirect}
 

Detailed Description

SignalHandlerRegistry is a singleton object. If used - it itself registers signal handlers for each supported signal.

The user can then add in their own 'handlers' for those signals, and they are ALL called - one after the other (TDB how threads work with this).

When an platform signal-handler is installed (via 'sigaction' for example) - and then later UNINSTALLED (due to changes in GetHandledSignals) - this code resets the signal handler to SIG_DFL (not the previous value).

Note
The SignalHandlerRegistry must only be accessed after the start of main, and must not be accessed after main has completed.

To use 'safe' signal handlers, be sure to read about and use

See also
SignalHandlerRegistry::SafeSignalsManager
Note
Thread-Safety Internally-Synchronized-Thread-Safety

Definition at line 162 of file SignalHandlers.h.

Member Function Documentation

◆ Get()

SignalHandlerRegistry & SignalHandlerRegistry::Get ( )
static

Access singleton implementation. None exists until this is called.

Definition at line 295 of file SignalHandlers.cpp.

◆ GetHandledSignals()

Set< SignalID > SignalHandlerRegistry::GetHandledSignals ( ) const

Returns the set of signals trapped by the SignalHandlerRegistry registry. Note - if not 'Installed ()' - these are tracked internally by Stroika but not actually installed in the OS.

Definition at line 321 of file SignalHandlers.cpp.

◆ GetSignalHandlers()

Set< SignalHandler > SignalHandlerRegistry::GetSignalHandlers ( SignalID  signal) const

Returns the set of signals trapped by the SignalHandlerRegistry registry. This doesn't imply there is a handler. NB: A signal handler must be registered for a given signal number AND the signal number must be in GetHandledSignals () AND the SignalHandlerRegistry must be Installed () - to get the signal called.

It is NOT an error to have a signal handler registered for a signal not in the set of GetHandledSignals () - or vice versa. Signals in the list of GetHandledSignals() with no handlers are effectively ignored.

Definition at line 334 of file SignalHandlers.cpp.

◆ SetSignalHandlers()

void SignalHandlerRegistry::SetSignalHandlers ( SignalID  signal)
See also
GetSignalHandlers().

SetSignalHandlers () with NO arguments uninstalls all Stroika signal handlers for this signal. SetSignalHandlers () with ONE argument makes Stroika take-over the signal handling - and sets the set of hanlders to be exactly the one given (effectively removing any others previously added). SetSignalHandlers () with ONE a set of handlers registers all the given handlers.

Note - if through ANY combination of set/add/remove - you have NO signal handler - this reverts to SIG_DFL, and if you have exactly ONE signal handler - and its kIGNORED- the signal will be ignored.

Note
Setting any 'Safe' signal handlers requires that SafeSignalsManager has been created.

Definition at line 348 of file SignalHandlers.cpp.

◆ AddSignalHandler()

void SignalHandlerRegistry::AddSignalHandler ( SignalID  signal,
const SignalHandler handler 
)
See also
GetSignalHandlers().
Note
- subtlety - if you wish to later call RemoveSignalHandler, save the signalhandler in a static const of type SignalHandler, and re-use that value.
Adding any 'Safe' signal handlers requires that SafeSignalsManager has been created.

Definition at line 455 of file SignalHandlers.cpp.

◆ RemoveSignalHandler()

void SignalHandlerRegistry::RemoveSignalHandler ( SignalID  signal,
const SignalHandler handler 
)
See also
GetSignalHandlers()

Definition at line 462 of file SignalHandlers.cpp.

◆ DefaultCrashSignalHandler()

void SignalHandlerRegistry::DefaultCrashSignalHandler ( SignalID  signal)
static

This signal handler simply prints error to the trace log, and calls 'abort' - which on most operating systems will allow the debugger to examine the errant code.

Definition at line 470 of file SignalHandlers.cpp.

◆ GetStandardCrashSignals()

Containers::Set< SignalID > SignalHandlerRegistry::GetStandardCrashSignals ( )
static

These signals are generally associated with a programming error or bug, and these signals should generally be treated as a crash and terminate the program with a core-dump file. o SIGABRT o SIGILL o SIGFPE o SIGSEGV o SIGSYS (POSIX ONLY) o SIGBUS (POSIX ONLY) o SIGQUIT (POSIX ONLY)

Definition at line 476 of file SignalHandlers.cpp.

◆ SetStandardCrashHandlerSignals()

void SignalHandlerRegistry::SetStandardCrashHandlerSignals ( SignalHandler  handler = SignalHandler{DefaultCrashSignalHandler, SignalHandler::Type::eDirect},
const Containers::Set< SignalID > &  forSignals = GetStandardCrashSignals () 
)

The set of signals given (by default GetStandardCrashSignals) will be set to the given handler (by default DefaultCrashSignalHandler).

The only exception is SIGABRT will be intentionally ignored from this call because it prevents abort() from functioning properly. We COULD disable SIGABRT upon receipt of that signal (SIG_DFL) but that would be different than other signals handled, raise re-entrancy issues etc. Didn't seem worth while.

Note
By default these are created as 'unsafe' signal handlers, meaning that they are run on the thread that triggered the error. This is mostly because we (currently) have no other way to capture what thread we were running on at that point.

This is bad, because we could deadlock in handling the crash. But realistically, we were crashing anyhow, so the better stack trace maybe worth it.

Definition at line 490 of file SignalHandlers.cpp.

Member Data Documentation

◆ kIGNORED

const SignalHandler SignalHandlerRegistry::kIGNORED = SignalHandler{SIG_IGN, SignalHandler::Type::eDirect}
static

If this handler is set to the the ONLY handler for a given signal, then that signal handler is effectively ignored.

To get the signal to be handled the DEFAULT way - remove all signal handlers.

Definition at line 170 of file SignalHandlers.h.


The documentation for this class was generated from the following files: