diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2004-02-20 12:55:27 +0100 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2004-02-20 12:55:27 +0100 |
commit | 6e059adb240df3f9918401dbacca61c283e618ed (patch) | |
tree | 090dd01dc14b79f968d8f244e3b4dc22b2c55e6b /gcc/ada/init.c | |
parent | d80d3d962235927d1c27c624852f54f80db7bccf (diff) | |
download | gcc-6e059adb240df3f9918401dbacca61c283e618ed.zip gcc-6e059adb240df3f9918401dbacca61c283e618ed.tar.gz gcc-6e059adb240df3f9918401dbacca61c283e618ed.tar.bz2 |
[multiple changes]
2004-02-20 Robert Dewar <dewar@gnat.com>
* bld.adb, exp_util.adb, gprcmd.adb: Minor reformatting
2004-02-20 Ed Schonberg <schonberg@gnat.com>
* freeze.adb (Freeze_Record_Type): Generalize mechanism that generates
itype references for the constrained designated type of a component
whose base type is already frozen.
2004-02-20 Arnaud Charlet <charlet@act-europe.fr>
* init.c (__gnat_error_handler [tru64]): Rewrite previous change to
avoid GCC warnings.
2004-02-20 Sergey Rybin <rybin@act-europe.fr>
* sem_ch12.adb (Analyze_Formal_Package): Create a new defining
identifier for a phantom package that rewrites the formal package
declaration with a box. The Add semantic decorations for the defining
identifier from the original node (that represents the formal package).
From-SVN: r78164
Diffstat (limited to 'gcc/ada/init.c')
-rw-r--r-- | gcc/ada/init.c | 81 |
1 files changed, 39 insertions, 42 deletions
diff --git a/gcc/ada/init.c b/gcc/ada/init.c index 7db7f1f..f160255 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -388,6 +388,7 @@ __gnat_error_handler (int sig, siginfo_t *sip, struct sigcontext *context) static int recurse = 0; struct sigcontext *mstate; const char *msg; + jmp_buf handler_jmpbuf; /* If this was an explicit signal from a "kill", just resignal it. */ if (SI_FROMUSER (sip)) @@ -397,6 +398,43 @@ __gnat_error_handler (int sig, siginfo_t *sip, struct sigcontext *context) } /* Otherwise, treat it as something we handle. */ + + /* We are now going to raise the exception corresponding to the signal we + caught, which may eventually end up resuming the application code if the + exception is handled. + + When the exception is handled, merely arranging for the *exception* + handler's context (stack pointer, program counter, other registers, ...) + to be installed is *not* enough to let the kernel think we've left the + *signal* handler. This has annoying implications if an alternate stack + has been setup for this *signal* handler, because the kernel thinks we + are still running on that alternate stack even after the jump, which + causes trouble at least as soon as another signal is raised. + + We deal with this by forcing a "local" longjmp within the signal handler + below, forcing the "on alternate stack" indication to be reset (kernel + wise) on the way. If no alternate stack has been setup, this should be a + neutral operation. Otherwise, we will be in a delicate situation for a + short while because we are going to run the exception propagation code + within the alternate stack area (that is, with the stack pointer inside + the alternate stack bounds), but with the corresponding flag off from the + kernel's standpoint. We expect this to be ok as long as the propagation + code does not trigger a signal itself, which is expected. + + ??? A better approach would be to at least delay this operation until the + last second, that is, until just before we jump to the exception handler, + if any. */ + + if (setjmp (handler_jmpbuf) == 0) + { +#define JB_ONSIGSTK 0 + + /* Arrange for the "on alternate stack" flag to be reset. See the + comments around "jmp_buf offsets" in /usr/include/setjmp.h. */ + handler_jmpbuf [JB_ONSIGSTK] = 0; + longjmp (handler_jmpbuf, 1); + } + switch (sig) { case SIGSEGV: @@ -448,48 +486,7 @@ __gnat_error_handler (int sig, siginfo_t *sip, struct sigcontext *context) if (mstate != 0) *mstate = *context; - /* We are now going to raise the exception corresponding to the signal we - caught, which may eventually end up resuming the application code if the - exception is handled. - - When the exception is handled, merely arranging for the *exception* - handler's context (stack pointer, program counter, other registers, ...) - to be installed is *not* enough to let the kernel think we've left the - *signal* handler. This has annoying implications if an alternate stack - has been setup for this *signal* handler, because the kernel thinks we - are still running on that alternate stack even after the jump, which - causes trouble at least as soon as another signal is raised. - - We deal with this by forcing a "local" longjmp within the signal handler - below, forcing the "on alternate stack" indication to be reset (kernel - wise) on the way. If no alternate stack has been setup, this should be a - neutral operation. Otherwise, we will be in a delicate situation for a - short while because we are going to run the exception propagation code - within the alternate stack area (that is, with the stack pointer inside - the alternate stack bounds), but with the corresponding flag off from the - kernel's standpoint. We expect this to be ok as long as the propagation - code does not trigger a signal itself, which is expected. - - ??? A better approach would be to at least delay this operation until the - last second, that is, until just before we jump to the exception handler, - if any. */ - { - jmp_buf handler_jmpbuf; - - if (setjmp (handler_jmpbuf) != 0) - Raise_From_Signal_Handler (exception, (char *) msg); - else - { - /* Arrange for the "on alternate stack" flag to be reset. See the - comments around "jmp_buf offsets" in /usr/include/setjmp.h. */ - struct sigcontext * handler_context - = (struct sigcontext *) & handler_jmpbuf; - - handler_context->sc_onstack = 0; - - longjmp (handler_jmpbuf, 1); - } - } + Raise_From_Signal_Handler (exception, (char *) msg); } void |