-
Notifications
You must be signed in to change notification settings - Fork 84
Handle thread joins #137
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
Handle thread joins #137
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
be4f5e3
Add thread variable component to `ThreadCreate
sim642 44ff8c4
Add thread variable to threadenter, threadcombine and ctx.spawn
sim642 e041c8d
Add thread variable content to base analysis
sim642 37a22a8
Add hacky main thread join support
sim642 9fea9c1
Fix base ThreadCreate with local thread variable (uninitialized)
sim642 b193079
Fix thread analysis not checking if thread exited cleanly
sim642 828b1ac
Add forgotten thread variable in deadlocksByRaces
sim642 654bcf2
Merge branch 'thread/flag' into thread/join
sim642 f0467e7
Merge branch 'thread/flag' into thread/join
sim642 fd568e3
Merge branch 'thread/flag' into thread/join
sim642 81bb405
Add missing lval argument to threadenter/threadspawn in Poly
sim642 9ae617d
Merge branch 'thread/flag' into thread/join
sim642 35dcab6
Fix pthread_join arguments in some regression tests
sim642 1af0297
Add thread return value support
sim642 eea7f71
Add pthread_exit return value support
sim642 2b64bd5
Limit thread return value to only returning from thread functions
sim642 ced8e7f
Replace thread ID name based thread return check with standalone stac…
sim642 b75f8bf
Merge branch 'thread/flag' into thread/join
sim642 a5d6f30
Fix threadspawn without lval in base
sim642 6ee0e8d
Remove base dependency on threadid
sim642 72703a6
Merge branch 'thread/flag' into thread/join
sim642 b5dc093
Merge branch 'master' into thread/join
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
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 |
|---|---|---|
|
|
@@ -1637,7 +1637,7 @@ struct | |
| let find_fps e xs = Addr.to_var_must e @ xs in | ||
| let vars = AD.fold find_fps adrs [] in | ||
| let funs = List.filter (fun x -> isFunctionType x.vtype) vars in | ||
| List.iter (fun x -> ctx.spawn x []) funs | ||
| List.iter (fun x -> ctx.spawn None x []) funs | ||
| | _ -> () | ||
| ); | ||
| match lval with (* this section ensure global variables contain bottom values of the proper type before setting them *) | ||
|
|
@@ -1748,7 +1748,13 @@ struct | |
| | TFun(ret, _, _, _) -> ret | ||
| | _ -> assert false | ||
| in | ||
| set ~t_override ctx.ask ctx.global nst (return_var ()) t_override (eval_rv ctx.ask ctx.global ctx.local exp) | ||
| let rv = eval_rv ctx.ask ctx.global ctx.local exp in | ||
| let nst = | ||
| match ThreadId.get_current ctx.ask with | ||
| | `Lifted tid when ThreadReturn.is_current ctx.ask -> Tuple2.map1 (CPA.add tid rv) nst | ||
| | _ -> nst | ||
| in | ||
| set ~t_override ctx.ask ctx.global nst (return_var ()) t_override rv | ||
| (* lval_raw:None, and rval_raw:None is correct here *) | ||
|
|
||
| let vdecl ctx (v:varinfo) = | ||
|
|
@@ -1834,8 +1840,8 @@ struct | |
|
|
||
|
|
||
|
|
||
| let forkfun (ctx:(D.t, G.t, C.t) Analyses.ctx) (lv: lval option) (f: varinfo) (args: exp list) : (varinfo * exp list) list = | ||
| let create_thread arg v = | ||
| let forkfun (ctx:(D.t, G.t, C.t) Analyses.ctx) (lv: lval option) (f: varinfo) (args: exp list) : (lval option * varinfo * exp list) list = | ||
| let create_thread lval arg v = | ||
| try | ||
| (* try to get function declaration *) | ||
| let fd = Cilfacade.getdec v in | ||
|
|
@@ -1844,25 +1850,25 @@ struct | |
| | Some x -> [x] | ||
| | None -> List.map (fun x -> MyCFG.unknown_exp) fd.sformals | ||
| in | ||
| Some (v, args) | ||
| Some (lval, v, args) | ||
| with Not_found -> | ||
| if LF.use_special f.vname then None (* we handle this function *) | ||
| else if isFunctionType v.vtype then ( | ||
| M.warn_each ("Creating a thread from unknown function " ^ v.vname); | ||
| Some (v, args) | ||
| Some (lval, v, args) | ||
| ) else ( | ||
| M.warn_each ("Not creating a thread from " ^ v.vname ^ " because its type is " ^ sprint d_type v.vtype); | ||
| None | ||
| ) | ||
| in | ||
| match LF.classify f.vname args with | ||
| (* handling thread creations *) | ||
| | `ThreadCreate (start,ptc_arg) -> begin | ||
| | `ThreadCreate (id,start,ptc_arg) -> begin | ||
| (* extra sync so that we do not analyze new threads with bottom global invariant *) | ||
| publish_all ctx; | ||
| (* Collect the threads. *) | ||
| let start_addr = eval_tv ctx.ask ctx.global ctx.local start in | ||
| List.filter_map (create_thread (Some ptc_arg)) (AD.to_var_may start_addr) | ||
| List.filter_map (create_thread (Some (Mem id, NoOffset)) (Some ptc_arg)) (AD.to_var_may start_addr) | ||
| end | ||
| | `Unknown _ when get_bool "exp.unknown_funs_spawn" -> begin | ||
| let args = | ||
|
|
@@ -1872,7 +1878,7 @@ struct | |
| in | ||
| let flist = collect_funargs ctx.ask ctx.global ctx.local args in | ||
| let addrs = List.concat (List.map AD.to_var_may flist) in | ||
| List.filter_map (create_thread None) addrs | ||
| List.filter_map (create_thread None None) addrs | ||
| end | ||
| | _ -> [] | ||
|
|
||
|
|
@@ -1928,8 +1934,8 @@ struct | |
| let special ctx (lv:lval option) (f: varinfo) (args: exp list) = | ||
| (* let heap_var = heap_var !Tracing.current_loc in*) | ||
| let forks = forkfun ctx lv f args in | ||
| if M.tracing then if not (List.is_empty forks) then M.tracel "spawn" "Base.special %s: spawning functions %a\n" f.vname (d_list "," d_varinfo) (List.map fst forks); | ||
| List.iter (uncurry ctx.spawn) forks; | ||
| if M.tracing then if not (List.is_empty forks) then M.tracel "spawn" "Base.special %s: spawning functions %a\n" f.vname (d_list "," d_varinfo) (List.map BatTuple.Tuple3.second forks); | ||
| List.iter (BatTuple.Tuple3.uncurry ctx.spawn) forks; | ||
| let cpa,dep as st = ctx.local in | ||
| let gs = ctx.global in | ||
| match LF.classify f.vname args with | ||
|
|
@@ -2012,7 +2018,18 @@ struct | |
| end | ||
| | `Unknown "exit" -> raise Deadcode | ||
| | `Unknown "abort" -> raise Deadcode | ||
| | `Unknown "pthread_exit" -> raise Deadcode (* TODO: somehow actually return value, pthread_join doesn't handle anyway? *) | ||
| | `Unknown "pthread_exit" -> | ||
| begin match args with | ||
| | [exp] -> | ||
| begin match ThreadId.get_current ctx.ask with | ||
| | `Lifted tid -> | ||
| let rv = eval_rv ctx.ask ctx.global ctx.local exp in | ||
| ctx.sideg tid rv | ||
| | _ -> () | ||
| end; | ||
| raise Deadcode | ||
| | _ -> failwith "Unknown pthread_exit." | ||
| end | ||
| | `Unknown "__builtin_expect" -> | ||
| begin match lv with | ||
| | Some v -> assign ctx v (List.hd args) | ||
|
|
@@ -2023,10 +2040,20 @@ struct | |
| | Some x -> assign ctx x (List.hd args) | ||
| | None -> ctx.local | ||
| end | ||
| (* handling thread creations *) | ||
| | `ThreadCreate _ -> | ||
| D.bot () (* actual results joined via threadspawn *) | ||
| (* handling thread joins... sort of *) | ||
| | `ThreadJoin (id,ret_var) -> | ||
| begin match (eval_rv ctx.ask gs st ret_var) with | ||
| | `Int n when GU.opt_predicate (BI.equal BI.zero) (ID.to_int n) -> cpa,dep | ||
| | `Address ret_a -> | ||
| begin match eval_rv ctx.ask gs st id with | ||
| | `Address a -> | ||
| (* TODO: is this type right? *) | ||
| set ctx.ask gs st ret_a (Cil.typeOf ret_var) (get ctx.ask gs st a None) | ||
| | _ -> invalidate ctx.ask gs st [ret_var] | ||
| end | ||
| | _ -> invalidate ctx.ask gs st [ret_var] | ||
| end | ||
| | `Malloc size -> begin | ||
|
|
@@ -2145,15 +2172,25 @@ struct | |
| Printable.get_short_list (GU.demangle f.svar.vname ^ "(") ")" 80 args_short | ||
|
|
||
|
|
||
| let threadenter ctx (f: varinfo) (args: exp list): D.t = | ||
| let threadenter ctx (lval: lval option) (f: varinfo) (args: exp list): D.t = | ||
| try | ||
| make_entry ctx f args | ||
| with Not_found -> | ||
| (* Unknown functions *) | ||
| ctx.local | ||
|
|
||
| let threadspawn ctx (f: varinfo) (args: exp list) fctx: D.t = | ||
| D.bot () | ||
| let threadspawn ctx (lval: lval option) (f: varinfo) (args: exp list) fctx: D.t = | ||
| match lval with | ||
| | Some lval -> | ||
| begin match ThreadId.get_current fctx.ask with | ||
| | `Lifted tid -> | ||
| (* TODO: is this type right? *) | ||
| set ctx.ask ctx.global ctx.local (eval_lv ctx.ask ctx.global ctx.local lval) (Cil.typeOfLval lval) (`Address (AD.from_var tid)) | ||
|
Comment on lines
+2187
to
+2188
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to be considered after re-adding type to |
||
| | _ -> | ||
| ctx.local | ||
| end | ||
| | None -> | ||
| ctx.local | ||
| end | ||
|
|
||
| module type MainSpec = sig | ||
|
|
||
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
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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be considered after re-adding type to
set.