diff options
author | Andrew Gregory <andrew.gregory.8@gmail.com> | 2019-06-08 06:12:17 +0200 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2019-08-05 10:19:04 +0200 |
commit | 4e5254dbf3ff82b9190308e5e3501f18b876c419 (patch) | |
tree | 802190d6d26271b0385715297d4008ff7ab710f9 | |
parent | e7156e78b80899a1f434d65e558e0d9471828928 (diff) | |
download | pacman-4e5254dbf3ff82b9190308e5e3501f18b876c419.tar.gz pacman-4e5254dbf3ff82b9190308e5e3501f18b876c419.tar.xz |
create coredump on segfault
Overriding the segfault handler prevents the creation of core dumps by
the default handler, which makes debugging segfaults difficult.
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r-- | src/pacman/sighandler.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/src/pacman/sighandler.c b/src/pacman/sighandler.c index a4849a0c..082756b5 100644 --- a/src/pacman/sighandler.c +++ b/src/pacman/sighandler.c @@ -38,6 +38,15 @@ static ssize_t xwrite(int fd, const void *buf, size_t count) return ret; } +static void _reset_handler(int signum) +{ + struct sigaction new_action; + sigemptyset(&new_action.sa_mask); + new_action.sa_handler = SIG_DFL; + new_action.sa_flags = 0; + sigaction(signum, &new_action, NULL); +} + /** Catches thrown signals. Performs necessary cleanup to ensure database is * in a consistent state. * @param signum the thrown signal @@ -76,19 +85,26 @@ void install_soft_interrupt_handler(void) void remove_soft_interrupt_handler(void) { - struct sigaction new_action; - sigemptyset(&new_action.sa_mask); - new_action.sa_handler = SIG_DFL; - new_action.sa_flags = 0; - sigaction(SIGINT, &new_action, NULL); - sigaction(SIGHUP, &new_action, NULL); + _reset_handler(SIGINT); + _reset_handler(SIGHUP); } static void segv_handler(int signum) { + sigset_t segvset; const char msg[] = "\nerror: segmentation fault\n" "Please submit a full bug report with --debug if appropriate.\n"; xwrite(STDERR_FILENO, msg, sizeof(msg) - 1); + + /* restore the default handler */ + _reset_handler(signum); + /* unblock SIGSEGV */ + sigaddset(&segvset, signum); + sigprocmask(SIG_UNBLOCK, &segvset, NULL); + /* re-raise to trigger a core dump */ + raise(signum); + + /* raise should immediately abort, but just to make absolutely sure */ _Exit(signum); } |