Skip to content

Commit 5e9d0d3

Browse files
author
ex0dus-0x
committed
Improve backtrace routine
1 parent 862c725 commit 5e9d0d3

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

src/include/deepstate/DeepState.h

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
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);
524528
extern 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`. */
713734
static enum DeepState_TestRunResult
714735
DeepState_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
}

src/lib/DeepState.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ DEFINE_bool(abort_on_fail, ExecutionGroup, false, "Abort on file replay failure
4343
DEFINE_bool(exit_on_fail, ExecutionGroup, false, "Exit with status 255 on test failure.");
4444
DEFINE_int(min_log_level, ExecutionGroup, 0, "Minimum level of logging to output (default 2, 0=debug, 1=trace, 2=info, ...).");
4545
DEFINE_int(timeout, ExecutionGroup, 120, "Timeout for brute force fuzzing.");
46-
DEFINE_uint(num_workers, ExecutionGroup, 1, "Number of workers to spawn for testing and test generation.");
4746
DEFINE_bool(verbose_reads, ExecutionGroup, false, "Report on bytes being read during execution of test.");
48-
DEFINE_bool(verbose_crash_trace, ExecutionGroup, false, "If test crashes, report an execution backtrace after abrupt exit.");
47+
DEFINE_bool(verbose_crash_trace, ExecutionGroup, false, "If unforked test crashes, report crash information and backtrace.");
4948

5049
/* Fuzzing and symex related options, baked in to perform analysis-related tasks without auxiliary tools */
5150
DEFINE_bool(fuzz, AnalysisGroup, false, "Perform brute force unguided fuzzing.");

0 commit comments

Comments
 (0)