about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--lib/Core/Executor.cpp607
1 files changed, 315 insertions, 292 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index c7d88c2c..9b2c1b0a 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -8,8 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "Executor.h"
+
+#include "../Expr/ArrayExprOptimizer.h"
 #include "Context.h"
 #include "CoreStats.h"
+#include "ExecutorTimerInfo.h"
 #include "ExternalDispatcher.h"
 #include "ImpliedValue.h"
 #include "Memory.h"
@@ -21,21 +24,11 @@
 #include "StatsTracker.h"
 #include "TimingSolver.h"
 #include "UserSearcher.h"
-#include "ExecutorTimerInfo.h"
 
-
-#include "klee/ExecutionState.h"
-#include "klee/Expr.h"
-#include "klee/Interpreter.h"
-#include "klee/TimerStatIncrementer.h"
-#include "klee/SolverCmdLine.h"
 #include "klee/Common.h"
-#include "klee/util/Assignment.h"
-#include "klee/util/ExprPPrinter.h"
-#include "klee/util/ExprSMTLIBPrinter.h"
-#include "klee/util/ExprUtil.h"
-#include "klee/util/GetElementPtrTypeIterator.h"
 #include "klee/Config/Version.h"
+#include "klee/ExecutionState.h"
+#include "klee/Expr.h"
 #include "klee/Internal/ADT/KTest.h"
 #include "klee/Internal/ADT/RNG.h"
 #include "klee/Internal/Module/Cell.h"
@@ -46,12 +39,19 @@
 #include "klee/Internal/Support/FileHandling.h"
 #include "klee/Internal/Support/FloatEvaluation.h"
 #include "klee/Internal/Support/ModuleUtil.h"
-#include "klee/Internal/System/Time.h"
 #include "klee/Internal/System/MemoryUsage.h"
+#include "klee/Internal/System/Time.h"
+#include "klee/Interpreter.h"
 #include "klee/OptionCategories.h"
+#include "klee/SolverCmdLine.h"
 #include "klee/SolverStats.h"
+#include "klee/TimerStatIncrementer.h"
+#include "klee/util/Assignment.h"
+#include "klee/util/ExprPPrinter.h"
+#include "klee/util/ExprSMTLIBPrinter.h"
+#include "klee/util/ExprUtil.h"
+#include "klee/util/GetElementPtrTypeIterator.h"
 
-#include "../Expr/ArrayExprOptimizer.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Attributes.h"
@@ -76,307 +76,330 @@
 #include "llvm/IR/CallSite.h"
 #endif
 
-#include <cassert>
 #include <algorithm>
+#include <cassert>
+#include <cerrno>
+#include <cxxabi.h>
+#include <fstream>
 #include <iomanip>
 #include <iosfwd>
-#include <fstream>
 #include <sstream>
-#include <vector>
 #include <string>
-
 #include <sys/mman.h>
-
-#include <errno.h>
-#include <cxxabi.h>
+#include <vector>
 
 using namespace llvm;
 using namespace klee;
 
-
 namespace {
 
-  /*** Test generation options ***/
-
-  cl::OptionCategory TestGenCat("Test generation options",
-                                "These options impact test generation.");
-
-  cl::opt<bool>
-  DumpStatesOnHalt("dump-states-on-halt",
-                   cl::init(true),
-		   cl::desc("Dump test cases for all active states on exit (default=true)"),
-                   cl::cat(TestGenCat));
-
-  cl::opt<bool>
-  OnlyOutputStatesCoveringNew("only-output-states-covering-new",
-                              cl::init(false),
-			      cl::desc("Only output test cases covering new code (default=false)."),
-                              cl::cat(TestGenCat));
-
-  cl::opt<bool>
-  EmitAllErrors("emit-all-errors",
-                cl::init(false),
-                cl::desc("Generate tests cases for all errors "
-                         "(default=false, i.e. one per (error,instruction) pair)"),
-                cl::cat(TestGenCat));
-
-
+/*** Test generation options ***/
+
+cl::OptionCategory TestGenCat("Test generation options",
+                              "These options impact test generation.");
+
+cl::opt<bool> DumpStatesOnHalt(
+    "dump-states-on-halt",
+    cl::init(true),
+    cl::desc("Dump test cases for all active states on exit (default=true)"),
+    cl::cat(TestGenCat));
+
+cl::opt<bool> OnlyOutputStatesCoveringNew(
+    "only-output-states-covering-new",
+    cl::init(false),
+    cl::desc("Only output test cases covering new code (default=false)"),
+    cl::cat(TestGenCat));
+
+cl::opt<bool> EmitAllErrors(
+    "emit-all-errors", cl::init(false),
+    cl::desc("Generate tests cases for all errors "
+             "(default=false, i.e. one per (error,instruction) pair)"),
+    cl::cat(TestGenCat));
+
+
+/* Constraint solving options */
+
+cl::opt<unsigned> MaxSymArraySize(
+    "max-sym-array-size",
+    cl::desc(
+        "If a symbolic array exceeds this size (in bytes), symbolic addresses "
+        "into this array are concretized.  Set to 0 to disable (default=0)"),
+    cl::init(0),
+    cl::cat(SolvingCat));
+
+cl::opt<bool>
+    SimplifySymIndices("simplify-sym-indices",
+                       cl::init(false),
+                       cl::desc("Simplify symbolic accesses using equalities "
+                                "from other constraints (default=false)"),
+                       cl::cat(SolvingCat));
 
-  /* Constraint solving options */
+cl::opt<bool>
+    EqualitySubstitution("equality-substitution", cl::init(true),
+                         cl::desc("Simplify equality expressions before "
+                                  "querying the solver (default=true)"),
+                         cl::cat(SolvingCat));
 
-  cl::opt<unsigned>
-  MaxSymArraySize("max-sym-array-size",
-                  cl::desc("If a symbolic array exceeds this size (in bytes), symbolic addresses into this array are concretized.  Set to 0 to disable (default=0)"),
-                  cl::init(0),
-                  cl::cat(SolvingCat));
+/*** External call policy options ***/
 
-  cl::opt<bool>
-  SimplifySymIndices("simplify-sym-indices",
-                     cl::init(false),
-		     cl::desc("Simplify symbolic accesses using equalities from other constraints (default=false)"),
-                     cl::cat(SolvingCat));
+cl::OptionCategory ExtCallsCat("External call policy options",
+                               "These options impact external calls.");
 
-  cl::opt<bool>
-  EqualitySubstitution("equality-substitution",
-		       cl::init(true),
-		       cl::desc("Simplify equality expressions before querying the solver (default=true)"),
-                       cl::cat(SolvingCat));
+enum class ExternalCallPolicy {
+  None,     // No external calls allowed
+  Concrete, // Only external calls with concrete arguments allowed
+  All,      // All external calls allowed
+};
 
-  
-  /*** External call policy options ***/
+cl::opt<ExternalCallPolicy> ExternalCalls(
+    "external-calls",
+    cl::desc("Specify the external call policy"),
+    cl::values(
+        clEnumValN(
+            ExternalCallPolicy::None, "none",
+            "No external function calls are allowed.  Note that KLEE always "
+            "allows some external calls with concrete arguments to go through "
+            "(in particular printf and puts), regardless of this option."),
+        clEnumValN(ExternalCallPolicy::Concrete, "concrete",
+                   "Only external function calls with concrete arguments are "
+                   "allowed (default)"),
+        clEnumValN(ExternalCallPolicy::All, "all",
+                   "All external function calls are allowed.  This concretizes "
+                   "any symbolic arguments in calls to external functions.")
+            KLEE_LLVM_CL_VAL_END),
+    cl::init(ExternalCallPolicy::Concrete),
+    cl::cat(ExtCallsCat));
+
+cl::opt<bool> SuppressExternalWarnings(
+    "suppress-external-warnings",
+    cl::init(false),
+    cl::desc("Supress warnings about calling external functions."),
+    cl::cat(ExtCallsCat));
+
+cl::opt<bool> AllExternalWarnings(
+    "all-external-warnings",
+    cl::init(false),
+    cl::desc("Issue a warning everytime an external call is made, "
+             "as opposed to once per function (default=false)"),
+    cl::cat(ExtCallsCat));
+
+/*** Seeding options ***/
+
+cl::OptionCategory SeedingCat(
+    "Seeding options",
+    "These options are related to the use of seeds to start exploration.");
+
+cl::opt<bool> AlwaysOutputSeeds(
+    "always-output-seeds",
+    cl::init(true),
+    cl::desc(
+        "Dump test cases even if they are driven by seeds only (default=true)"),
+    cl::cat(SeedingCat));
+
+cl::opt<bool> OnlyReplaySeeds(
+    "only-replay-seeds",
+    cl::init(false),
+    cl::desc("Discard states that do not have a seed (default=false)."),
+    cl::cat(SeedingCat));
+
+cl::opt<bool> OnlySeed("only-seed",
+                       cl::init(false),
+                       cl::desc("Stop execution after seeding is done without "
+                                "doing regular search (default=false)."),
+                       cl::cat(SeedingCat));
+
+cl::opt<bool>
+    AllowSeedExtension("allow-seed-extension",
+                       cl::init(false),
+                       cl::desc("Allow extra (unbound) values to become "
+                                "symbolic during seeding (default=false)."),
+                       cl::cat(SeedingCat));
+
+cl::opt<bool> ZeroSeedExtension(
+    "zero-seed-extension",
+    cl::init(false),
+    cl::desc(
+        "Use zero-filled objects if matching seed not found (default=false)"),
+    cl::cat(SeedingCat));
+
+cl::opt<bool> AllowSeedTruncation(
+    "allow-seed-truncation",
+    cl::init(false),
+    cl::desc("Allow smaller buffers than in seeds (default=false)."),
+    cl::cat(SeedingCat));
+
+cl::opt<bool> NamedSeedMatching(
+    "named-seed-matching",
+    cl::init(false),
+    cl::desc("Use names to match symbolic objects to inputs (default=false)."),
+    cl::cat(SeedingCat));
+
+cl::opt<std::string>
+    SeedTime("seed-time",
+             cl::desc("Amount of time to dedicate to seeds, before normal "
+                      "search (default=0s (off))"),
+             cl::cat(SeedingCat));
+
+
+/*** Termination criteria options ***/
+
+cl::OptionCategory
+    TerminationCat("State and overall termination options",
+                   "These options control termination of the overall KLEE "
+                   "execution and of individual states.");
+
+cl::list<Executor::TerminateReason> ExitOnErrorType(
+    "exit-on-error-type",
+    cl::desc(
+        "Stop execution after reaching a specified condition (default=false)"),
+    cl::values(
+        clEnumValN(Executor::Abort, "Abort", "The program crashed"),
+        clEnumValN(Executor::Assert, "Assert", "An assertion was hit"),
+        clEnumValN(Executor::BadVectorAccess, "BadVectorAccess",
+                   "Vector accessed out of bounds"),
+        clEnumValN(Executor::Exec, "Exec",
+                   "Trying to execute an unexpected instruction"),
+        clEnumValN(Executor::External, "External",
+                   "External objects referenced"),
+        clEnumValN(Executor::Free, "Free", "Freeing invalid memory"),
+        clEnumValN(Executor::Model, "Model", "Memory model limit hit"),
+        clEnumValN(Executor::Overflow, "Overflow", "An overflow occurred"),
+        clEnumValN(Executor::Ptr, "Ptr", "Pointer error"),
+        clEnumValN(Executor::ReadOnly, "ReadOnly", "Write to read-only memory"),
+        clEnumValN(Executor::ReportError, "ReportError",
+                   "klee_report_error called"),
+        clEnumValN(Executor::User, "User", "Wrong klee_* functions invocation"),
+        clEnumValN(Executor::Unhandled, "Unhandled",
+                   "Unhandled instruction hit") KLEE_LLVM_CL_VAL_END),
+    cl::ZeroOrMore,
+    cl::cat(TerminationCat));
+
+cl::opt<unsigned long long> MaxInstructions(
+    "max-instructions",
+    cl::desc("Stop execution after this many instructions.  Set to 0 to disable (default=0)"),
+    cl::init(0),
+    cl::cat(TerminationCat));
+
+cl::opt<unsigned>
+    MaxForks("max-forks",
+             cl::desc("Only fork this many times.  Set to -1 to disable (default=-1)"),
+             cl::init(~0u),
+             cl::cat(TerminationCat));
+
+cl::opt<unsigned> MaxDepth(
+    "max-depth",
+    cl::desc("Only allow this many symbolic branches.  Set to 0 to disable (default=0)"),
+    cl::init(0),
+    cl::cat(TerminationCat));
+
+cl::opt<unsigned> MaxMemory("max-memory",
+                            cl::desc("Refuse to fork when above this amount of "
+                                     "memory (in MB) (default=2000)"),
+                            cl::init(2000),
+                            cl::cat(TerminationCat));
+
+cl::opt<bool> MaxMemoryInhibit(
+    "max-memory-inhibit",
+    cl::desc(
+        "Inhibit forking at memory cap (vs. random terminate) (default=true)"),
+    cl::init(true),
+    cl::cat(TerminationCat));
+
+cl::opt<unsigned> RuntimeMaxStackFrames(
+    "max-stack-frames",
+    cl::desc("Terminate a state after this many stack frames.  Set to 0 to "
+             "disable (default=8192)"),
+    cl::init(8192),
+    cl::cat(TerminationCat));
+
+cl::opt<std::string> MaxInstructionTime(
+    "max-instruction-time",
+    cl::desc("Allow a single instruction to take only this much time.  Enables "
+             "--use-forked-solver.  Set to 0s to disable (default=0s)"),
+    cl::cat(TerminationCat));
+
+cl::opt<double> MaxStaticForkPct(
+    "max-static-fork-pct", cl::init(1.),
+    cl::desc("Maximum percentage spent by an instruction forking out of the "
+             "forking of all instructions (default=1.0 (always))"),
+    cl::cat(TerminationCat));
+
+cl::opt<double> MaxStaticSolvePct(
+    "max-static-solve-pct", cl::init(1.),
+    cl::desc("Maximum percentage of solving time that can be spent by a single "
+             "instruction over total solving time for all instructions "
+             "(default=1.0 (always))"),
+    cl::cat(TerminationCat));
+
+cl::opt<double> MaxStaticCPForkPct(
+    "max-static-cpfork-pct", cl::init(1.),
+    cl::desc("Maximum percentage spent by an instruction of a call path "
+             "forking out of the forking of all instructions in the call path "
+             "(default=1.0 (always))"),
+    cl::cat(TerminationCat));
+
+cl::opt<double> MaxStaticCPSolvePct(
+    "max-static-cpsolve-pct", cl::init(1.),
+    cl::desc("Maximum percentage of solving time that can be spent by a single "
+             "instruction of a call path over total solving time for all "
+             "instructions (default=1.0 (always))"),
+    cl::cat(TerminationCat));
+
+/*** Debugging options ***/
+
+cl::OptionCategory DebugCat("Debugging options",
+                            "These are debugging options.");
+
+/// The different query logging solvers that can switched on/off
+enum PrintDebugInstructionsType {
+  STDERR_ALL, ///
+  STDERR_SRC,
+  STDERR_COMPACT,
+  FILE_ALL,    ///
+  FILE_SRC,    ///
+  FILE_COMPACT ///
+};
 
-  cl::OptionCategory ExtCallsCat("External call policy options",
-                                 "These options impact external calls.");
-  
-  enum class ExternalCallPolicy {
-    None,     // No external calls allowed
-    Concrete, // Only external calls with concrete arguments allowed
-    All,      // All external calls allowed
-  };
-
-  cl::opt<ExternalCallPolicy>
-  ExternalCalls("external-calls",
-                cl::desc("Specify the external call policy"),
-                cl::values(clEnumValN(ExternalCallPolicy::None, "none", "No external function calls are allowed.  Note that KLEE always allows some external calls with concrete arguments to go through (in particular printf and puts), regardless of this option."),
-                           clEnumValN(ExternalCallPolicy::Concrete, "concrete", "Only external function calls with concrete arguments are allowed (default)"),
-                           clEnumValN(ExternalCallPolicy::All, "all", "All external function calls are allowed.  This concretizes any symbolic arguments in calls to external functions.")
-                           KLEE_LLVM_CL_VAL_END),
-                cl::init(ExternalCallPolicy::Concrete),
-                cl::cat(ExtCallsCat));
-
-  cl::opt<bool>
-  SuppressExternalWarnings("suppress-external-warnings",
-			   cl::init(false),
-			   cl::desc("Supress warnings about calling external functions."),
-                           cl::cat(ExtCallsCat));
-
-  cl::opt<bool>
-  AllExternalWarnings("all-external-warnings",
-		      cl::init(false),
-		      cl::desc("Issue a warning everytime an external call is made, "
-			       "as opposed to once per function (default=false)"),
-                      cl::cat(ExtCallsCat));
-
-
-  /*** Seeding options ***/
-
-  cl::OptionCategory SeedingCat("Seeding options",
-                                "These options are related to the use of seeds to start exploration.");
-
-  cl::opt<bool>
-  AlwaysOutputSeeds("always-output-seeds",
-		    cl::init(true),
-                    cl::desc("Dump test cases even if they are driven by seeds only (default=true)"),
-                    cl::cat(SeedingCat));
-
-  cl::opt<bool>
-  OnlyReplaySeeds("only-replay-seeds",
-		  cl::init(false),
-                  cl::desc("Discard states that do not have a seed (default=false)."),
-                  cl::cat(SeedingCat));
-
-  cl::opt<bool>
-  OnlySeed("only-seed",
-	   cl::init(false),
-           cl::desc("Stop execution after seeding is done without doing regular search (default=false)."),
-           cl::cat(SeedingCat));
- 
-  cl::opt<bool>
-  AllowSeedExtension("allow-seed-extension",
-		     cl::init(false),
-                     cl::desc("Allow extra (unbound) values to become symbolic during seeding (default=false)."),
-                     cl::cat(SeedingCat));
- 
-  cl::opt<bool>
-  ZeroSeedExtension("zero-seed-extension",
-		    cl::init(false),
-		    cl::desc("Use zero-filled objects if matching seed not found (default=false)"),
-                    cl::cat(SeedingCat));
- 
-  cl::opt<bool>
-  AllowSeedTruncation("allow-seed-truncation",
-		      cl::init(false),
-                      cl::desc("Allow smaller buffers than in seeds (default=false)."),
-                      cl::cat(SeedingCat));
- 
-  cl::opt<bool>
-  NamedSeedMatching("named-seed-matching",
-		    cl::init(false),
-                    cl::desc("Use names to match symbolic objects to inputs (default=false)."),
-                    cl::cat(SeedingCat));
-
-  cl::opt<std::string>
-  SeedTime("seed-time",
-           cl::desc("Amount of time to dedicate to seeds, before normal search (default=0s (off))"),
-           cl::cat(SeedingCat));
-
-
-  /*** Termination criteria options ***/
-
-  cl::OptionCategory TerminationCat("State and overall termination options",
-                                    "These options control termination of the overall KLEE execution and of individual states.");
-
-  cl::list<Executor::TerminateReason>
-  ExitOnErrorType("exit-on-error-type",
-		  cl::desc("Stop execution after reaching a specified condition (default=false)"),
-		  cl::values(
-		    clEnumValN(Executor::Abort, "Abort", "The program crashed"),
-		    clEnumValN(Executor::Assert, "Assert", "An assertion was hit"),
-		    clEnumValN(Executor::BadVectorAccess, "BadVectorAccess", "Vector accessed out of bounds"),
-		    clEnumValN(Executor::Exec, "Exec", "Trying to execute an unexpected instruction"),
-		    clEnumValN(Executor::External, "External", "External objects referenced"),
-		    clEnumValN(Executor::Free, "Free", "Freeing invalid memory"),
-		    clEnumValN(Executor::Model, "Model", "Memory model limit hit"),
-		    clEnumValN(Executor::Overflow, "Overflow", "An overflow occurred"),
-		    clEnumValN(Executor::Ptr, "Ptr", "Pointer error"),
-		    clEnumValN(Executor::ReadOnly, "ReadOnly", "Write to read-only memory"),
-		    clEnumValN(Executor::ReportError, "ReportError", "klee_report_error called"),
-		    clEnumValN(Executor::User, "User", "Wrong klee_* functions invocation"),
-		    clEnumValN(Executor::Unhandled, "Unhandled", "Unhandled instruction hit")
-		    KLEE_LLVM_CL_VAL_END),
-		  cl::ZeroOrMore,
-                  cl::cat(TerminationCat));
-
-  cl::opt<unsigned long long>
-  MaxInstructions("max-instructions",
-                  cl::desc("Stop execution after this many instructions (default=0 (off))"),
-                  cl::init(0),
-                  cl::cat(TerminationCat));
-  
-  cl::opt<unsigned>
-  MaxForks("max-forks",
-           cl::desc("Only fork this many times (default=-1 (off))"),
-           cl::init(~0u),
-           cl::cat(TerminationCat));
-  
-  cl::opt<unsigned>
-  MaxDepth("max-depth",
-           cl::desc("Only allow this many symbolic branches (default=0 (off))"),
-           cl::init(0),
-           cl::cat(TerminationCat));
-  
-  cl::opt<unsigned>
-  MaxMemory("max-memory",
-            cl::desc("Refuse to fork when above this amount of memory (in MB, default=2000)"),
-            cl::init(2000),
-            cl::cat(TerminationCat));
-
-  cl::opt<bool>
-  MaxMemoryInhibit("max-memory-inhibit",
-                   cl::desc("Inhibit forking at memory cap (vs. random terminate) (default=true)"),
-                   cl::init(true),
-                   cl::cat(TerminationCat));
-
-  cl::opt<unsigned> RuntimeMaxStackFrames("max-stack-frames",
-                                          cl::desc("Terminate a state after this many stack frames (default=8192).  Disable check with 0."),
-                                          cl::init(8192),
-                                          cl::cat(TerminationCat));
-
-  cl::opt<std::string>
-  MaxInstructionTime("max-instruction-time",
-                     cl::desc("Allow a single instruction to take only this much time (default=0s (off)). Enables --use-forked-solver"),
-                     cl::cat(TerminationCat));
-
-  cl::opt<double>
-  MaxStaticForkPct("max-static-fork-pct",
-		   cl::init(1.),
-		   cl::desc("Maximum percentage spent by an instruction forking out of the forking of all instructions (default=1.0 (always))"),
-                   cl::cat(TerminationCat));
-
-  cl::opt<double>
-  MaxStaticSolvePct("max-static-solve-pct",
-		    cl::init(1.),
-		    cl::desc("Maximum percentage of solving time that can be spent by a single instruction over total solving time for all instructions (default=1.0 (always))"),
-                    cl::cat(TerminationCat));
-
-  cl::opt<double>
-  MaxStaticCPForkPct("max-static-cpfork-pct", 
-		     cl::init(1.),
-		     cl::desc("Maximum percentage spent by an instruction of a call path forking out of the forking of all instructions in the call path (default=1.0 (always))"),
-                     cl::cat(TerminationCat));
-
-  cl::opt<double>
-  MaxStaticCPSolvePct("max-static-cpsolve-pct",
-		      cl::init(1.),
-		      cl::desc("Maximum percentage of solving time that can be spent by a single instruction of a call path over total solving time for all instructions (default=1.0 (always))"),
-                      cl::cat(TerminationCat));
-
-
-  /*** Debugging options ***/
-
-  cl::OptionCategory DebugCat("Debugging options",
-                              "These are debugging options.");
-
-  /// The different query logging solvers that can switched on/off
-  enum PrintDebugInstructionsType {
-    STDERR_ALL, ///
-    STDERR_SRC,
-    STDERR_COMPACT,
-    FILE_ALL,    ///
-    FILE_SRC,    ///
-    FILE_COMPACT ///
-  };
-
-  llvm::cl::bits<PrintDebugInstructionsType> DebugPrintInstructions(
-      "debug-print-instructions",
-      llvm::cl::desc("Log instructions during execution."),
-      llvm::cl::values(
-          clEnumValN(STDERR_ALL, "all:stderr", "Log all instructions to stderr "
-                                               "in format [src, inst_id, "
-                                               "llvm_inst]"),
-          clEnumValN(STDERR_SRC, "src:stderr",
-                     "Log all instructions to stderr in format [src, inst_id]"),
-          clEnumValN(STDERR_COMPACT, "compact:stderr",
-                     "Log all instructions to stderr in format [inst_id]"),
-          clEnumValN(FILE_ALL, "all:file", "Log all instructions to file "
-                                           "instructions.txt in format [src, "
-                                           "inst_id, llvm_inst]"),
-          clEnumValN(FILE_SRC, "src:file", "Log all instructions to file "
-                                           "instructions.txt in format [src, "
-                                           "inst_id]"),
-          clEnumValN(FILE_COMPACT, "compact:file",
-                     "Log all instructions to file instructions.txt in format "
-                     "[inst_id]")
-          KLEE_LLVM_CL_VAL_END),
-      llvm::cl::CommaSeparated,
-      cl::cat(DebugCat));
+llvm::cl::bits<PrintDebugInstructionsType> DebugPrintInstructions(
+    "debug-print-instructions",
+    llvm::cl::desc("Log instructions during execution."),
+    llvm::cl::values(
+        clEnumValN(STDERR_ALL, "all:stderr",
+                   "Log all instructions to stderr "
+                   "in format [src, inst_id, "
+                   "llvm_inst]"),
+        clEnumValN(STDERR_SRC, "src:stderr",
+                   "Log all instructions to stderr in format [src, inst_id]"),
+        clEnumValN(STDERR_COMPACT, "compact:stderr",
+                   "Log all instructions to stderr in format [inst_id]"),
+        clEnumValN(FILE_ALL, "all:file",
+                   "Log all instructions to file "
+                   "instructions.txt in format [src, "
+                   "inst_id, llvm_inst]"),
+        clEnumValN(FILE_SRC, "src:file",
+                   "Log all instructions to file "
+                   "instructions.txt in format [src, "
+                   "inst_id]"),
+        clEnumValN(FILE_COMPACT, "compact:file",
+                   "Log all instructions to file instructions.txt in format "
+                   "[inst_id]") KLEE_LLVM_CL_VAL_END),
+    llvm::cl::CommaSeparated,
+    cl::cat(DebugCat));
 
 #ifdef HAVE_ZLIB_H
-  cl::opt<bool>
-  DebugCompressInstructions("debug-compress-instructions",
-                            cl::init(false),
-                            cl::desc("Compress the logged instructions in gzip format (default=false)."),
-                            cl::cat(DebugCat));
+cl::opt<bool> DebugCompressInstructions(
+    "debug-compress-instructions", cl::init(false),
+    cl::desc(
+        "Compress the logged instructions in gzip format (default=false)."),
+    cl::cat(DebugCat));
 #endif
 
-  cl::opt<bool>
-  DebugCheckForImpliedValues("debug-check-for-implied-values",
-                             cl::init(false),
-                             cl::desc("Debug the implied value optimization"),
-                             cl::cat(DebugCat));
-
-}
+cl::opt<bool> DebugCheckForImpliedValues(
+    "debug-check-for-implied-values", cl::init(false),
+    cl::desc("Debug the implied value optimization"),
+    cl::cat(DebugCat));
 
+} // namespace
 
 namespace klee {
   RNG theRNG;