Skip to content

Commit

Permalink
Add flags --fail-on-trap-only and fail-on-assertion-only
Browse files Browse the repository at this point in the history
  • Loading branch information
filipeom authored and zapashcanon committed Aug 1, 2024
1 parent a99b768 commit c661ea0
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## unreleased

- adds flags `--fail-on-trap-only` and `fail-on-assertion-only`
- parameterize the `Thread` module on the symbolic memory and the `Choice_monad` module on a Thread
- adds a `owi_char` function to create char symbolic value
- adds a `Mem` argument to external function to allow direct manipulation of the memory.
Expand Down
1 change: 1 addition & 0 deletions bench/tool/tool.ml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ let execvp ~output_dir tool file timeout =
, [ "owi"; "c" ]
@ (if concolic then [ "--concolic" ] else [])
@ [ "--unsafe"
; "--fail-on-assertion-only"
; Format.sprintf "-O%d" optimisation_level
; Format.sprintf "-w%d" workers
; "-o"
Expand Down
6 changes: 6 additions & 0 deletions example/c/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,12 @@ OPTIONS
Guarantee a fixed deterministic order of found failures. This
implies --no-stop-at-failure.

--fail-on-assertion-only
ignore traps and only report assertion violations

--fail-on-trap-only
ignore assertion violations and only report traps

-I VAL
headers path

Expand Down
6 changes: 6 additions & 0 deletions example/conc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ OPTIONS
Guarantee a fixed deterministic order of found failures. This
implies --no-stop-at-failure.

--fail-on-assertion-only
ignore traps and only report assertion violations

--fail-on-trap-only
ignore assertion violations and only report traps

--no-stop-at-failure
do not stop when a program failure is encountered

Expand Down
6 changes: 6 additions & 0 deletions example/sym/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ OPTIONS
Guarantee a fixed deterministic order of found failures. This
implies --no-stop-at-failure.

--fail-on-assertion-only
ignore traps and only report assertion violations

--fail-on-trap-only
ignore assertion violations and only report traps

--no-stop-at-failure
do not stop when a program failure is encountered

Expand Down
22 changes: 16 additions & 6 deletions src/bin/owi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ let no_values =
let doc = "do not display a value for each symbol" in
Cmdliner.Arg.(value & flag & info [ "no-value" ] ~doc)

let fail_mode =
let trap_doc = "ignore assertion violations and only report traps" in
let assert_doc = "ignore traps and only report assertion violations" in
Cmdliner.Arg.(
value
& vflag `Both
[ (`Trap_only, info [ "fail-on-trap-only" ] ~doc:trap_doc)
; (`Assertion_only, info [ "fail-on-assertion-only" ] ~doc:assert_doc)
] )

let optimize =
let doc = "optimize mode" in
Cmdliner.Arg.(value & flag & info [ "optimize" ] ~doc)
Expand Down Expand Up @@ -135,8 +145,8 @@ let c_cmd =
Term.(
const Cmd_c.cmd $ debug $ arch $ property $ testcomp $ output $ workers
$ opt_lvl $ includes $ files $ profiling $ unsafe $ optimize
$ no_stop_at_failure $ no_values $ deterministic_result_order $ concolic
$ solver )
$ no_stop_at_failure $ no_values $ deterministic_result_order $ fail_mode
$ concolic $ solver )

let fmt_cmd =
let open Cmdliner in
Expand Down Expand Up @@ -201,8 +211,8 @@ let sym_cmd =
Cmd.v info
Term.(
const Cmd_sym.cmd $ profiling $ debug $ unsafe $ optimize $ workers
$ no_stop_at_failure $ no_values $ deterministic_result_order $ workspace
$ solver $ files )
$ no_stop_at_failure $ no_values $ deterministic_result_order $ fail_mode
$ workspace $ solver $ files )

let conc_cmd =
let open Cmdliner in
Expand All @@ -214,8 +224,8 @@ let conc_cmd =
Cmd.v info
Term.(
const Cmd_conc.cmd $ profiling $ debug $ unsafe $ optimize $ workers
$ no_stop_at_failure $ no_values $ deterministic_result_order $ workspace
$ solver $ files )
$ no_stop_at_failure $ no_values $ deterministic_result_order $ fail_mode
$ workspace $ solver $ files )

let wasm2wat_cmd =
let open Cmdliner in
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/cmd_c.ml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ let metadata ~workspace arch property files : unit Result.t =

let cmd debug arch property _testcomp workspace workers opt_lvl includes files
profiling unsafe optimize no_stop_at_failure no_values
deterministic_result_order concolic solver : unit Result.t =
deterministic_result_order fail_mode concolic solver : unit Result.t =
if debug then Logs.set_level (Some Debug);
let workspace = Fpath.v workspace in
let includes = libc_location @ includes in
Expand All @@ -131,4 +131,4 @@ let cmd debug arch property _testcomp workspace workers opt_lvl includes files
let files = [ modul ] in
(if concolic then Cmd_conc.cmd else Cmd_sym.cmd)
profiling debug unsafe optimize workers no_stop_at_failure no_values
deterministic_result_order workspace solver files
deterministic_result_order fail_mode workspace solver files
1 change: 1 addition & 0 deletions src/cmd/cmd_c.mli
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ val cmd :
-> bool
-> bool
-> bool
-> Cmd_sym.fail_mode
-> bool
-> Smtml.Solver_dispatcher.solver_type
-> unit Result.t
2 changes: 1 addition & 1 deletion src/cmd/cmd_conc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ let launch solver tree link_state modules_to_run =
which are handled here. Most of the computations are done in the Result
monad, hence the let*. *)
let cmd profiling debug unsafe optimize _workers _no_stop_at_failure no_values
_deterministic_result_order (workspace : Fpath.t) solver files =
_deterministic_result_order _fail_mode (workspace : Fpath.t) solver files =
if profiling then Log.profiling_on := true;
if debug then Log.debug_on := true;

Expand Down
1 change: 1 addition & 0 deletions src/cmd/cmd_conc.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ val cmd :
-> bool
-> bool
-> bool
-> Cmd_sym.fail_mode
-> Fpath.t
-> Smtml.Solver_dispatcher.solver_type
-> Fpath.t list
Expand Down
32 changes: 19 additions & 13 deletions src/cmd/cmd_sym.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ open Syntax
module Expr = Smtml.Expr
module Choice = Symbolic_choice_with_memory

type fail_mode =
[ `Trap_only
| `Assertion_only
| `Both
]

let ( let*/ ) (t : 'a Result.t) (f : 'a -> 'b Result.t Choice.t) :
'b Result.t Choice.t =
match t with Error e -> Choice.return (Error e) | Ok x -> f x
Expand Down Expand Up @@ -38,7 +44,7 @@ let run_file ~unsafe ~optimize pc filename =
which are handled here. Most of the computations are done in the Result
monad, hence the let*. *)
let cmd profiling debug unsafe optimize workers no_stop_at_failure no_values
deterministic_result_order (workspace : Fpath.t) solver files =
deterministic_result_order fail_mode (workspace : Fpath.t) solver files =
if profiling then Log.profiling_on := true;
if debug then Log.debug_on := true;
(* deterministic_result_order implies no_stop_at_failure *)
Expand All @@ -49,9 +55,15 @@ let cmd profiling debug unsafe optimize workers no_stop_at_failure no_values
let thread = Thread_with_memory.init () in
let res_queue = Wq.init () in
let callback v =
match v with
| Symbolic_choice_intf.EVal (Ok ()), _ -> ()
| v -> Wq.push v res_queue
let open Symbolic_choice_intf in
match (fail_mode, v) with
| _, (EVal (Ok ()), _) -> ()
| _, (EVal (Error e), thread) -> Wq.push (`Error e, thread) res_queue
| (`Both | `Trap_only), (ETrap (t, m), thread) ->
Wq.push (`ETrap (t, m), thread) res_queue
| (`Both | `Assertion_only), (EAssert (e, m), thread) ->
Wq.push (`EAssert (e, m), thread) res_queue
| (`Trap_only | `Assertion_only), _ -> ()
in
let join_handles =
Symbolic_choice_with_memory.run ~workers solver result thread ~callback
Expand All @@ -75,17 +87,11 @@ let cmd profiling debug unsafe optimize workers no_stop_at_failure no_values
| Seq.Nil -> Ok count_acc
| Seq.Cons ((result, _thread), tl) ->
let* model =
let open Symbolic_choice_intf in
match result with
| EAssert (assertion, model) ->
print_bug (`EAssert (assertion, model));
Ok model
| ETrap (tr, model) ->
print_bug (`ETrap (tr, model));
| (`EAssert (_, model) | `ETrap (_, model)) as bug ->
print_bug bug;
Ok model
| EVal (Ok ()) ->
Fmt.failwith "unreachable: callback should have filtered eval ok out."
| EVal (Error e) -> Error e
| `Error e -> Error e
in
let count_acc = succ count_acc in
let* () =
Expand Down
7 changes: 7 additions & 0 deletions src/cmd/cmd_sym.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
(* Copyright © 2021-2024 OCamlPro *)
(* Written by the Owi programmers *)

type fail_mode =
[ `Trap_only
| `Assertion_only
| `Both
]

val cmd :
bool
-> bool
Expand All @@ -11,6 +17,7 @@ val cmd :
-> bool
-> bool
-> bool
-> fail_mode
-> Fpath.t
-> Smtml.Solver_dispatcher.solver_type
-> Fpath.t list
Expand Down

0 comments on commit c661ea0

Please sign in to comment.