diff options
author | Tristan Gingold <gingold@adacore.com> | 2009-04-10 13:07:23 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2009-04-10 13:07:23 +0200 |
commit | 2436ca9ee8f3bab11e16594f590f4aefc82ea95e (patch) | |
tree | f6b2fe32b4e05f855cff53e7876d1674c7628219 /gcc/ada/init.c | |
parent | c5288c909bc01b5df59bbf9334af6bac1fe93a2c (diff) | |
download | gcc-2436ca9ee8f3bab11e16594f590f4aefc82ea95e.tar.gz |
init.c: Install signal handler on Darwin.
2009-04-10 Tristan Gingold <gingold@adacore.com>
* init.c: Install signal handler on Darwin.
From-SVN: r145888
Diffstat (limited to 'gcc/ada/init.c')
-rw-r--r-- | gcc/ada/init.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/gcc/ada/init.c b/gcc/ada/init.c index 324c22e147a..1b6952719a1 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -2083,6 +2083,76 @@ __gnat_install_handler(void) __gnat_handler_installed = 1; } +/******************/ +/* Darwin Section */ +/******************/ + +#elif defined(__APPLE__) + +#include <signal.h> + +static void __gnat_error_handler (int sig, siginfo_t * si, void * uc); + +static void +__gnat_error_handler (int sig, siginfo_t * si, void * uc) +{ + struct Exception_Data *exception; + const char *msg; + + switch (sig) + { + case SIGSEGV: + /* FIXME: we need to detect the case of a *real* SIGSEGV. */ + exception = &storage_error; + msg = "stack overflow or erroneous memory access"; + break; + + case SIGBUS: + exception = &constraint_error; + msg = "SIGBUS"; + break; + + case SIGFPE: + exception = &constraint_error; + msg = "SIGFPE"; + break; + + default: + exception = &program_error; + msg = "unhandled signal"; + } + + Raise_From_Signal_Handler (exception, msg); +} + +void +__gnat_install_handler (void) +{ + struct sigaction act; + + /* Set up signal handler to map synchronous signals to appropriate + exceptions. Make sure that the handler isn't interrupted by another + signal that might cause a scheduling event! */ + + act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO; + act.sa_sigaction = __gnat_error_handler; + sigemptyset (&act.sa_mask); + + /* Do not install handlers if interrupt state is "System". */ + if (__gnat_get_interrupt_state (SIGABRT) != 's') + sigaction (SIGABRT, &act, NULL); + if (__gnat_get_interrupt_state (SIGFPE) != 's') + sigaction (SIGFPE, &act, NULL); + if (__gnat_get_interrupt_state (SIGILL) != 's') + sigaction (SIGILL, &act, NULL); + if (__gnat_get_interrupt_state (SIGSEGV) != 's') + sigaction (SIGSEGV, &act, NULL); + if (__gnat_get_interrupt_state (SIGBUS) != 's') + sigaction (SIGBUS, &act, NULL); + + __gnat_handler_installed = 1; +} + #else /* For all other versions of GNAT, the handler does nothing. */ |