3636#include < unistd.h>
3737#include < fnmatch.h>
3838#include < execinfo.h>
39+ #include < ucontext.h>
40+
41+ #include < libunwind-ptrace.h>
3942
4043#include < deepstate/Log.h>
4144#include < deepstate/Compiler.h>
5962#define DEEPSTATE_SIZE 8192
6063#endif
6164
65+ #ifndef DEEPSTATE_CRASH_MAX_FRAMES
66+ #define DEEPSTATE_CRASH_MAX_FRAMES 63
67+ #endif
68+
6269#ifndef DEEPSTATE_MAX_SWARM_CONFIGS
6370#define DEEPSTATE_MAX_SWARM_CONFIGS 1024
6471#endif
@@ -524,21 +531,38 @@ extern void DeepState_SaveFailingTest(void);
524531extern void DeepState_SaveCrashingTest (void );
525532
526533/* Emit test function backtrace after test crashes. */
527- static void DeepState_EmitBacktrace (int signum, siginfo_t *sig, void *context) {
534+ static void DeepState_EmitBacktrace (int signum, siginfo_t *sig, void *_context) {
535+
536+ /* output information about the signal caught and the exception that occurred */
537+ const char *result;
538+ if (!sig->si_status )
539+ result = sys_siglist[signum];
540+ else
541+ result = sys_siglist[sig->si_status ];
542+ DeepState_LogFormat (DeepState_LogError, " Signal caught in test: %s (error: %d)" , result, sig->si_signo );
528543
529- DeepState_LogFormat (DeepState_LogInfo, " Test crashed with: %s" , sys_siglist[sig->si_status ]);
544+ ucontext_t *context = (ucontext_t *) _context;
545+ // printf("%lx", context->uc_mcontext.gregs[REG_RIP]);
530546
531- void *array[ 10 ];
547+ /* return a backtrace */
532548 size_t size;
533- char **strings;
549+ void *back_addrs[DEEPSTATE_CRASH_MAX_FRAMES];
550+ char **symbols;
534551
535- size = backtrace (array, 10 );
536- strings = backtrace_symbols (array, size);
552+ size = backtrace (back_addrs, DEEPSTATE_CRASH_MAX_FRAMES);
553+ if (size == 0 )
554+ DeepState_Abandon (" Cannot retrieve backtrace stack addresses" );
537555
556+ symbols = backtrace_symbols (back_addrs, size);
557+ if (symbols == NULL )
558+ DeepState_Abandon (" Cannot retrieve symbols for stack addresses" );
559+
560+ DeepState_LogFormat (DeepState_LogTrace, " ======= Backtrace: =========" );
538561 for (size_t i = 0 ; i < size; i++)
539- DeepState_LogFormat (DeepState_LogTrace, " %s" , strings[i]);
562+ DeepState_LogFormat (DeepState_LogTrace, " %s" , symbols[i]);
563+ DeepState_LogFormat (DeepState_LogTrace, " ===========================" );
540564
541- free (strings );
565+ free (symbols );
542566}
543567
544568
@@ -712,21 +736,18 @@ static int DeepState_RunTestNoFork(struct DeepState_TestInfo *test) {
712736/* Fork and run `test`. */
713737static enum DeepState_TestRunResult
714738DeepState_ForkAndRunTest (struct DeepState_TestInfo *test) {
739+ pid_t test_pid;
740+ if (FLAGS_fork) {
715741
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- }
742+ /* If flag is set, install a signal handler for SIGCHLD */
743+ if (FLAGS_verbose_crash_trace) {
744+ struct sigaction sigact;
745+ sigact.sa_flags = SA_SIGINFO | SA_NODEFER;
746+ sigact.sa_sigaction = DeepState_EmitBacktrace;
726747
748+ sigaction (SIGCHLD, &sigact, 0 );
749+ }
727750
728- pid_t test_pid;
729- if (FLAGS_fork) {
730751 test_pid = fork ();
731752 if (!test_pid) {
732753 DeepState_RunTest (test);
@@ -737,6 +758,8 @@ DeepState_ForkAndRunTest(struct DeepState_TestInfo *test) {
737758 if (FLAGS_fork) {
738759 waitpid (test_pid, &wstatus, 0 );
739760 } else {
761+
762+ /* TODO: install multiplexer signal handler, since we need to handle more than SIGCHLD */
740763 wstatus = DeepState_RunTestNoFork (test);
741764 DeepState_CleanUp ();
742765 }
0 commit comments