-
Notifications
You must be signed in to change notification settings - Fork 84
Refactor race warnings (accesses) to use global invariant on master #519
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
Merged
Merged
Changes from 41 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
b0fd976
Copy mutex analysis to race analysis
sim642 48e0cd6
Remove race access logic from mutex analysis
sim642 359019b
Remove mutex logic from race analysis
sim642 c7ffcc7
Activate race analysis by default
sim642 66583d7
Fix protecting locksets by adding Access event
sim642 7a190ce
Rename race analysis -> access analysis
sim642 ebc6f8c
Add access analysis in ana.activated of regression tests
sim642 412a9b9
Add access analysis dependency to mutex analysis
sim642 6006ed5
Remove unused from mutex analysis
sim642 32818de
Remove unused from access analysis
sim642 6f47ee0
Remove unused module aliases from mutex and access analysis
sim642 88e194e
Add hack to allow verify to add accesses to solution
sim642 47dac54
Add WarnGlobal query
sim642 5f3a5dd
Add access collecting into global invariant
sim642 43573d3
Add race warnings based on access analysis global invariant
sim642 5b48a3a
Fix verify of None in access analysis
sim642 f205189
Fix WarnGlobal crashes with default bottom value
sim642 3fbfd0e
Move access domain definitions to Access
sim642 e1498d5
Move access analysis warnings to Access
sim642 36f50d9
Add race summary using access analysis
sim642 36ba839
Add some_accesses condition to access analysis
sim642 70f567b
Add is_all_safe to access analysis
sim642 6dbeea9
Use access analysis for SV-COMP data races
sim642 e6d7632
Remove access table functions
sim642 9cc4542
Remove access table
sim642 92d1c7e
Inline Acc_typHashable in Access
sim642 df02b73
Add comment about Access lattice structure
sim642 a38ba50
Remove unused locks intersection component from access mapping
sim642 4bd10bf
Remove old unused access table functions
sim642 16c7601
Remove access table some_accesses
sim642 56564c1
Remove WarnGlobal debug print
sim642 b0ce3da
Fix access summary during incremental load
sim642 f3d671e
Add timing to warn_global
sim642 6a9fc3e
Fix Access.add_struct bypassing should_warn
sim642 41270cc
Change access analysis global leq hack to only apply during postsolving
sim642 2f05e2d
Merge branch 'master' into access-analysis
sim642 90043bf
Fix Access.check_safe crash due to polymorphic Set
sim642 cbdcb67
Refactor access analysis globals
sim642 694bc15
Add hash to access offsets
sim642 96b3c1a
Fix typos in access analysis comments
sim642 d225832
Add access analysis to svcomp22 conf
sim642 4ee387e
Remove outdated comment from access analysis
sim642 21ced5a
Temporarily skip failing 00-basic/06-threadid incremental test
sim642 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| "threadreturn", | ||
| "mallocWrapper", | ||
| "mutex", | ||
| "access", | ||
| "escape", | ||
| "expRelation", | ||
| "var_eq", | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
| "threadflag", | ||
| "mallocWrapper", | ||
| "mutex", | ||
| "access", | ||
| "escape", | ||
| "expRelation", | ||
| "var_eq", | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
| "threadflag", | ||
| "mallocWrapper", | ||
| "mutex", | ||
| "access", | ||
| "escape", | ||
| "expRelation", | ||
| "var_eq", | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,231 @@ | ||
| (** Access and data race analysis. *) | ||
|
|
||
| module M = Messages | ||
| module LF = LibraryFunctions | ||
| open Prelude.Ana | ||
| open Analyses | ||
| open GobConfig | ||
|
|
||
|
|
||
| (** Access and data race analyzer without base --- this is the new standard *) | ||
| module Spec = | ||
| struct | ||
| include Analyses.DefaultSpec | ||
|
|
||
| let name () = "access" | ||
|
|
||
| (** Add current lockset alongside to the base analysis domain. Global data is collected using dirty side-effecting. *) | ||
| module D = Lattice.Unit | ||
| module C = Lattice.Unit | ||
|
|
||
| module G = | ||
| struct | ||
| include Access.PM | ||
|
|
||
| let leq x y = !GU.postsolving || leq x y (* HACK: to pass verify*) | ||
| end | ||
| module V = Printable.Prod (Access.LVOpt) (Access.T) | ||
|
|
||
| let safe = ref 0 | ||
| let vulnerable = ref 0 | ||
| let unsafe = ref 0 | ||
|
|
||
| let init marshal = | ||
| safe := 0; | ||
| vulnerable := 0; | ||
| unsafe := 0 | ||
|
|
||
| let side_access ctx ty lv_opt ls_opt (conf, w, loc, e, lp) = | ||
| if !GU.should_warn then ( | ||
| let d = | ||
| let open Access in | ||
| PM.singleton ls_opt ( | ||
| AS.singleton (conf, w, loc, e, lp) | ||
| ) | ||
| in | ||
| ctx.sideg (lv_opt, ty) d | ||
| ) | ||
| else | ||
| ctx.sideg (lv_opt, ty) (G.bot ()) (* HACK: just to pass validation with MCP DomVariantLattice *) | ||
michael-schwarz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| let do_access (ctx: (D.t, G.t, C.t, V.t) ctx) (w:bool) (reach:bool) (conf:int) (e:exp) = | ||
| let open Queries in | ||
| let part_access ctx (e:exp) (vo:varinfo option) (w: bool) = | ||
| ctx.emit (Access {var_opt=vo; write=w}); | ||
| (*partitions & locks*) | ||
| ctx.ask (PartAccess {exp=e; var_opt=vo; write=w}) | ||
| in | ||
| let add_access conf vo oo = | ||
| let (po,pd) = part_access ctx e vo w in | ||
| Access.add (side_access ctx) e w conf vo oo (po,pd); | ||
| in | ||
| let add_access_struct conf ci = | ||
| let (po,pd) = part_access ctx e None w in | ||
| Access.add_struct (side_access ctx) e w conf (`Struct (ci,`NoOffset)) None (po,pd) | ||
| in | ||
| let has_escaped g = ctx.ask (Queries.MayEscape g) in | ||
| (* The following function adds accesses to the lval-set ls | ||
| -- this is the common case if we have a sound points-to set. *) | ||
| let on_lvals ls includes_uk = | ||
| let ls = LS.filter (fun (g,_) -> g.vglob || has_escaped g) ls in | ||
| let conf = if reach then conf - 20 else conf in | ||
| let conf = if includes_uk then conf - 10 else conf in | ||
| let f (var, offs) = | ||
| let coffs = Lval.CilLval.to_ciloffs offs in | ||
| if CilType.Varinfo.equal var dummyFunDec.svar then | ||
| add_access conf None (Some coffs) | ||
| else | ||
| add_access conf (Some var) (Some coffs) | ||
| in | ||
| LS.iter f ls | ||
| in | ||
| let reach_or_mpt = if reach then ReachableFrom e else MayPointTo e in | ||
| match ctx.ask reach_or_mpt with | ||
| | ls when not (LS.is_top ls) && not (Queries.LS.mem (dummyFunDec.svar,`NoOffset) ls) -> | ||
| (* the case where the points-to set is non top and does not contain unknown values *) | ||
| on_lvals ls false | ||
| | ls when not (LS.is_top ls) -> | ||
| (* the case where the points-to set is non top and contains unknown values *) | ||
| let includes_uk = ref false in | ||
| (* now we need to access all fields that might be pointed to: is this correct? *) | ||
| begin match ctx.ask (ReachableUkTypes e) with | ||
| | ts when Queries.TS.is_top ts -> | ||
| includes_uk := true | ||
| | ts -> | ||
| if Queries.TS.is_empty ts = false then | ||
| includes_uk := true; | ||
| let f = function | ||
| | TComp (ci, _) -> | ||
| add_access_struct (conf - 50) ci | ||
| | _ -> () | ||
| in | ||
| Queries.TS.iter f ts | ||
| end; | ||
| on_lvals ls !includes_uk | ||
| | _ -> | ||
| add_access (conf - 60) None None | ||
|
|
||
| let access_one_top ?(force=false) ctx write reach exp = | ||
| (* ignore (Pretty.printf "access_one_top %b %b %a:\n" write reach d_exp exp); *) | ||
| if force || ThreadFlag.is_multi (Analyses.ask_of_ctx ctx) then ( | ||
| let conf = 110 in | ||
| if reach || write then do_access ctx write reach conf exp; | ||
| Access.distribute_access_exp (do_access ctx) false false conf exp; | ||
| ) | ||
|
|
||
| (** We just lift start state, global and dependency functions: *) | ||
| let startstate v = () | ||
| let threadenter ctx lval f args = [()] | ||
| let exitstate v = () | ||
|
|
||
|
|
||
| (** Transfer functions: *) | ||
|
|
||
| let assign ctx lval rval : D.t = | ||
| (* ignore global inits *) | ||
| if !GU.global_initialization then ctx.local else begin | ||
| access_one_top ctx true false (AddrOf lval); | ||
| access_one_top ctx false false rval; | ||
| ctx.local | ||
| end | ||
|
|
||
| let branch ctx exp tv : D.t = | ||
| access_one_top ctx false false exp; | ||
| ctx.local | ||
|
|
||
| let return ctx exp fundec : D.t = | ||
| begin match exp with | ||
| | Some exp -> access_one_top ctx false false exp | ||
| | None -> () | ||
| end; | ||
| ctx.local | ||
|
|
||
| let body ctx f : D.t = | ||
| ctx.local | ||
|
|
||
| let special ctx lv f arglist : D.t = | ||
| match (LF.classify f.vname arglist, f.vname) with | ||
| (* TODO: remove cases *) | ||
| | _, "_lock_kernel" -> | ||
| ctx.local | ||
| | _, "_unlock_kernel" -> | ||
| ctx.local | ||
| | `Lock (failing, rw, nonzero_return_when_aquired), _ | ||
| -> ctx.local | ||
| | `Unlock, "__raw_read_unlock" | ||
| | `Unlock, "__raw_write_unlock" -> | ||
| ctx.local | ||
| | `Unlock, _ -> | ||
| ctx.local | ||
| | _, "spinlock_check" -> ctx.local | ||
| | _, "acquire_console_sem" when get_bool "kernel" -> | ||
| ctx.local | ||
| | _, "release_console_sem" when get_bool "kernel" -> | ||
| ctx.local | ||
| | _, "__builtin_prefetch" | _, "misc_deregister" -> | ||
| ctx.local | ||
| | _, "__VERIFIER_atomic_begin" when get_bool "ana.sv-comp.functions" -> | ||
| ctx.local | ||
| | _, "__VERIFIER_atomic_end" when get_bool "ana.sv-comp.functions" -> | ||
| ctx.local | ||
| | _, "pthread_cond_wait" | ||
| | _, "pthread_cond_timedwait" -> | ||
| ctx.local | ||
| | _, x -> | ||
| let arg_acc act = | ||
| match LF.get_threadsafe_inv_ac x with | ||
| | Some fnc -> (fnc act arglist) | ||
| | _ -> arglist | ||
| in | ||
| List.iter (access_one_top ctx false true) (arg_acc `Read); | ||
| List.iter (access_one_top ctx true true ) (arg_acc `Write); | ||
| (match lv with | ||
| | Some x -> access_one_top ctx true false (AddrOf x) | ||
| | None -> ()); | ||
| ctx.local | ||
|
|
||
| let enter ctx lv f args : (D.t * D.t) list = | ||
| [(ctx.local,ctx.local)] | ||
|
|
||
| let combine ctx lv fexp f args fc al = | ||
| access_one_top ctx false false fexp; | ||
| begin match lv with | ||
| | None -> () | ||
| | Some lval -> access_one_top ctx true false (AddrOf lval) | ||
| end; | ||
| List.iter (access_one_top ctx false false) args; | ||
| al | ||
|
|
||
|
|
||
| let threadspawn ctx lval f args fctx = | ||
| (* must explicitly access thread ID lval because special to pthread_create doesn't if singlethreaded before *) | ||
| begin match lval with | ||
| | None -> () | ||
| | Some lval -> access_one_top ~force:true ctx true false (AddrOf lval) (* must force because otherwise doesn't if singlethreaded before *) | ||
| end; | ||
| ctx.local | ||
|
|
||
| let query ctx (type a) (q: a Queries.t): a Queries.result = | ||
| match q with | ||
| | WarnGlobal g -> | ||
| let g: V.t = Obj.obj g in | ||
| (* ignore (Pretty.printf "WarnGlobal %a\n" CilType.Varinfo.pretty g); *) | ||
| let pm = ctx.global g in | ||
| Access.print_accesses g pm; | ||
| Access.incr_summary safe vulnerable unsafe g pm | ||
| | _ -> Queries.Result.top q | ||
|
|
||
| let finalize () = | ||
| let total = !safe + !unsafe + !vulnerable in | ||
| if total > 0 then ( | ||
| ignore (Pretty.printf "\nSummary for all memory locations:\n"); | ||
| ignore (Pretty.printf "\tsafe: %5d\n" !safe); | ||
| ignore (Pretty.printf "\tvulnerable: %5d\n" !vulnerable); | ||
| ignore (Pretty.printf "\tunsafe: %5d\n" !unsafe); | ||
| ignore (Pretty.printf "\t-------------------\n"); | ||
| ignore (Pretty.printf "\ttotal: %5d\n" total) | ||
| ) | ||
| end | ||
|
|
||
| let _ = | ||
| MCP.register_analysis (module Spec : MCPSpec) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.