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

Spawn threads created from unknown functions as non-unique #1187

Merged
merged 7 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion src/analyses/abortUnless.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct
false

let startstate v = false
let threadenter ctx lval f args = [false]
let threadenter ctx ~multiple lval f args = [false]
let threadspawn ctx lval f args fctx = false
let exitstate v = false
end
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/accessAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ struct

(** We just lift start state, global and dependency functions: *)
let startstate v = ()
let threadenter ctx lval f args = [()]
let threadenter ctx ~multiple lval f args = [()]
let exitstate v = ()
let context fd d = ()

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/activeLongjmp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct

(* Initial values don't really matter: overwritten at longjmp call. *)
let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let query ctx (type a) (q: a Queries.t): a Queries.result =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/activeSetjmp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct
| _ -> ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let query ctx (type a) (q: a Queries.t): a Queries.result =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/apron/relationAnalysis.apron.ml
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ struct

(* Thread transfer functions. *)

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
let st = ctx.local in
match Cilfacade.find_varinfo_fundec f with
| fd ->
Expand Down
16 changes: 8 additions & 8 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1902,7 +1902,7 @@ struct



let forkfun (ctx:(D.t, G.t, C.t, V.t) Analyses.ctx) (lv: lval option) (f: varinfo) (args: exp list) : (lval option * varinfo * exp list) list =
let forkfun (ctx:(D.t, G.t, C.t, V.t) Analyses.ctx) (lv: lval option) (f: varinfo) (args: exp list) : (lval option * varinfo * exp list) list * bool =
let create_thread lval arg v =
try
(* try to get function declaration *)
Expand Down Expand Up @@ -1943,7 +1943,7 @@ struct
else
start_funvars
in
List.filter_map (create_thread (Some (Mem id, NoOffset)) (Some ptc_arg)) start_funvars_with_unknown
List.filter_map (create_thread (Some (Mem id, NoOffset)) (Some ptc_arg)) start_funvars_with_unknown, false
end
| _, _ when get_bool "sem.unknown_function.spawn" ->
(* TODO: Remove sem.unknown_function.spawn check because it is (and should be) really done in LibraryFunctions.
Expand All @@ -1956,9 +1956,9 @@ struct
let deep_flist = collect_invalidate ~deep:true (Analyses.ask_of_ctx ctx) ctx.global ctx.local deep_args in
let flist = shallow_flist @ deep_flist in
let addrs = List.concat_map AD.to_var_may flist in
if addrs <> [] then M.debug ~category:Analyzer "Spawning functions from unknown function: %a" (d_list ", " CilType.Varinfo.pretty) addrs;
List.filter_map (create_thread None None) addrs
| _, _ -> []
if addrs <> [] then M.debug ~category:Analyzer "Spawning non-unique functions from unknown function: %a" (d_list ", " CilType.Varinfo.pretty) addrs;
List.filter_map (create_thread None None) addrs, true
| _, _ -> [], false

let assert_fn ctx e refine =
(* make the state meet the assertion in the rest of the code *)
Expand Down Expand Up @@ -2024,9 +2024,9 @@ struct
let addr = eval_lv (Analyses.ask_of_ctx ctx) ctx.global ctx.local lval in
(addr, AD.type_of addr)
in
let forks = forkfun ctx lv f args in
let forks, multiple = 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 "," CilType.Varinfo.pretty) (List.map BatTuple.Tuple3.second forks);
List.iter (BatTuple.Tuple3.uncurry ctx.spawn) forks;
List.iter (BatTuple.Tuple3.uncurry (ctx.spawn ~multiple)) forks;
let st: store = ctx.local in
let gs = ctx.global in
let desc = LF.find f in
Expand Down Expand Up @@ -2503,7 +2503,7 @@ struct
in
combine_one ctx.local after

let threadenter ctx (lval: lval option) (f: varinfo) (args: exp list): D.t list =
let threadenter ctx ~multiple (lval: lval option) (f: varinfo) (args: exp list): D.t list =
match Cilfacade.find_varinfo_fundec f with
| fd ->
[make_entry ~thread:true ctx fd args]
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/condVars.ml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ struct
ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.bot ()
end
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/expsplit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct
in
emit_splits ctx d

let threadenter ctx lval f args = [ctx.local]
let threadenter ctx ~multiple lval f args = [ctx.local]

let threadspawn ctx lval f args fctx =
emit_splits_ctx ctx
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/extractPthread.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ module Spec : Analyses.MCPSpec = struct
(Ctx.top ())


let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
let d : D.t = ctx.local in
let tasks = ctx.global tasks_var in
(* TODO: optimize finding *)
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/fileUse.ml
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ struct
| _ -> m

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.bot ()
end
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/locksetAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct
module C = D

let startstate v = D.empty ()
let threadenter ctx lval f args = [D.empty ()]
let threadenter ctx ~multiple lval f args = [D.empty ()]
let exitstate v = D.empty ()
end

Expand Down
12 changes: 6 additions & 6 deletions src/analyses/mCP.ml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ struct
f ((k,v::a')::a) b
in f [] xs

let do_spawns ctx (xs:(varinfo * (lval option * exp list)) list) =
let do_spawns ctx (xs:(varinfo * (lval option * exp list * bool)) list) =
let spawn_one v d =
List.iter (fun (lval, args) -> ctx.spawn lval v args) d
List.iter (fun (lval, args, multiple) -> ctx.spawn ~multiple lval v args) d
in
if not (get_bool "exp.single-threaded") then
iter (uncurry spawn_one) @@ group_assoc_eq Basetype.Variables.equal xs
Expand Down Expand Up @@ -322,8 +322,8 @@ struct

and outer_ctx tfname ?spawns ?sides ?emits ctx =
let spawn = match spawns with
| Some spawns -> (fun l v a -> spawns := (v,(l,a)) :: !spawns)
| None -> (fun v d -> failwith ("Cannot \"spawn\" in " ^ tfname ^ " context."))
| Some spawns -> (fun ?(multiple=false) l v a -> spawns := (v,(l,a,multiple)) :: !spawns)
| None -> (fun ?(multiple=false) v d -> failwith ("Cannot \"spawn\" in " ^ tfname ^ " context."))
in
let sideg = match sides with
| Some sides -> (fun v g -> sides := (v, (!WideningTokens.side_tokens, g)) :: !sides)
Expand Down Expand Up @@ -565,13 +565,13 @@ struct
let d = do_emits ctx !emits d q in
if q then raise Deadcode else d

let threadenter (ctx:(D.t, G.t, C.t, V.t) ctx) lval f a =
let threadenter (ctx:(D.t, G.t, C.t, V.t) ctx) ~multiple lval f a =
let sides = ref [] in
let emits = ref [] in
let ctx'' = outer_ctx "threadenter" ~sides ~emits ctx in
let f (n,(module S:MCPSpec),d) =
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "threadenter" ctx'' n d in
map (fun d -> (n, repr d)) @@ S.threadenter ctx' lval f a
map (fun d -> (n, repr d)) @@ (S.threadenter ~multiple) ctx' lval f a
in
let css = map f @@ spec_list ctx.local in
do_sideg ctx !sides;
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/mallocFresh.ml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct
| None -> ctx.local
| Some lval -> assign_lval (Analyses.ask_of_ctx ctx) lval ctx.local

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[D.empty ()]

let threadspawn ctx lval f args fctx =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/malloc_null.ml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ struct
let name () = "malloc_null"

let startstate v = D.empty ()
let threadenter ctx lval f args = [D.empty ()]
let threadenter ctx ~multiple lval f args = [D.empty ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.empty ()

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/modifiedSinceLongjmp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct
ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let query ctx (type a) (q: a Queries.t): a Queries.result =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/mutexTypeAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct
| _ -> ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.top ()]
let threadenter ctx ~multiple lval f args = [D.top ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.top ()

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/poisonVariables.ml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct
VS.join au ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let event ctx e octx =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/pthreadSignals.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct
| _ -> ctx.local

let startstate v = Signals.empty ()
let threadenter ctx lval f args = [ctx.local]
let threadenter ctx ~multiple lval f args = [ctx.local]
let exitstate v = Signals.empty ()
end

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/region.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ struct
let startstate v =
`Lifted (RegMap.bot ())

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[`Lifted (RegMap.bot ())]
let threadspawn ctx lval f args fctx = ctx.local

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/spec.ml
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ struct


let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.bot ()
end
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/stackTrace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct
ctx.local (* keep local as opposed to IdentitySpec *)

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()
end

Expand All @@ -45,7 +45,7 @@ struct
let startstate v = D.bot ()
let exitstate v = D.top ()

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[D.push !Tracing.current_loc ctx.local]
end

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/symbLocks.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct
let name () = "symb_locks"

let startstate v = D.top ()
let threadenter ctx lval f args = [D.top ()]
let threadenter ctx ~multiple lval f args = [D.top ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.top ()

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/taintPartialContexts.ml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ struct
d

let startstate v = D.bot ()
let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[D.bot ()]
let threadspawn ctx lval f args fctx =
match lval with
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/termination.ml
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ struct
(* | _ -> ctx.local *)

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.bot ()
end

Expand Down
8 changes: 7 additions & 1 deletion src/analyses/threadAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@ struct
| _ -> Queries.Result.top q

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]

let threadenter ctx ~multiple lval f args =
if multiple then
(let tid = ThreadId.get_current_unlift (Analyses.ask_of_ctx ctx) in
ctx.sideg tid (true, TS.bot (), false));
[D.bot ()]

let threadspawn ctx lval f args fctx =
let creator = ThreadId.get_current (Analyses.ask_of_ctx ctx) in
let tid = ThreadId.get_current_unlift (Analyses.ask_of_ctx fctx) in
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/threadEscape.ml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ struct
let startstate v = D.bot ()
let exitstate v = D.bot ()

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[D.bot ()]

let threadspawn ctx lval f args fctx =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/threadFlag.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct
let access ctx _ =
is_currently_multi (Analyses.ask_of_ctx ctx)

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
if not (has_ever_been_multi (Analyses.ask_of_ctx ctx)) then
ctx.emit Events.EnterMultiThreaded;
[create_tid f]
Expand Down
8 changes: 4 additions & 4 deletions src/analyses/threadId.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ struct
Hashtbl.replace !tids tid ();
(N.bot (), `Lifted (tid), (TD.bot (), TD.bot ()))

let create_tid (_, current, (td, _)) ((node, index): Node.t * int option) v =
let create_tid ?(multiple=false) (_, current, (td, _)) ((node, index): Node.t * int option) v =
match current with
| `Lifted current ->
| `Lifted current when not multiple ->
let+ tid = Thread.threadenter (current, td) node index v in
if GobConfig.get_bool "dbg.print_tids" then
Hashtbl.replace !tids tid ();
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -133,9 +133,9 @@ struct
| `Lifted node, count -> node, Some count
| (`Bot | `Top), _ -> ctx.prev_node, None

let threadenter ctx lval f args:D.t list =
let threadenter ctx ~multiple lval f args:D.t list =
let n, i = indexed_node_for_ctx ctx in
let+ tid = create_tid ctx.local (n, i) f in
let+ tid = create_tid ~multiple ctx.local (n, i) f in
(`Lifted (f, n, i), tid, (TD.bot (), TD.bot ()))

let threadspawn ctx lval f args fctx =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/threadReturn.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct
ctx.local (* keep local as opposed to IdentitySpec *)

let startstate v = true
let threadenter ctx lval f args = [true]
let threadenter ctx ~multiple lval f args = [true]
let exitstate v = D.top ()

let query (ctx: (D.t, _, _, _) ctx) (type a) (x: a Queries.t): a Queries.result =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/tmpSpecial.ml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct
| _ -> Queries.Result.top q

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.bot ()
end
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/tutorials/taint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ struct

(* You may leave these alone *)
let startstate v = D.bot ()
let threadenter ctx lval f args = [D.top ()]
let threadenter ctx ~multiple lval f args = [D.top ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.top ()
end
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/tutorials/unitAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct
ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.top ()]
let threadenter ctx ~multiple lval f args = [D.top ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v = D.top ()
end
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/uninit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct
let name () = "uninit"

let startstate v : D.t = D.empty ()
let threadenter ctx lval f args = [D.empty ()]
let threadenter ctx ~multiple lval f args = [D.empty ()]
let threadspawn ctx lval f args fctx = ctx.local
let exitstate v : D.t = D.empty ()

Expand Down
Loading