diff options
-rw-r--r-- | lib/Core/ExternalDispatcher.cpp | 17 | ||||
-rw-r--r-- | test/regression/2018-10-01-double-segfault.c | 27 |
2 files changed, 36 insertions, 8 deletions
diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp index c8ebf38a..60bdf711 100644 --- a/lib/Core/ExternalDispatcher.cpp +++ b/lib/Core/ExternalDispatcher.cpp @@ -34,20 +34,20 @@ #include "llvm/IR/CallSite.h" #endif -#include <setjmp.h> -#include <signal.h> +#include <csetjmp> +#include <csignal> using namespace llvm; using namespace klee; /***/ -static jmp_buf escapeCallJmpBuf; +static sigjmp_buf escapeCallJmpBuf; extern "C" { static void sigsegv_handler(int signal, siginfo_t *info, void *context) { - longjmp(escapeCallJmpBuf, 1); + siglongjmp(escapeCallJmpBuf, 1); } } @@ -249,13 +249,14 @@ bool ExternalDispatcherImpl::runProtectedCall(Function *f, uint64_t *args) { std::vector<GenericValue> gvArgs; gTheArgsP = args; - segvAction.sa_handler = 0; - memset(&segvAction.sa_mask, 0, sizeof(segvAction.sa_mask)); + segvAction.sa_handler = nullptr; + sigemptyset(&(segvAction.sa_mask)); + sigaddset(&(segvAction.sa_mask), SIGSEGV); segvAction.sa_flags = SA_SIGINFO; segvAction.sa_sigaction = ::sigsegv_handler; sigaction(SIGSEGV, &segvAction, &segvActionOld); - if (setjmp(escapeCallJmpBuf)) { + if (sigsetjmp(escapeCallJmpBuf, 1)) { res = false; } else { errno = lastErrno; @@ -265,7 +266,7 @@ bool ExternalDispatcherImpl::runProtectedCall(Function *f, uint64_t *args) { res = true; } - sigaction(SIGSEGV, &segvActionOld, 0); + sigaction(SIGSEGV, &segvActionOld, nullptr); return res; } diff --git a/test/regression/2018-10-01-double-segfault.c b/test/regression/2018-10-01-double-segfault.c new file mode 100644 index 00000000..0fa10e8b --- /dev/null +++ b/test/regression/2018-10-01-double-segfault.c @@ -0,0 +1,27 @@ +// REQUIRES: not-asan +// RUN: %llvmgcc %s -emit-llvm -O0 -g -c -o %t.bc +// RUN: rm -rf %t.klee-out +// RUN: %klee -output-dir=%t.klee-out %t.bc 2>&1 | FileCheck %s +// CHECK: failed external call: strdup +// CHECK: failed external call: strdup + +// objective: check handling of more than one failing external call + + +#include "klee/klee.h" + +#include <stdbool.h> +#include <string.h> + +int main(int argc, char * argv[]) { + bool b; + klee_make_symbolic(&b, sizeof(bool), "b"); + + char * s0; + if (b) { + s0 = strdup((char *) 0xdeadbeef); + } else { + s0 = strdup((void *) 0xdeafbee5); + } + (void) s0; +} |