about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--include/klee/klee.h6
-rw-r--r--runtime/Intrinsic/klee_is_replay.c15
-rw-r--r--runtime/Runtest/intrinsics.c4
-rw-r--r--test/Replay/libkleeruntest/replay_detection.c33
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