diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 2dc7199e..b1cb341f 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -529,23 +529,24 @@ extern void DeepState_SaveFailingTest(void); extern void DeepState_SaveCrashingTest(void); /* Emit test function backtrace after test crashes. */ -static void DeepState_EmitBacktrace(int signum, siginfo_t *sig, void *context) { +static void DeepState_EmitBacktrace(int signum, siginfo_t *sig, void *_context) { + /* output information about the signal caught and the exception that occurred */ const char *result; if (!sig->si_status) result = sys_siglist[signum]; else result = sys_siglist[sig->si_status]; + DeepState_LogFormat(DeepState_LogError, "Signal caught in test: %s (%d)", result, sig->si_signo); - DeepState_LogFormat(DeepState_LogInfo, "Test crashed with: %s", result); - - // TODO: add line number of crash (ie. addr2line) + ucontext_t *context = (ucontext_t *) _context; + //printf("%lx", context->uc_mcontext.gregs[REG_EIP]); + /* return a backtrace */ + size_t size; void *back_addrs[DEEPSTATE_CRASH_MAX_FRAMES]; char **symbols; - size_t size; - size = backtrace(back_addrs, DEEPSTATE_CRASH_MAX_FRAMES); if (size == 0) DeepState_Abandon("Cannot retrieve backtrace stack addresses"); @@ -554,8 +555,6 @@ static void DeepState_EmitBacktrace(int signum, siginfo_t *sig, void *context) { if (symbols == NULL) DeepState_Abandon("Cannot retrieve symbols for stack addresses"); - // TODO: demangle and resolve, also do for Darwin/BSD - DeepState_LogFormat(DeepState_LogTrace, "======= Backtrace: ========="); for (size_t i = 0; i < size; i++) DeepState_LogFormat(DeepState_LogTrace, "%s", symbols[i]); @@ -740,12 +739,11 @@ DeepState_ForkAndRunTest(struct DeepState_TestInfo *test) { /* If flag is set, install a signal handler for SIGCHLD */ if (FLAGS_verbose_crash_trace) { - struct sigaction sigact, oldact; - - sigact.sa_flags = SA_SIGINFO | SA_NOCLDWAIT; + struct sigaction sigact; + sigact.sa_flags = SA_SIGINFO | SA_NODEFER; sigact.sa_sigaction = DeepState_EmitBacktrace; - sigaction(SIGCHLD, &sigact, &oldact); + sigaction(SIGCHLD, &sigact, 0); } test_pid = fork(); @@ -759,18 +757,7 @@ DeepState_ForkAndRunTest(struct DeepState_TestInfo *test) { waitpid(test_pid, &wstatus, 0); } else { - /* If flag is set, install a signal handler for any arbitrary crash*/ - if (FLAGS_verbose_crash_trace) { - - struct sigaction sigact, oldact; - - sigact.sa_flags = SA_SIGINFO | SA_NODEFER; - sigact.sa_sigaction = DeepState_EmitBacktrace; - - sigaction(SIGBUS, &sigact, &oldact); - sigaction(SIGSEGV, &sigact, &oldact); - } - + /* TODO: install multiplexer signal handler, since we need to handle more than SIGCHLD */ wstatus = DeepState_RunTestNoFork(test); DeepState_CleanUp(); } diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 64ecc141..fa553b68 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#define __USE_GNU + #include "deepstate/DeepState.h" #include "deepstate/Option.h" #include "deepstate/Log.h" @@ -44,7 +46,7 @@ DEFINE_bool(exit_on_fail, ExecutionGroup, false, "Exit with status 255 on test f DEFINE_int(min_log_level, ExecutionGroup, 0, "Minimum level of logging to output (default 2, 0=debug, 1=trace, 2=info, ...)."); DEFINE_int(timeout, ExecutionGroup, 120, "Timeout for brute force fuzzing."); DEFINE_bool(verbose_reads, ExecutionGroup, false, "Report on bytes being read during execution of test."); -DEFINE_bool(verbose_crash_trace, ExecutionGroup, false, "If test crashes, report an execution backtrace after abrupt exit."); +DEFINE_bool(verbose_crash_trace, ExecutionGroup, false, "If test crashes on a fork, report an execution backtrace after abrupt exit."); /* Fuzzing and symex related options, baked in to perform analysis-related tasks without auxiliary tools */ DEFINE_bool(fuzz, AnalysisGroup, false, "Perform brute force unguided fuzzing.");