why weren't we always handling SIGFPE?

This commit is contained in:
nick black 2021-07-17 21:55:57 -04:00
parent 84a61d1476
commit 382b68f5ab
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
5 changed files with 21 additions and 14 deletions

View File

@ -8,6 +8,8 @@ rearrangements of Notcurses.
plane from scrolling along with it.
* Added `input_errors` and `input_events` stats.
* `NCALPHA_HIGHCONTRAST` now works properly atop default backgrounds.
* `SIGFPE` is now included among the fatal signals for which handlers are
by default installed. Unsure how I overlooked it this long.
* 2.3.10 (2021-07-14)
* Notcurses now builds and works, so far as I can tell, on OS X 11.4+.

View File

@ -169,9 +169,9 @@ The following flags are defined:
will place the terminal into cbreak mode (i.e. disabling echo and line
buffering; see **tcgetattr(3)**).
* **NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS**: A signal handler will usually be
installed for **SIGINT**, **SIGILL**, **SIGQUIT**, **SIGSEGV**,
**SIGTERM**, and **SIGABRT**, cleaning up the terminal on such exceptions.
* **NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS**: A signal handler will usually be installed
for **SIGABRT**, **SIGFPE**, **SIGILL**, **SIGINT**, **SIGQUIT**,
**SIGSEGV**, and **SIGTERM**, cleaning up the terminal on such exceptions.
With this flag, the handler will not be installed.
* **NCDIRECT_OPTION_VERBOSE**: Enable diagnostics to **stderr** at the level of

View File

@ -127,9 +127,9 @@ zero. The following flags are defined:
installed.
* **NCOPTION_NO_QUIT_SIGHANDLERS**: A signal handler will usually be installed
for **SIGINT**, **SIGILL**, **SIGQUIT**, **SIGSEGV**, **SIGTERM**, and
**SIGABRT**, cleaning up the terminal on such exceptions. With this flag,
the handler will not be installed.
for **SIGABRT**, **SIGFPE**, **SIGILL**, **SIGINT**, **SIGQUIT**,
**SIGSEGV**, and **SIGTERM**, cleaning up the terminal on such exceptions.
With this flag, the handler will not be installed.
* **NCOPTION_SUPPRESS_BANNERS**: Disables the diagnostics and version
information printed on startup, and the performance summary on exit.

View File

@ -397,6 +397,7 @@ block_on_input(int fd, const struct timespec* ts, const sigset_t* sigmask){
sigdelset(&scratchmask, SIGCONT);
sigdelset(&scratchmask, SIGWINCH);
sigdelset(&scratchmask, SIGILL);
sigdelset(&scratchmask, SIGFPE);
sigdelset(&scratchmask, SIGSEGV);
sigdelset(&scratchmask, SIGABRT);
// now add those which we don't want while writing

View File

@ -15,12 +15,12 @@ static bool handling_fatals;
// saved signal actions, restored in drop_signals() FIXME make an array
static struct sigaction old_winch;
static struct sigaction old_cont;
static struct sigaction old_term;
static struct sigaction old_int;
static struct sigaction old_abrt;
static struct sigaction old_fpe;
static struct sigaction old_ill;
static struct sigaction old_int;
static struct sigaction old_quit;
static struct sigaction old_segv;
static struct sigaction old_abrt;
static struct sigaction old_term;
// Signals we block when we start writing out a frame, so as not to be
@ -55,12 +55,13 @@ int drop_signals(void* nc){
handling_winch = false;
}
if(handling_fatals){
sigaction(SIGINT, &old_int, NULL);
sigaction(SIGILL, &old_ill, NULL);
sigaction(SIGTERM, &old_term, NULL);
sigaction(SIGSEGV, &old_segv, NULL);
sigaction(SIGABRT, &old_abrt, NULL);
sigaction(SIGFPE, &old_fpe, NULL);
sigaction(SIGILL, &old_ill, NULL);
sigaction(SIGINT, &old_int, NULL);
sigaction(SIGQUIT, &old_quit, NULL);
sigaction(SIGSEGV, &old_segv, NULL);
sigaction(SIGTERM, &old_term, NULL);
handling_fatals = false;
}
ret = !atomic_compare_exchange_strong(&signal_nc, &expected, NULL);
@ -92,10 +93,11 @@ fatal_handler(int signo, siginfo_t* siginfo, void* v){
fatal_callback(nc);
switch(signo){
case SIGTERM: invoke_old(&old_term, signo, siginfo, v); break;
case SIGQUIT: invoke_old(&old_quit, signo, siginfo, v); break;
case SIGSEGV: invoke_old(&old_segv, signo, siginfo, v); break;
case SIGQUIT: invoke_old(&old_quit, signo, siginfo, v); break;
case SIGINT: invoke_old(&old_int, signo, siginfo, v); break;
case SIGILL: invoke_old(&old_ill, signo, siginfo, v); break;
case SIGFPE: invoke_old(&old_fpe, signo, siginfo, v); break;
case SIGABRT: invoke_old(&old_abrt, signo, siginfo, v); break;
}
raise(signo); // FIXME does this invoke twice? hrmmm
@ -135,6 +137,7 @@ int setup_signals(void* vnc, bool no_quit_sigs, bool no_winch_sig,
memset(&sa, 0, sizeof(sa));
fatal_callback = handler;
sa.sa_sigaction = fatal_handler;
sigaddset(&sa.sa_mask, SIGFPE);
sigaddset(&sa.sa_mask, SIGILL);
sigaddset(&sa.sa_mask, SIGINT);
sigaddset(&sa.sa_mask, SIGQUIT);
@ -143,6 +146,7 @@ int setup_signals(void* vnc, bool no_quit_sigs, bool no_winch_sig,
sigaddset(&sa.sa_mask, SIGTERM);
sa.sa_flags = SA_SIGINFO | SA_RESETHAND; // don't try fatal signals twice
int ret = 0;
ret |= sigaction(SIGFPE, &sa, &old_fpe);
ret |= sigaction(SIGILL, &sa, &old_ill);
ret |= sigaction(SIGINT, &sa, &old_int);
ret |= sigaction(SIGQUIT, &sa, &old_quit);