Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unassume benchmarking fixes #1124

Merged
merged 20 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .semgrep/tracing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rules:
- pattern: Messages.traceu
- pattern: Messages.traceli
- pattern-not-inside: if Messages.tracing then ...
- pattern-not-inside: if Messages.tracing && ... then ...
message: trace functions should only be called if tracing is enabled at compile time
languages: [ocaml]
severity: WARNING
8 changes: 0 additions & 8 deletions conf/bench-yaml-validate.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,6 @@
"tokens": true
}
},
"witness": {
"enabled": false,
"invariant": {
"loop-head": true,
"after-lock": true,
"other": false
}
},
"sem": {
"unknown_function": {
"invalidate": {
Expand Down
14 changes: 0 additions & 14 deletions conf/bench-yaml.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,6 @@
]
}
},
"witness": {
"enabled": false,
"yaml": {
"enabled": true
},
"invariant": {
"exact": false,
"exclude-vars": [
"tmp\\(___[0-9]+\\)?",
"cond",
"RETURN"
]
}
},
"sem": {
"unknown_function": {
"invalidate": {
Expand Down
13 changes: 5 additions & 8 deletions conf/svcomp-yaml-validate.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"float": {
"interval": true
},
"apron": {
"domain": "polyhedra",
"strengthening": true
},
"activated": [
"base",
"threadid",
Expand All @@ -31,6 +35,7 @@
"region",
"thread",
"threadJoins",
"apron",
"unassume"
],
"context": {
Expand Down Expand Up @@ -74,14 +79,6 @@
"exp": {
"region-offsets": true
},
"witness": {
"enabled": false,
"invariant": {
"loop-head": true,
"after-lock": false,
"other": false
}
},
"solver": "td3",
"sem": {
"unknown_function": {
Expand Down
10 changes: 9 additions & 1 deletion conf/svcomp-yaml.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"float": {
"interval": true
},
"apron": {
"domain": "polyhedra",
"strengthening": true
},
"activated": [
"base",
"threadid",
Expand All @@ -30,7 +34,8 @@
"symb_locks",
"region",
"thread",
"threadJoins"
"threadJoins",
"apron"
],
"context": {
"widen": false
Expand Down Expand Up @@ -76,6 +81,9 @@
"enabled": true
},
"invariant": {
"loop-head": true,
"other": false,
"accessed": false,
"exact": false,
"exclude-vars": [
"tmp\\(___[0-9]+\\)?",
Expand Down
19 changes: 14 additions & 5 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ struct
Int (if AD.is_bot (AD.meet p1 p2) then ID.of_int ik BI.zero else match eq p1 p2 with Some x when x -> ID.of_int ik BI.one | _ -> bool_top ik)
| Ne ->
Int (if AD.is_bot (AD.meet p1 p2) then ID.of_int ik BI.one else match eq p1 p2 with Some x when x -> ID.of_int ik BI.zero | _ -> bool_top ik)
| IndexPI when AD.to_string p2 = ["all_index"] ->
addToAddrOp p1 (ID.top_of (Cilfacade.ptrdiff_ikind ()))
| _ -> VD.top ()
end
(* For other values, we just give up! *)
Expand Down Expand Up @@ -1053,7 +1055,6 @@ struct
else if AD.may_be_null adr
then M.warn ~category:M.Category.Behavior.Undefined.nullpointer_dereference ~tags:[CWE 476] "May dereference NULL pointer");
AD.map (add_offset_varinfo (convert_offset a gs st ofs)) adr
| Bot -> AD.bot ()
| _ ->
M.debug ~category:Analyzer "Failed evaluating %a to lvalue" d_lval lval;
AD.unknown_ptr
Expand Down Expand Up @@ -2275,10 +2276,18 @@ struct
then AD.join addr AD.null_ptr (* calloc can fail and return NULL *)
else addr in
let ik = Cilfacade.ptrdiff_ikind () in
let blobsize = ID.mul (ID.cast_to ik @@ eval_int (Analyses.ask_of_ctx ctx) gs st size) (ID.cast_to ik @@ eval_int (Analyses.ask_of_ctx ctx) gs st n) in
(* the memory that was allocated by calloc is set to bottom, but we keep track that it originated from calloc, so when bottom is read from memory allocated by calloc it is turned to zero *)
set_many ~ctx (Analyses.ask_of_ctx ctx) gs st [(add_null (AD.of_var heap_var), TVoid [], Array (CArrays.make (IdxDom.of_int (Cilfacade.ptrdiff_ikind ()) BI.one) (Blob (VD.bot (), blobsize, false))));
(eval_lv (Analyses.ask_of_ctx ctx) gs st lv, (Cilfacade.typeOfLval lv), Address (add_null (AD.of_mval (heap_var, `Index (IdxDom.of_int (Cilfacade.ptrdiff_ikind ()) BI.zero, `NoOffset)))))]
let sizeval = eval_int (Analyses.ask_of_ctx ctx) gs st size in
let countval = eval_int (Analyses.ask_of_ctx ctx) gs st n in
if ID.to_int countval = Some Z.one then (
set_many ~ctx (Analyses.ask_of_ctx ctx) gs st [(add_null (AD.of_var heap_var), TVoid [], Blob (VD.bot (), sizeval, false));
(eval_lv (Analyses.ask_of_ctx ctx) gs st lv, (Cilfacade.typeOfLval lv), Address (add_null (AD.of_var heap_var)))]
)
else (
let blobsize = ID.mul (ID.cast_to ik @@ sizeval) (ID.cast_to ik @@ countval) in
(* the memory that was allocated by calloc is set to bottom, but we keep track that it originated from calloc, so when bottom is read from memory allocated by calloc it is turned to zero *)
set_many ~ctx (Analyses.ask_of_ctx ctx) gs st [(add_null (AD.of_var heap_var), TVoid [], Array (CArrays.make (IdxDom.of_int (Cilfacade.ptrdiff_ikind ()) BI.one) (Blob (VD.bot (), blobsize, false))));
(eval_lv (Analyses.ask_of_ctx ctx) gs st lv, (Cilfacade.typeOfLval lv), Address (add_null (AD.of_mval (heap_var, `Index (IdxDom.of_int (Cilfacade.ptrdiff_ikind ()) BI.zero, `NoOffset)))))]
)
| _ -> st
end
| Realloc { ptr = p; size }, _ ->
Expand Down
6 changes: 3 additions & 3 deletions src/analyses/unassumeAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ struct
Locator.ES.iter (fun n ->
let fundec = Node.find_fundec n in

match InvariantParser.parse_cil inv_parser ~fundec ~loc inv_cabs with
match InvariantParser.parse_cil inv_parser ~check:false ~fundec ~loc inv_cabs with
| Ok inv_exp ->
M.debug ~category:Witness ~loc:msgLoc "located invariant to %a: %a" Node.pretty n Cil.d_exp inv_exp;
NH.add invs n {exp = inv_exp; uuid}
Expand Down Expand Up @@ -157,12 +157,12 @@ struct
Locator.ES.iter (fun n ->
let fundec = Node.find_fundec n in

match InvariantParser.parse_cil inv_parser ~fundec ~loc pre_cabs with
match InvariantParser.parse_cil inv_parser ~check:false ~fundec ~loc pre_cabs with
| Ok pre_exp ->
M.debug ~category:Witness ~loc:msgLoc "located precondition to %a: %a" CilType.Fundec.pretty fundec Cil.d_exp pre_exp;
FH.add fun_pres fundec pre_exp;

begin match InvariantParser.parse_cil inv_parser ~fundec ~loc inv_cabs with
begin match InvariantParser.parse_cil inv_parser ~check:false ~fundec ~loc inv_cabs with
| Ok inv_exp ->
M.debug ~category:Witness ~loc:msgLoc "located invariant to %a: %a" Node.pretty n Cil.d_exp inv_exp;
if not (NH.mem pre_invs n) then
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/varEq.ml
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ struct
| Question (b, t, f, _) -> lval_may_change_pt b bl || lval_may_change_pt t bl || lval_may_change_pt f bl
in
let r =
if Cil.isConstant b then false
if Cil.isConstant b || Cil.isConstant a then false
else if Queries.LS.is_top bls || Queries.LS.mem (dummyFunDec.svar, `NoOffset) bls
then ((*Messages.warn ~category:Analyzer "No PT-set: switching to types ";*) type_may_change_apt a )
else Queries.LS.exists (lval_may_change_pt a) bls
Expand Down
6 changes: 3 additions & 3 deletions src/cdomains/apron/apronDomain.apron.ml
Original file line number Diff line number Diff line change
Expand Up @@ -693,16 +693,16 @@ struct

let join x y =
(* just to optimize joining folds, which start with bot *)
if is_bot x then
if is_bot x then (* TODO: also for non-empty env *)
y
else if is_bot y then
else if is_bot y then (* TODO: also for non-empty env *)
x
else (
if M.tracing then M.traceli "apron" "join %a %a\n" pretty x pretty y;
let j = join x y in
if M.tracing then M.trace "apron" "j = %a\n" pretty j;
let j =
if strengthening_enabled then
if strengthening_enabled then (* TODO: skip if same envs? *)
strengthening j x y
else
j
Expand Down
2 changes: 1 addition & 1 deletion src/cdomains/intDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ struct
norm ik @@ Some (l2,u2) |> fst
let widen ik x y =
let r = widen ik x y in
if M.tracing then M.tracel "int" "interval widen %a %a -> %a\n" pretty x pretty y pretty r;
if M.tracing && not (equal x y) then M.tracel "int" "interval widen %a %a -> %a\n" pretty x pretty y pretty r;
Fixed Show fixed Hide fixed
assert (leq x y); (* TODO: remove for performance reasons? *)
r

Expand Down
2 changes: 1 addition & 1 deletion src/cdomains/valueDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ struct
| _ -> false

let is_mutex_type (t: typ): bool = match t with
| TNamed (info, attr) -> info.tname = "pthread_mutex_t" || info.tname = "spinlock_t" || info.tname = "pthread_spinlock_t"
| TNamed (info, attr) -> info.tname = "pthread_mutex_t" || info.tname = "spinlock_t" || info.tname = "pthread_spinlock_t" || info.tname = "pthread_cond_t"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we treating pthread_cond_t as a mutex type here? That is confusing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just in the base analysis to ignore the condition variable struct contents.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still, for consistency, I think we should introduce a is_cond_type here, there are several similar functions already around.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wouldn't be more consistent though because it still uses Mutex for ValueDomain. I don't think it's worth it to introduce Cond into ValueDomain just for this. Mutex analyses treat condition variables via unlock-lock anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutex analyses treat condition variables via unlock-lock anyway.

What do you mean by this? If there is an analysis that does this, it is wrong. (Or are you talking about the second argument of pthread_cond_wait? That seems to be unrelated, no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And we do something with condition variables, see #520.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well yes, but we don't care about the implementation detail struct of a condition variable in base, just like we don't care about it for mutexes. All this does is make the contents opaque instead of tracking a struct whose contents our special functions don't update and thus those contents are outright wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that. I still think it is cleaner to have a dedicated function for this case, rather than confusing things. Maybe one should replace Mutex in base with OpaquePThreadType or something like this?
However, my happiness isn't tied up in this, so if you prefer we can merge as-is.

| TInt (IInt, attr) -> hasAttribute "mutex" attr
| _ -> false

Expand Down
29 changes: 17 additions & 12 deletions src/domains/partitionDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,23 @@ struct
for_all (fun p -> exists (B.leq p) y) x

let pretty_diff () (y, x) =
(* based on DisjointDomain.PairwiseSet *)
let x_not_leq = filter (fun p ->
not (exists (fun q -> B.leq p q) y)
) x
in
let p_not_leq = choose x_not_leq in
GoblintCil.Pretty.(
dprintf "%a:\n" B.pretty p_not_leq
++
fold (fun q acc ->
dprintf "not leq %a because %a\n" B.pretty q B.pretty_diff (p_not_leq, q) ++ acc
) y nil
if E.is_top x then (
GoblintCil.Pretty.(dprintf "%a not leq bot" pretty y)
)
else (
(* based on DisjointDomain.PairwiseSet *)
let x_not_leq = filter (fun p ->
not (exists (fun q -> B.leq p q) y)
) x
in
let p_not_leq = choose x_not_leq in
GoblintCil.Pretty.(
dprintf "%a:\n" B.pretty p_not_leq
++
fold (fun q acc ->
dprintf "not leq %a because %a\n" B.pretty q B.pretty_diff (p_not_leq, q) ++ acc
) y nil
)
)

let meet xs ys = if is_bot xs || is_bot ys then bot () else
Expand Down
1 change: 1 addition & 0 deletions src/framework/analyses.ml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ end
module GVarF (V: SpecSysVar) =
struct
include Printable.Either (V) (CilType.Fundec)
let name () = "FromSpec"
let spec x = `Left x
let contexts x = `Right x

Expand Down
2 changes: 1 addition & 1 deletion src/framework/control.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module type S2S = functor (X : Spec) -> Spec
(* spec is lazy, so HConsed table in Hashcons lifters is preserved between analyses in server mode *)
let spec_module: (module Spec) Lazy.t = lazy (
GobConfig.building_spec := true;
let arg_enabled = get_bool "ana.sv-comp.enabled" || get_bool "exp.arg" in
let arg_enabled = (get_bool "ana.sv-comp.enabled" && get_bool "witness.enabled") || get_bool "exp.arg" in
let open Batteries in
(* apply functor F on module X if opt is true *)
let lift opt (module F : S2S) (module X : Spec) = (module (val if opt then (module F (X)) else (module X) : Spec) : Spec) in
Expand Down
2 changes: 1 addition & 1 deletion src/goblint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ let main () =
exit 1
| Sys.Break -> (* raised on Ctrl-C if `Sys.catch_break true` *)
do_stats ();
(* Printexc.print_backtrace BatInnerIO.stderr *)
Printexc.print_backtrace stderr;
eprintf "%s\n" (MessageUtil.colorize ~fd:Unix.stderr ("{RED}Analysis was aborted by SIGINT (Ctrl-C)!"));
Goblint_timing.teardown_tef ();
exit 131 (* same exit code as without `Sys.catch_break true`, otherwise 0 *)
Expand Down
5 changes: 4 additions & 1 deletion src/solvers/td3.ml
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ module Base =
);
if not (Timing.wrap "S.Dom.equal" (fun () -> S.Dom.equal old wpd) ()) then ( (* value changed *)
if tracing then trace "sol" "Changed\n";
(* if tracing && not (S.Dom.is_bot old) && HM.mem wpoint x then trace "solchange" "%a (wpx: %b): %a -> %a\n" S.Var.pretty_trace x (HM.mem wpoint x) S.Dom.pretty old S.Dom.pretty wpd; *)
if tracing && not (S.Dom.is_bot old) && HM.mem wpoint x then trace "solchange" "%a (wpx: %b): %a\n" S.Var.pretty_trace x (HM.mem wpoint x) S.Dom.pretty_diff (wpd, old);
update_var_event x old wpd;
HM.replace rho x wpd;
destabilize x;
Expand Down Expand Up @@ -429,7 +431,8 @@ module Base =
if tracing then trace "sol2" "stable add %a\n" S.Var.pretty_trace y;
HM.replace stable y ();
if not (S.Dom.leq tmp old) then (
if tracing && not (S.Dom.is_bot old) then trace "solside" "side to %a (wpx: %b) from %a\n" S.Var.pretty_trace y (HM.mem wpoint y) (Pretty.docOpt (S.Var.pretty_trace ())) x;
if tracing && not (S.Dom.is_bot old) then trace "solside" "side to %a (wpx: %b) from %a: %a -> %a\n" S.Var.pretty_trace y (HM.mem wpoint y) (Pretty.docOpt (S.Var.pretty_trace ())) x S.Dom.pretty old S.Dom.pretty tmp;
if tracing && not (S.Dom.is_bot old) then trace "solchange" "side to %a (wpx: %b) from %a: %a\n" S.Var.pretty_trace y (HM.mem wpoint y) (Pretty.docOpt (S.Var.pretty_trace ())) x S.Dom.pretty_diff (tmp, old);
let sided = match x with
| Some x ->
let sided = VS.mem x old_sides in
Expand Down
Loading