summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5detect.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/src/H5detect.c b/src/H5detect.c
index 3554d50..0f8d051 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -60,9 +60,9 @@ static const char *FileHeader = "\n\
#define MAXDETECT 64
-/* The ALIGNMENT test code may generate the SIGBUS or SIGSEGV signals. We use
- * setjmp/longjmp in the signal handlers for recovery. But setjmp/longjmp do
- * not necessary restore the signal blocking status while sigsetjmp/siglongjmp
+/* The ALIGNMENT test code may generate the SIGBUS, SIGSEGV, or SIGILL signals.
+ * We use setjmp/longjmp in the signal handlers for recovery. But setjmp/longjmp
+ * do not necessary restore the signal blocking status while sigsetjmp/siglongjmp
* do. If sigsetjmp/siglongjmp are not supported, need to use sigprocmask to
* unblock the signal before doing longjmp.
*/
@@ -139,7 +139,8 @@ static void detect_alignments(void);
static size_t align_g[] = {1, 2, 4, 8, 16};
static int align_status_g = 0; /* ALIGNMENT Signal Status */
static int sigbus_handler_called_g = 0; /* how many times called */
-static int sigsegv_handler_called_g = 0; /* how many times called */
+static int sigsegv_handler_called_g = 0;/* how many times called */
+static int sigill_handler_called_g = 0; /* how many times called */
static int signal_handler_tested_g = 0; /* how many times tested */
#if defined(H5SETJMP) && defined(H5_HAVE_SIGNAL)
static int verify_signal_handlers(int signum, void (*handler)(int));
@@ -425,6 +426,7 @@ precision (detected_t *d)
volatile size_t _ano = 0; \
void (*_handler)(int) = HDsignal(SIGBUS, sigbus_handler); \
void (*_handler2)(int) = HDsignal(SIGSEGV, sigsegv_handler);\
+ void (*_handler3)(int) = HDsignal(SIGILL, sigill_handler); \
\
_buf = (char*)HDmalloc(sizeof(TYPE) + align_g[NELMTS(align_g) - 1]); \
if(H5SETJMP(jbuf_g)) _ano++; \
@@ -454,6 +456,7 @@ precision (detected_t *d)
HDfree(_buf); \
HDsignal(SIGBUS, _handler); /*restore original handler*/ \
HDsignal(SIGSEGV, _handler2); /*restore original handler*/ \
+ HDsignal(SIGILL, _handler3); /*restore original handler*/ \
}
#else
#define ALIGNMENT(TYPE,INFO) { \
@@ -539,6 +542,42 @@ sigbus_handler(int UNUSED signo)
#endif
+#if defined(H5LONGJMP) && defined(H5_HAVE_SIGNAL)
+/*-------------------------------------------------------------------------
+ * Function: sigill_handler
+ *
+ * Purpose: Handler for SIGILL. We use signal() instead of sigaction()
+ * because it's more portable to non-Posix systems. Although
+ * it's not nearly as nice to work with, it does the job for
+ * this simple stuff.
+ *
+ * Return: Returns via H5LONGJMP to jbuf_g.
+ *
+ * Programmer: Raymond Lu
+ * 28 October 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+sigill_handler(int UNUSED signo)
+{
+#if !defined(H5HAVE_SIGJMP) && defined(H5_HAVE_SIGPROCMASK)
+ /* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
+ /* supported. */
+ sigset_t set;
+
+ HDsigemptyset(&set);
+ HDsigaddset(&set, SIGILL);
+ HDsigprocmask(SIG_UNBLOCK, &set, NULL);
+#endif
+
+ sigill_handler_called_g++;
+ HDsignal(SIGILL, sigill_handler);
+ H5LONGJMP(jbuf_g, SIGILL);
+}
+#endif
+
+
/*-------------------------------------------------------------------------
* Function: print_results
*