signals: upon a crash, save changed buffers and reset terminal state

Upon a segmentation fault or an abort signal, instead of crashing,
losing all changes, and leaving the terminal in curses mode, nano
now calls die(), to save any changed buffers and to restore the
terminal to a usable state.

For the remote chance that nano segfaults in die(), the handler for
SIGSEGV and for SIGABRT is reset to its default value as soon as the
signal fires, to prevent a crash-handler loop.

Since a core dump is usually more helpful for debugging, the crash
handler is not included in a debug build.

This addresses https://savannah.gnu.org/patch/?9623.

Signed-off-by: Devin Hussey <husseydevin@gmail.com>
master
Devin Hussey 2018-04-29 07:51:52 -04:00 committed by Benno Schulenberg
parent 0da554e6d7
commit e889c28a95
2 changed files with 21 additions and 0 deletions

View File

@ -1211,6 +1211,16 @@ void signal_init(void)
sigaction(SIGTSTP, &act, NULL);
#endif
}
#ifndef DEBUG
/* Trap SIGSEGV and SIGABRT to save any changed buffers and reset
* the terminal to a usable state. Reset these handlers to their
* defaults as soon as their signal fires. */
act.sa_handler = handle_crash;
act.sa_flags |= SA_RESETHAND;
sigaction(SIGSEGV, &act, NULL);
sigaction(SIGABRT, &act, NULL);
#endif
}
/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
@ -1219,6 +1229,14 @@ RETSIGTYPE handle_hupterm(int signal)
die(_("Received SIGHUP or SIGTERM\n"));
}
#ifndef DEBUG
/* Handler for SIGSEGV (segfault) and SIGABRT (abort). */
RETSIGTYPE handle_crash(int signal)
{
die(_("Sorry! Nano crashed! Code: %d. Please report a bug.\n"), signal);
}
#endif
/* Handler for SIGTSTP (suspend). */
RETSIGTYPE do_suspend(int signal)
{

View File

@ -426,6 +426,9 @@ void window_init(void);
void do_exit(void);
void close_and_go(void);
RETSIGTYPE handle_hupterm(int signal);
#ifndef DEBUG
RETSIGTYPE handle_crash(int signal);
#endif
RETSIGTYPE do_suspend(int signal);
RETSIGTYPE do_continue(int signal);
#ifndef NANO_TINY