-
Notifications
You must be signed in to change notification settings - Fork 84
Analysis of pthread_cond
#520
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 all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
da81043
Analysis of must-received signals
michael-schwarz 5d51b27
Use MHP information
michael-schwarz e3a4c8a
Merge branch 'master' into signals
michael-schwarz f614ea2
Refactor MHP
michael-schwarz e5ade47
Make ocpindent happy
michael-schwarz 1f99cfb
Merge branch 'master' into signals
michael-schwarz 2af52ea
Switch signalling / waiting over to new library mechanism
michael-schwarz 6378203
pthread_cond_timedwait: mark argument `abstime` as read
michael-schwarz 7aee8be
Improve messages in pthreadSignals analysis
michael-schwarz b221784
Remove spurious check
michael-schwarz 0ffd04c
Generalize to several condition variables
michael-schwarz 6f54741
Use full power of MHP
michael-schwarz 108174c
Merge branch 'master' into signals
michael-schwarz 4353d73
Use pretty instead of show
michael-schwarz 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
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
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
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
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
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
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,113 @@ | ||
| (** Analysis of must-received pthread_signals. *) | ||
|
|
||
| open Prelude.Ana | ||
| open Analyses | ||
| module LF = LibraryFunctions | ||
|
|
||
| module Spec : Analyses.MCPSpec = | ||
| struct | ||
| module Signals = SetDomain.ToppedSet (ValueDomain.Addr) (struct let topname = "All signals" end) | ||
| module MustSignals = Lattice.Reverse (Signals) | ||
|
|
||
| include Analyses.DefaultSpec | ||
| module V = VarinfoV | ||
|
|
||
| let name () = "pthreadSignals" | ||
| module D = MustSignals | ||
| module C = MustSignals | ||
| module G = SetDomain.ToppedSet (MHP) (struct let topname = "All Threads" end) | ||
|
|
||
| let rec conv_offset x = | ||
| match x with | ||
| | `NoOffset -> `NoOffset | ||
| | `Index (Const (CInt (i,_,s)),o) -> `Index (IntDomain.of_const (i,Cilfacade.ptrdiff_ikind (),s), conv_offset o) | ||
| | `Index (_,o) -> `Index (ValueDomain.IndexDomain.top (), conv_offset o) | ||
| | `Field (f,o) -> `Field (f, conv_offset o) | ||
|
|
||
| let eval_exp_addr (a: Queries.ask) exp = | ||
| let gather_addr (v,o) b = ValueDomain.Addr.from_var_offset (v,conv_offset o) :: b in | ||
| match a.f (Queries.MayPointTo exp) with | ||
| | a when not (Queries.LS.is_top a) && not (Queries.LS.mem (dummyFunDec.svar,`NoOffset) a) -> | ||
| Queries.LS.fold gather_addr (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) [] | ||
| | _ -> [] | ||
|
|
||
| let possible_vinfos a cv_arg = | ||
| List.filter_map ValueDomain.Addr.to_var_may (eval_exp_addr a cv_arg) | ||
|
|
||
| (* transfer functions *) | ||
| let assign ctx (lval:lval) (rval:exp) : D.t = | ||
| ctx.local | ||
|
|
||
| let branch ctx (exp:exp) (tv:bool) : D.t = | ||
| ctx.local | ||
|
|
||
| let body ctx (f:fundec) : D.t = | ||
| ctx.local | ||
|
|
||
| let return ctx (exp:exp option) (f:fundec) : D.t = | ||
| ctx.local | ||
|
|
||
| let enter ctx (lval: lval option) (f:fundec) (args:exp list) : (D.t * D.t) list = | ||
| [ctx.local, ctx.local] | ||
|
|
||
| let combine ctx (lval:lval option) fexp (f:fundec) (args:exp list) fc (au:D.t) : D.t = | ||
| au | ||
|
|
||
| let special ctx (lval: lval option) (f:varinfo) (arglist:exp list) : D.t = | ||
| let desc = LF.find f in | ||
| match desc.special arglist with | ||
| | Signal cond | ||
| | Broadcast cond -> | ||
| let mhp = G.singleton @@ MHP.current (Analyses.ask_of_ctx ctx) in | ||
| let publish_one a = ctx.sideg a mhp in | ||
| let possible_vars = possible_vinfos (Analyses.ask_of_ctx ctx) cond in | ||
| List.iter publish_one possible_vars; | ||
| ctx.local | ||
| | Wait {cond = cond; _} -> | ||
| let current_mhp = MHP.current (Analyses.ask_of_ctx ctx) in | ||
| let module Signalled = struct | ||
| type signalled = Never | NotConcurrently | PossiblySignalled | ||
|
|
||
| let (|||) a b = match a,b with | ||
| | PossiblySignalled, _ | ||
| | _, PossiblySignalled -> PossiblySignalled | ||
| | NotConcurrently , _ | ||
| | _, NotConcurrently -> NotConcurrently | ||
| | Never, Never -> Never | ||
|
|
||
| let can_be_signalled a = | ||
| let signalling_tids = ctx.global a in | ||
| if G.is_top signalling_tids then | ||
| PossiblySignalled | ||
| else if G.is_empty signalling_tids then | ||
| Never | ||
| else if not @@ G.exists (MHP.may_happen_in_parallel current_mhp) signalling_tids then | ||
| NotConcurrently | ||
| else | ||
| PossiblySignalled | ||
| end | ||
| in | ||
| let open Signalled in | ||
| let add_if_singleton conds = match conds with | [a] -> Signals.add (ValueDomain.Addr.from_var a) ctx.local | _ -> ctx.local in | ||
| let conds = possible_vinfos (Analyses.ask_of_ctx ctx) cond in | ||
| (match List.fold_left (fun acc cond -> can_be_signalled cond ||| acc) Never conds with | ||
| | PossiblySignalled -> add_if_singleton conds | ||
| | NotConcurrently -> | ||
| (M.warn ~category:Deadcode "The condition variable(s) pointed to by %a are never signalled concurrently, succeeding code is live due to spurious wakeups only!" Basetype.CilExp.pretty cond; ctx.local) | ||
| | Never -> | ||
| (M.warn ~category:Deadcode "The condition variable(s) pointed to by %a are never signalled, succeeding code is live due to spurious wakeups only!" Basetype.CilExp.pretty cond; ctx.local) | ||
| ) | ||
|
|
||
| | TimedWait _ -> | ||
| (* Time could simply have elapsed *) | ||
| ctx.local | ||
| | _ -> ctx.local | ||
|
|
||
| let startstate v = Signals.empty () | ||
| let threadenter ctx lval f args = [ctx.local] | ||
| let threadspawn ctx lval f args fctx = ctx.local | ||
| let exitstate v = Signals.empty () | ||
| end | ||
|
|
||
| let _ = | ||
| MCP.register_analysis ~dep:["mutex"] (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
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,43 @@ | ||
| // PARAM: --set ana.activated[+] 'pthreadSignals' | ||
| #include<pthread.h> | ||
| #include<stdio.h> | ||
| #include<unistd.h> | ||
| #include <assert.h> | ||
|
|
||
| int g; | ||
|
|
||
| pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | ||
| pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | ||
|
|
||
| void* f1(void* ptr) { | ||
| int top; | ||
| pthread_mutex_lock(&mut); | ||
| g = 1; | ||
| if(top) { | ||
| pthread_cond_wait(&cond,&mut); //NOWARN | ||
| } | ||
| pthread_mutex_unlock(&mut); | ||
| return NULL; | ||
| } | ||
|
|
||
| void* f2(void* ptr) { | ||
| pthread_mutex_lock(&mut); | ||
| pthread_cond_signal(&cond); | ||
| pthread_mutex_unlock(&mut); | ||
| return NULL; | ||
| } | ||
|
|
||
| int main(int argc, char const *argv[]) | ||
| { | ||
| pthread_t t1; | ||
| pthread_t t2; | ||
|
|
||
| pthread_create(&t1,NULL,f1,NULL); | ||
| sleep(1); | ||
| pthread_create(&t2,NULL,f2,NULL); | ||
|
|
||
| pthread_join(t1, NULL); | ||
| pthread_join(t2, NULL); | ||
|
|
||
| return 0; | ||
| } |
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,30 @@ | ||
| // PARAM: --set ana.activated[+] 'pthreadSignals' | ||
| #include<pthread.h> | ||
| #include<stdio.h> | ||
| #include<unistd.h> | ||
| #include <assert.h> | ||
|
|
||
| int g; | ||
|
|
||
| pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | ||
| pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | ||
|
|
||
| void* f1(void* ptr) { | ||
| int top; | ||
| pthread_mutex_lock(&mut); | ||
| int res = 0; | ||
| pthread_cond_wait(&cond,&mut); //WARN | ||
| assert(res == 0); | ||
| pthread_mutex_unlock(&mut); | ||
| return NULL; | ||
| } | ||
|
|
||
| int main(int argc, char const *argv[]) | ||
| { | ||
| pthread_t t1; | ||
| pthread_t t2; | ||
|
|
||
| pthread_create(&t1,NULL,f1,NULL); | ||
|
|
||
| return 0; | ||
| } |
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,38 @@ | ||
| // PARAM: --set ana.activated[+] 'pthreadSignals' --set ana.activated[+] 'threadJoins' | ||
| #include<pthread.h> | ||
| #include<stdio.h> | ||
| #include<unistd.h> | ||
| #include <assert.h> | ||
|
|
||
| int g; | ||
|
|
||
| pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | ||
| pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | ||
|
|
||
| void* f1(void* ptr) { | ||
| int top; | ||
| pthread_mutex_lock(&mut); | ||
| int res = 0; | ||
| pthread_cond_wait(&cond,&mut); //WARN | ||
| pthread_mutex_unlock(&mut); | ||
| return NULL; | ||
| } | ||
|
|
||
| void* f2(void* ptr) { | ||
| pthread_mutex_lock(&mut); | ||
| pthread_cond_signal(&cond); | ||
| pthread_mutex_unlock(&mut); | ||
| return NULL; | ||
| } | ||
|
|
||
| int main(int argc, char const *argv[]) | ||
| { | ||
| pthread_t t1; | ||
| pthread_t t2; | ||
|
|
||
| pthread_create(&t2,NULL,f2,NULL); | ||
| pthread_join(t2,NULL); | ||
| pthread_create(&t1,NULL,f1,NULL); | ||
|
|
||
| return 0; | ||
| } |
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,41 @@ | ||
| // PARAM: --set ana.activated[+] 'pthreadSignals' --set ana.activated[+] 'threadJoins' | ||
| #include<pthread.h> | ||
| #include<stdio.h> | ||
| #include<unistd.h> | ||
| #include <assert.h> | ||
|
|
||
| void* f2(void*); | ||
|
|
||
| pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | ||
| pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | ||
|
|
||
| void* f1(void* ptr) { | ||
| int top; | ||
| pthread_mutex_lock(&mut); | ||
| int res = 0; | ||
| pthread_cond_wait(&cond,&mut); //WARN | ||
| pthread_mutex_unlock(&mut); | ||
|
|
||
| pthread_t t; | ||
| pthread_create(&t,NULL,f2,NULL); | ||
| return NULL; | ||
| } | ||
|
|
||
| void* f2(void* ptr) { | ||
| pthread_mutex_lock(&mut); | ||
| pthread_cond_signal(&cond); | ||
| pthread_mutex_unlock(&mut); | ||
| return NULL; | ||
| } | ||
|
|
||
| int main(int argc, char const *argv[]) | ||
| { | ||
| pthread_t t1; | ||
| pthread_t t2; | ||
|
|
||
| pthread_create(&t2,NULL,f2,NULL); | ||
| pthread_join(t2,NULL); | ||
| pthread_create(&t1,NULL,f1,NULL); | ||
|
|
||
| return 0; | ||
| } |
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.