@@ -23,6 +23,7 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do
2323
2424#include " pal/corunix.hpp"
2525#include " pal/handleapi.hpp"
26+ #include " pal/process.h"
2627#include " pal/thread.hpp"
2728#include " pal/threadinfo.hpp"
2829#include " pal/threadsusp.hpp"
@@ -36,7 +37,6 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do
3637
3738#if !HAVE_MACH_EXCEPTIONS
3839#include " pal/init.h"
39- #include " pal/process.h"
4040#include " pal/debug.h"
4141#include " pal/virtual.h"
4242#include " pal/utils.h"
@@ -62,12 +62,6 @@ using namespace CorUnix;
6262
6363/* local type definitions *****************************************************/
6464
65- #if !HAVE_SIGINFO_T
66- /* This allows us to compile on platforms that don't have siginfo_t.
67- * Exceptions will work poorly on those platforms. */
68- #warning Exceptions will work poorly on this platform
69- typedef void *siginfo_t ;
70- #endif /* !HAVE_SIGINFO_T */
7165typedef void (*SIGFUNC )(int , siginfo_t *, void *);
7266
7367/* internal function declarations *********************************************/
@@ -91,6 +85,7 @@ static void inject_activation_handler(int code, siginfo_t *siginfo, void *contex
9185
9286static void handle_signal (int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction, int additionalFlags = 0 , bool skipIgnored = false );
9387static void restore_signal (int signal_id, struct sigaction *previousAction);
88+ static void restore_signal_and_resend (int code, struct sigaction * action);
9489
9590/* internal data declarations *********************************************/
9691
@@ -240,6 +235,68 @@ void SEHCleanupSignals()
240235/* internal function definitions **********************************************/
241236
242237#if !HAVE_MACH_EXCEPTIONS
238+ /* ++
239+ Function :
240+ invoke_previous_action
241+
242+ synchronously invokes the previous action or aborts when that is not possible
243+
244+ Parameters :
245+ action : previous sigaction struct
246+ code : signal code
247+ siginfo : signal siginfo
248+ context : signal context
249+ signalRestarts: BOOL state : TRUE if the process will be signalled again
250+
251+ (no return value)
252+ --*/
253+ static void invoke_previous_action (struct sigaction * action, int code, siginfo_t *siginfo, void *context, bool signalRestarts = true )
254+ {
255+ _ASSERTE (action != NULL );
256+
257+ if (action->sa_flags & SA_SIGINFO )
258+ {
259+ // Directly call the previous handler.
260+ _ASSERTE (action->sa_sigaction != NULL );
261+ action->sa_sigaction (code, siginfo, context);
262+ }
263+ else
264+ {
265+ if (action->sa_handler == SIG_IGN )
266+ {
267+ if (signalRestarts)
268+ {
269+ // This signal mustn't be ignored because it will be restarted.
270+ PROCAbort ();
271+ }
272+ return ;
273+ }
274+ else if (action->sa_handler == SIG_DFL )
275+ {
276+ if (signalRestarts)
277+ {
278+ // Restore the original and restart h/w exception.
279+ restore_signal (code, action);
280+ }
281+ else
282+ {
283+ // We can't invoke the original handler because returning from the
284+ // handler doesn't restart the exception.
285+ PROCAbort ();
286+ }
287+ }
288+ else
289+ {
290+ // Directly call the previous handler.
291+ _ASSERTE (action->sa_handler != NULL );
292+ action->sa_handler (code);
293+ }
294+ }
295+
296+ PROCNotifyProcessShutdown ();
297+ PROCCreateCrashDumpIfEnabled ();
298+ }
299+
243300/* ++
244301Function :
245302 sigill_handler
@@ -261,18 +318,7 @@ static void sigill_handler(int code, siginfo_t *siginfo, void *context)
261318 }
262319 }
263320
264- if (g_previous_sigill.sa_sigaction != NULL )
265- {
266- g_previous_sigill.sa_sigaction (code, siginfo, context);
267- }
268- else
269- {
270- // Restore the original or default handler and restart h/w exception
271- restore_signal (code, &g_previous_sigill);
272- }
273-
274- PROCNotifyProcessShutdown ();
275- PROCCreateCrashDumpIfEnabled ();
321+ invoke_previous_action (&g_previous_sigill, code, siginfo, context);
276322}
277323
278324/* ++
@@ -296,18 +342,7 @@ static void sigfpe_handler(int code, siginfo_t *siginfo, void *context)
296342 }
297343 }
298344
299- if (g_previous_sigfpe.sa_sigaction != NULL )
300- {
301- g_previous_sigfpe.sa_sigaction (code, siginfo, context);
302- }
303- else
304- {
305- // Restore the original or default handler and restart h/w exception
306- restore_signal (code, &g_previous_sigfpe);
307- }
308-
309- PROCNotifyProcessShutdown ();
310- PROCCreateCrashDumpIfEnabled ();
345+ invoke_previous_action (&g_previous_sigfpe, code, siginfo, context);
311346}
312347
313348/* ++
@@ -418,18 +453,7 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
418453 }
419454 }
420455
421- if (g_previous_sigsegv.sa_sigaction != NULL )
422- {
423- g_previous_sigsegv.sa_sigaction (code, siginfo, context);
424- }
425- else
426- {
427- // Restore the original or default handler and restart h/w exception
428- restore_signal (code, &g_previous_sigsegv);
429- }
430-
431- PROCNotifyProcessShutdown ();
432- PROCCreateCrashDumpIfEnabled ();
456+ invoke_previous_action (&g_previous_sigsegv, code, siginfo, context);
433457}
434458
435459/* ++
@@ -453,19 +477,8 @@ static void sigtrap_handler(int code, siginfo_t *siginfo, void *context)
453477 }
454478 }
455479
456- if (g_previous_sigtrap.sa_sigaction != NULL )
457- {
458- g_previous_sigtrap.sa_sigaction (code, siginfo, context);
459- }
460- else
461- {
462- // We abort instead of restore the original or default handler and returning
463- // because returning from a SIGTRAP handler continues execution past the trap.
464- PROCAbort ();
465- }
466-
467- PROCNotifyProcessShutdown ();
468- PROCCreateCrashDumpIfEnabled ();
480+ // The signal doesn't restart, returning from a SIGTRAP handler continues execution past the trap.
481+ invoke_previous_action (&g_previous_sigtrap, code, siginfo, context, /* signalRestarts */ false );
469482}
470483
471484/* ++
@@ -492,18 +505,7 @@ static void sigbus_handler(int code, siginfo_t *siginfo, void *context)
492505 }
493506 }
494507
495- if (g_previous_sigbus.sa_sigaction != NULL )
496- {
497- g_previous_sigbus.sa_sigaction (code, siginfo, context);
498- }
499- else
500- {
501- // Restore the original or default handler and restart h/w exception
502- restore_signal (code, &g_previous_sigbus);
503- }
504-
505- PROCNotifyProcessShutdown ();
506- PROCCreateCrashDumpIfEnabled ();
508+ invoke_previous_action (&g_previous_sigbus, code, siginfo, context);
507509}
508510
509511/* ++
@@ -521,9 +523,7 @@ static void sigint_handler(int code, siginfo_t *siginfo, void *context)
521523{
522524 PROCNotifyProcessShutdown ();
523525
524- // Restore the original or default handler and resend signal
525- restore_signal (code, &g_previous_sigint);
526- kill (gPID , code);
526+ restore_signal_and_resend (code, &g_previous_sigint);
527527}
528528
529529/* ++
@@ -541,9 +541,7 @@ static void sigquit_handler(int code, siginfo_t *siginfo, void *context)
541541{
542542 PROCNotifyProcessShutdown ();
543543
544- // Restore the original or default handler and resend signal
545- restore_signal (code, &g_previous_sigquit);
546- kill (gPID , code);
544+ restore_signal_and_resend (code, &g_previous_sigquit);
547545}
548546#endif // !HAVE_MACH_EXCEPTIONS
549547
@@ -569,10 +567,7 @@ static void sigterm_handler(int code, siginfo_t *siginfo, void *context)
569567 }
570568 else
571569 {
572- if (g_previous_sigterm.sa_sigaction != NULL )
573- {
574- g_previous_sigterm.sa_sigaction (code, siginfo, context);
575- }
570+ restore_signal_and_resend (SIGTERM , &g_previous_sigterm);
576571 }
577572}
578573
@@ -612,9 +607,23 @@ static void inject_activation_handler(int code, siginfo_t *siginfo, void *contex
612607 CONTEXTToNativeContext (&winContext, ucontext);
613608 }
614609 }
615- else if (g_previous_activation. sa_sigaction != NULL )
610+ else
616611 {
617- g_previous_activation.sa_sigaction (code, siginfo, context);
612+ // Call the original handler when it is not ignored or default (terminate).
613+ if (g_previous_activation.sa_flags & SA_SIGINFO )
614+ {
615+ _ASSERTE (g_previous_activation.sa_sigaction != NULL );
616+ g_previous_activation.sa_sigaction (code, siginfo, context);
617+ }
618+ else
619+ {
620+ if (g_previous_activation.sa_handler != SIG_IGN &&
621+ g_previous_activation.sa_handler != SIG_DFL )
622+ {
623+ _ASSERTE (g_previous_activation.sa_handler != NULL );
624+ g_previous_activation.sa_handler (code);
625+ }
626+ }
618627 }
619628}
620629#endif
@@ -832,13 +841,9 @@ void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAct
832841 struct sigaction newAction;
833842
834843 newAction.sa_flags = SA_RESTART | additionalFlags;
835- #if HAVE_SIGINFO_T
836844 newAction.sa_handler = NULL ;
837845 newAction.sa_sigaction = sigfunc;
838846 newAction.sa_flags |= SA_SIGINFO ;
839- #else /* HAVE_SIGINFO_T */
840- newAction.sa_handler = SIG_DFL ;
841- #endif /* HAVE_SIGINFO_T */
842847 sigemptyset (&newAction.sa_mask );
843848
844849#ifdef INJECT_ACTIVATION_SIGNAL
@@ -891,3 +896,21 @@ void restore_signal(int signal_id, struct sigaction *previousAction)
891896 errno, strerror (errno));
892897 }
893898}
899+
900+ /* ++
901+ Function :
902+ restore_signal_and_resend
903+
904+ restore handler for specified signal and signal the process
905+
906+ Parameters :
907+ int signal_id : signal to handle
908+ previousAction : previous sigaction struct to restore
909+
910+ (no return value)
911+ --*/
912+ void restore_signal_and_resend (int signal_id, struct sigaction * previousAction)
913+ {
914+ restore_signal (signal_id, previousAction);
915+ kill (gPID , signal_id);
916+ }
0 commit comments