5959#define DEEPSTATE_SIZE 8192
6060#endif
6161
62+ #ifndef DEEPSTATE_CRASH_MAX_FRAMES
63+ #define DEEPSTATE_CRASH_MAX_FRAMES 63
64+ #endif
65+
6266#ifndef DEEPSTATE_MAX_SWARM_CONFIGS
6367#define DEEPSTATE_MAX_SWARM_CONFIGS 1024
6468#endif
@@ -524,21 +528,38 @@ extern void DeepState_SaveFailingTest(void);
524528extern void DeepState_SaveCrashingTest (void );
525529
526530/* Emit test function backtrace after test crashes. */
527- static void DeepState_EmitBacktrace (int signum, siginfo_t *sig, void *context ) {
531+ static void DeepState_EmitBacktrace (int signum, siginfo_t *sig, void *_context ) {
528532
529- DeepState_LogFormat (DeepState_LogInfo, " Test crashed with: %s" , sys_siglist[sig->si_status ]);
533+ /* output information about the signal caught and the exception that occurred */
534+ const char *result;
535+ if (!sig->si_status )
536+ result = sys_siglist[signum];
537+ else
538+ result = sys_siglist[sig->si_status ];
539+ DeepState_LogFormat (DeepState_LogError, " Signal caught in test: %s (error: %d)" , result, sig->si_signo );
530540
531- void *array[ 10 ];
541+ /* return a backtrace */
532542 size_t size;
533- char **strings;
543+ void *back_addrs[DEEPSTATE_CRASH_MAX_FRAMES];
544+ char **symbols;
534545
535- size = backtrace (array, 10 );
536- strings = backtrace_symbols (array, size);
546+ size = backtrace (back_addrs, DEEPSTATE_CRASH_MAX_FRAMES);
547+ if (size == 0 )
548+ DeepState_Abandon (" Cannot retrieve backtrace stack addresses" );
537549
550+ symbols = backtrace_symbols (back_addrs, size);
551+ if (symbols == NULL )
552+ DeepState_Abandon (" Cannot retrieve symbols for stack addresses" );
553+
554+ DeepState_LogFormat (DeepState_LogTrace, " ======= Backtrace: =========" );
538555 for (size_t i = 0 ; i < size; i++)
539- DeepState_LogFormat (DeepState_LogTrace, " %s" , strings[i]);
556+ DeepState_LogFormat (DeepState_LogTrace, " %s" , symbols[i]);
557+ DeepState_LogFormat (DeepState_LogTrace, " ===========================" );
540558
541- free (strings);
559+ /* cleanup resources and exit */
560+ free (symbols);
561+ DeepState_CleanUp ();
562+ exit (DeepState_TestRunCrash);
542563}
543564
544565
@@ -712,19 +733,6 @@ static int DeepState_RunTestNoFork(struct DeepState_TestInfo *test) {
712733/* Fork and run `test`. */
713734static enum DeepState_TestRunResult
714735DeepState_ForkAndRunTest (struct DeepState_TestInfo *test) {
715-
716- /* If flag is set, install a signal handler for SIGCHLD */
717- /* TODO(alan): use handler as "multiplexer" and handle child signal */
718- if (FLAGS_verbose_crash_trace) {
719- struct sigaction sigact, oldact;
720-
721- sigact.sa_flags = SA_SIGINFO | SA_NOCLDWAIT;
722- sigact.sa_sigaction = DeepState_EmitBacktrace;
723-
724- sigaction (SIGCHLD, &sigact, &oldact);
725- }
726-
727-
728736 pid_t test_pid;
729737 if (FLAGS_fork) {
730738 test_pid = fork ();
@@ -737,6 +745,18 @@ DeepState_ForkAndRunTest(struct DeepState_TestInfo *test) {
737745 if (FLAGS_fork) {
738746 waitpid (test_pid, &wstatus, 0 );
739747 } else {
748+
749+ /* If flag is set, install a "multiplexed" signal handler
750+ * in order to backtrace and cleanup without an abrupt exit. */
751+ if (FLAGS_verbose_crash_trace) {
752+ struct sigaction sigact;
753+ sigact.sa_flags = SA_SIGINFO;
754+ sigact.sa_sigaction = DeepState_EmitBacktrace;
755+
756+ for (int i = 0 ; i <= sizeof (sys_siglist); i++)
757+ sigaction (i, &sigact, 0 );
758+ }
759+
740760 wstatus = DeepState_RunTestNoFork (test);
741761 DeepState_CleanUp ();
742762 }
0 commit comments