diff options
-rw-r--r-- | include/klee/klee.h | 6 | ||||
-rw-r--r-- | runtime/Intrinsic/klee_is_replay.c | 15 | ||||
-rw-r--r-- | runtime/Runtest/intrinsics.c | 4 | ||||
-rw-r--r-- | test/Replay/libkleeruntest/replay_detection.c | 33 |
4 files changed, 58 insertions, 0 deletions
diff --git a/include/klee/klee.h b/include/klee/klee.h index 99fe15c7..fafdd55f 100644 --- a/include/klee/klee.h +++ b/include/klee/klee.h @@ -103,6 +103,12 @@ extern "C" { unsigned klee_is_symbolic(uintptr_t n); + /* Return true if replaying a concrete test case using the libkleeRuntime library + * Return false if executing symbolically in KLEE. + */ + unsigned klee_is_replay(); + + /* The following intrinsics are primarily intended for internal use and may have peculiar semantics. */ diff --git a/runtime/Intrinsic/klee_is_replay.c b/runtime/Intrinsic/klee_is_replay.c new file mode 100644 index 00000000..ac9e541d --- /dev/null +++ b/runtime/Intrinsic/klee_is_replay.c @@ -0,0 +1,15 @@ + +/*===-- klee_is_replay.c --------------------------------------------------===// +// +// The KLEE Symbolic Virtual Machine +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===*/ + +#include "klee/klee.h" + +unsigned klee_is_replay() { + return 0; +} diff --git a/runtime/Runtest/intrinsics.c b/runtime/Runtest/intrinsics.c index cdc8c9d6..f82bd554 100644 --- a/runtime/Runtest/intrinsics.c +++ b/runtime/Runtest/intrinsics.c @@ -146,6 +146,10 @@ uintptr_t klee_choose(uintptr_t n) { return x; } +unsigned klee_is_replay() { + return 1; +} + void klee_assume(uintptr_t x) { if (!x) { report_internal_error("invalid klee_assume"); diff --git a/test/Replay/libkleeruntest/replay_detection.c b/test/Replay/libkleeruntest/replay_detection.c new file mode 100644 index 00000000..7516ecd1 --- /dev/null +++ b/test/Replay/libkleeruntest/replay_detection.c @@ -0,0 +1,33 @@ +// RUN: %clang %s -emit-llvm -g %O0opt -c -o %t.bc +// RUN: rm -rf %t.klee-out +// RUN: %klee --output-dir=%t.klee-out %t.bc +// +// There should be a unique solution +// RUN: test -f %t.klee-out/test000001.ktest +// RUN: test ! -f %t.klee-out/test000002.ktest + +// Now try to replay with libkleeRuntest +// RUN: %cc %s %libkleeruntest -Wl,-rpath %libkleeruntestdir -o %t_runner +// RUN: env KTEST_FILE=%t.klee-out/test000001.ktest %t_runner | FileCheck %s + +#include "klee/klee.h" +#include <stdio.h> + +int main(int argc, char** argv) { + int x = 0; + klee_make_symbolic(&x, sizeof(x), "x"); + + if (klee_is_replay()) { // only print x on replay runs + printf("x = %d\n", x); + } + + // For the sake of testing, these constraints have a single solution + klee_assume(40 < x); + klee_assume(x < 43); + klee_assume((x & 1) == 0); + + return 0; +} + +// When replaying, it should print the concrete value it is running with +// CHECK: x = 42 |