summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2019-06-08 06:12:17 +0200
committerAllan McRae <allan@archlinux.org>2019-08-05 10:19:04 +0200
commit4e5254dbf3ff82b9190308e5e3501f18b876c419 (patch)
tree802190d6d26271b0385715297d4008ff7ab710f9 /src
parente7156e78b80899a1f434d65e558e0d9471828928 (diff)
downloadpacman-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>
Diffstat (limited to 'src')
-rw-r--r--src/pacman/sighandler.c28
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);
}