52 lines
1.8 KiB
Diff
52 lines
1.8 KiB
Diff
|
From: Kurt Garloff <kurt@garloff.de>
|
||
|
Subject: Need to restore sigprocmask when not returning from signal handler
|
||
|
|
||
|
I stumbled over the fine details of signal handling:
|
||
|
A second SIGILL would not have been delivered to the handler as it was
|
||
|
blocked when invoking the handler for the first time. As we can't return
|
||
|
from the handler, we need to restore the process' signal mask ourselves
|
||
|
and reenable delivery.
|
||
|
|
||
|
Signed-off-by: Kurt Garloff <kurt@garloff.de>
|
||
|
|
||
|
Index: find_nonzero.c
|
||
|
===================================================================
|
||
|
RCS file: /home/cvsroot/dd_rescue/find_nonzero.c,v
|
||
|
retrieving revision 1.44
|
||
|
retrieving revision 1.46
|
||
|
diff -u -p -r1.44 -r1.46
|
||
|
--- find_nonzero.c 21 Feb 2014 12:51:43 -0000 1.44
|
||
|
+++ find_nonzero.c 6 Mar 2014 12:14:18 -0000 1.46
|
||
|
@@ -24,6 +24,14 @@ static jmp_buf sigill_jmp;
|
||
|
static void ill_handler(int sig)
|
||
|
{
|
||
|
have_feature = 0;
|
||
|
+ /* As we can't return from handler (as it would result in
|
||
|
+ * reexecuting the illegal instruction again - we jump back
|
||
|
+ * using longjmp) -- we have to restore signal delivery, so the
|
||
|
+ * program context is back to normal. Otherwise a second
|
||
|
+ * probe_procedure would not handle SIGILL. */
|
||
|
+ sigset_t sigmask;
|
||
|
+ sigemptyset(&sigmask); sigaddset(&sigmask, sig);
|
||
|
+ sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
|
||
|
longjmp(sigill_jmp, 1);
|
||
|
}
|
||
|
|
||
|
Index: archdep.h
|
||
|
===================================================================
|
||
|
RCS file: /home/cvsroot/dd_rescue/archdep.h,v
|
||
|
retrieving revision 1.6
|
||
|
retrieving revision 1.7
|
||
|
diff -u -p -r1.6 -r1.7
|
||
|
--- archdep.h 25 Feb 2014 16:06:35 -0000 1.6
|
||
|
+++ archdep.h 6 Mar 2014 12:20:46 -0000 1.7
|
||
|
@@ -28,7 +28,7 @@ void probe_sse2();
|
||
|
#define have_avx2 0
|
||
|
#define have_sse42 0
|
||
|
#define ARCH_DETECT do {} while (0)
|
||
|
-#define ARCH_DECLS
|
||
|
+#define ARCH_DECLS ARCH_DECL_386
|
||
|
#elif defined(NO_AVX2) /* compiler does not support -mavx2 */
|
||
|
#define have_avx2 0
|
||
|
extern char have_sse42;
|