Skip to content

Commit 5f4f94b

Browse files
Merge pull request #1187 from goblint/issue_843
Spawn threads created from unknown functions as non-unique
2 parents 808e91d + 809e5a0 commit 5f4f94b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+214
-157
lines changed

src/analyses/abortUnless.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ struct
6565
false
6666

6767
let startstate v = false
68-
let threadenter ctx lval f args = [false]
69-
let threadspawn ctx lval f args fctx = false
68+
let threadenter ctx ~multiple lval f args = [false]
69+
let threadspawn ctx ~multiple lval f args fctx = false
7070
let exitstate v = false
7171
end
7272

src/analyses/accessAnalysis.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct
5454

5555
(** We just lift start state, global and dependency functions: *)
5656
let startstate v = ()
57-
let threadenter ctx lval f args = [()]
57+
let threadenter ctx ~multiple lval f args = [()]
5858
let exitstate v = ()
5959
let context fd d = ()
6060

@@ -121,7 +121,7 @@ struct
121121
ctx.local
122122

123123

124-
let threadspawn ctx lval f args fctx =
124+
let threadspawn ctx ~multiple lval f args fctx =
125125
(* must explicitly access thread ID lval because special to pthread_create doesn't if singlethreaded before *)
126126
begin match lval with
127127
| None -> ()

src/analyses/activeLongjmp.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct
2626

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

3232
let query ctx (type a) (q: a Queries.t): a Queries.result =

src/analyses/activeSetjmp.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct
2525
| _ -> ctx.local
2626

2727
let startstate v = D.bot ()
28-
let threadenter ctx lval f args = [D.bot ()]
28+
let threadenter ctx ~multiple lval f args = [D.bot ()]
2929
let exitstate v = D.top ()
3030

3131
let query ctx (type a) (q: a Queries.t): a Queries.result =

src/analyses/apron/relationAnalysis.apron.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ struct
647647

648648
(* Thread transfer functions. *)
649649

650-
let threadenter ctx lval f args =
650+
let threadenter ctx ~multiple lval f args =
651651
let st = ctx.local in
652652
match Cilfacade.find_varinfo_fundec f with
653653
| fd ->
@@ -665,7 +665,7 @@ struct
665665
(* TODO: do something like base? *)
666666
failwith "relation.threadenter: unknown function"
667667

668-
let threadspawn ctx lval f args fctx =
668+
let threadspawn ctx ~multiple lval f args fctx =
669669
ctx.local
670670

671671
let event ctx e octx =

src/analyses/base.ml

+9-9
Original file line numberDiff line numberDiff line change
@@ -1944,7 +1944,7 @@ struct
19441944

19451945

19461946

1947-
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 =
1947+
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 =
19481948
let create_thread lval arg v =
19491949
try
19501950
(* try to get function declaration *)
@@ -1985,7 +1985,7 @@ struct
19851985
else
19861986
start_funvars
19871987
in
1988-
List.filter_map (create_thread (Some (Mem id, NoOffset)) (Some ptc_arg)) start_funvars_with_unknown
1988+
List.filter_map (create_thread (Some (Mem id, NoOffset)) (Some ptc_arg)) start_funvars_with_unknown, false
19891989
end
19901990
| _, _ when get_bool "sem.unknown_function.spawn" ->
19911991
(* TODO: Remove sem.unknown_function.spawn check because it is (and should be) really done in LibraryFunctions.
@@ -1998,9 +1998,9 @@ struct
19981998
let deep_flist = collect_invalidate ~deep:true (Analyses.ask_of_ctx ctx) ctx.global ctx.local deep_args in
19991999
let flist = shallow_flist @ deep_flist in
20002000
let addrs = List.concat_map AD.to_var_may flist in
2001-
if addrs <> [] then M.debug ~category:Analyzer "Spawning functions from unknown function: %a" (d_list ", " CilType.Varinfo.pretty) addrs;
2002-
List.filter_map (create_thread None None) addrs
2003-
| _, _ -> []
2001+
if addrs <> [] then M.debug ~category:Analyzer "Spawning non-unique functions from unknown function: %a" (d_list ", " CilType.Varinfo.pretty) addrs;
2002+
List.filter_map (create_thread None None) addrs, true
2003+
| _, _ -> [], false
20042004

20052005
let assert_fn ctx e refine =
20062006
(* make the state meet the assertion in the rest of the code *)
@@ -2131,9 +2131,9 @@ struct
21312131
let addr = eval_lv (Analyses.ask_of_ctx ctx) ctx.global ctx.local lval in
21322132
(addr, AD.type_of addr)
21332133
in
2134-
let forks = forkfun ctx lv f args in
2134+
let forks, multiple = forkfun ctx lv f args in
21352135
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);
2136-
List.iter (BatTuple.Tuple3.uncurry ctx.spawn) forks;
2136+
List.iter (BatTuple.Tuple3.uncurry (ctx.spawn ~multiple)) forks;
21372137
let st: store = ctx.local in
21382138
let gs = ctx.global in
21392139
let desc = LF.find f in
@@ -2641,7 +2641,7 @@ struct
26412641
in
26422642
combine_one ctx.local after
26432643

2644-
let threadenter ctx (lval: lval option) (f: varinfo) (args: exp list): D.t list =
2644+
let threadenter ctx ~multiple (lval: lval option) (f: varinfo) (args: exp list): D.t list =
26452645
match Cilfacade.find_varinfo_fundec f with
26462646
| fd ->
26472647
[make_entry ~thread:true ctx fd args]
@@ -2651,7 +2651,7 @@ struct
26512651
let st = special_unknown_invalidate ctx (Analyses.ask_of_ctx ctx) ctx.global st f args in
26522652
[st]
26532653

2654-
let threadspawn ctx (lval: lval option) (f: varinfo) (args: exp list) fctx: D.t =
2654+
let threadspawn ctx ~multiple (lval: lval option) (f: varinfo) (args: exp list) fctx: D.t =
26552655
begin match lval with
26562656
| Some lval ->
26572657
begin match ThreadId.get_current (Analyses.ask_of_ctx fctx) with

src/analyses/basePriv.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ end
893893
module MinePrivBase =
894894
struct
895895
include NoFinalize
896-
include ConfCheck.RequireMutexPathSensInit
896+
include ConfCheck.RequireMutexPathSensOneMainInit
897897
include MutexGlobals (* explicit not needed here because G is Prod anyway? *)
898898

899899
let thread_join ?(force=false) ask get e st = st

src/analyses/commonPriv.ml

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ struct
1919
if not mutex_active then failwith "Privatization (to be useful) requires the 'mutex' analysis to be enabled (it is currently disabled)"
2020
end
2121

22-
module RequireMutexPathSensInit =
22+
module RequireMutexPathSensOneMainInit =
2323
struct
2424
let init () =
2525
RequireMutexActivatedInit.init ();
2626
let mutex_path_sens = List.mem "mutex" (GobConfig.get_string_list "ana.path_sens") in
2727
if not mutex_path_sens then failwith "The activated privatization requires the 'mutex' analysis to be enabled & path sensitive (it is currently enabled, but not path sensitive)";
28+
let mainfuns = List.length @@ GobConfig.get_list "mainfun" in
29+
if not (mainfuns = 1) then failwith "The activated privatization requires exactly one main function to be specified";
2830
()
2931
end
3032

src/analyses/condVars.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ struct
155155
ctx.local
156156

157157
let startstate v = D.bot ()
158-
let threadenter ctx lval f args = [D.bot ()]
159-
let threadspawn ctx lval f args fctx = ctx.local
158+
let threadenter ctx ~multiple lval f args = [D.bot ()]
159+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
160160
let exitstate v = D.bot ()
161161
end
162162

src/analyses/expsplit.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ struct
8484
in
8585
emit_splits ctx d
8686

87-
let threadenter ctx lval f args = [ctx.local]
87+
let threadenter ctx ~multiple lval f args = [ctx.local]
8888

89-
let threadspawn ctx lval f args fctx =
89+
let threadspawn ctx ~multiple lval f args fctx =
9090
emit_splits_ctx ctx
9191

9292
let event ctx (event: Events.t) octx =

src/analyses/extractPthread.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,7 @@ module Spec : Analyses.MCPSpec = struct
12381238
(Ctx.top ())
12391239

12401240

1241-
let threadenter ctx lval f args =
1241+
let threadenter ctx ~multiple lval f args =
12421242
let d : D.t = ctx.local in
12431243
let tasks = ctx.global tasks_var in
12441244
(* TODO: optimize finding *)
@@ -1254,7 +1254,7 @@ module Spec : Analyses.MCPSpec = struct
12541254
[ { f_d with pred = d.pred } ]
12551255

12561256

1257-
let threadspawn ctx lval f args fctx = ctx.local
1257+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
12581258

12591259
let exitstate v = D.top ()
12601260

src/analyses/fileUse.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,8 @@ struct
287287
| _ -> m
288288

289289
let startstate v = D.bot ()
290-
let threadenter ctx lval f args = [D.bot ()]
291-
let threadspawn ctx lval f args fctx = ctx.local
290+
let threadenter ctx ~multiple lval f args = [D.bot ()]
291+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
292292
let exitstate v = D.bot ()
293293
end
294294

src/analyses/locksetAnalysis.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct
1818
module C = D
1919

2020
let startstate v = D.empty ()
21-
let threadenter ctx lval f args = [D.empty ()]
21+
let threadenter ctx ~multiple lval f args = [D.empty ()]
2222
let exitstate v = D.empty ()
2323
end
2424

src/analyses/mCP.ml

+8-8
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ struct
140140
f ((k,v::a')::a) b
141141
in f [] xs
142142

143-
let do_spawns ctx (xs:(varinfo * (lval option * exp list)) list) =
143+
let do_spawns ctx (xs:(varinfo * (lval option * exp list * bool)) list) =
144144
let spawn_one v d =
145-
List.iter (fun (lval, args) -> ctx.spawn lval v args) d
145+
List.iter (fun (lval, args, multiple) -> ctx.spawn ~multiple lval v args) d
146146
in
147147
if get_bool "exp.single-threaded" then
148148
M.msg_final Error ~category:Unsound "Thread not spawned"
@@ -324,8 +324,8 @@ struct
324324

325325
and outer_ctx tfname ?spawns ?sides ?emits ctx =
326326
let spawn = match spawns with
327-
| Some spawns -> (fun l v a -> spawns := (v,(l,a)) :: !spawns)
328-
| None -> (fun v d -> failwith ("Cannot \"spawn\" in " ^ tfname ^ " context."))
327+
| Some spawns -> (fun ?(multiple=false) l v a -> spawns := (v,(l,a,multiple)) :: !spawns)
328+
| None -> (fun ?(multiple=false) v d -> failwith ("Cannot \"spawn\" in " ^ tfname ^ " context."))
329329
in
330330
let sideg = match sides with
331331
| Some sides -> (fun v g -> sides := (v, (!WideningTokens.side_tokens, g)) :: !sides)
@@ -567,28 +567,28 @@ struct
567567
let d = do_emits ctx !emits d q in
568568
if q then raise Deadcode else d
569569

570-
let threadenter (ctx:(D.t, G.t, C.t, V.t) ctx) lval f a =
570+
let threadenter (ctx:(D.t, G.t, C.t, V.t) ctx) ~multiple lval f a =
571571
let sides = ref [] in
572572
let emits = ref [] in
573573
let ctx'' = outer_ctx "threadenter" ~sides ~emits ctx in
574574
let f (n,(module S:MCPSpec),d) =
575575
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "threadenter" ctx'' n d in
576-
map (fun d -> (n, repr d)) @@ S.threadenter ctx' lval f a
576+
map (fun d -> (n, repr d)) @@ (S.threadenter ~multiple) ctx' lval f a
577577
in
578578
let css = map f @@ spec_list ctx.local in
579579
do_sideg ctx !sides;
580580
(* TODO: this do_emits is now different from everything else *)
581581
map (fun d -> do_emits ctx !emits d false) @@ map topo_sort_an @@ n_cartesian_product css
582582

583-
let threadspawn (ctx:(D.t, G.t, C.t, V.t) ctx) lval f a fctx =
583+
let threadspawn (ctx:(D.t, G.t, C.t, V.t) ctx) ~multiple lval f a fctx =
584584
let sides = ref [] in
585585
let emits = ref [] in
586586
let ctx'' = outer_ctx "threadspawn" ~sides ~emits ctx in
587587
let fctx'' = outer_ctx "threadspawn" ~sides ~emits fctx in
588588
let f post_all (n,(module S:MCPSpec),(d,fd)) =
589589
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "threadspawn" ~post_all ctx'' n d in
590590
let fctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "threadspawn" ~post_all fctx'' n fd in
591-
n, repr @@ S.threadspawn ctx' lval f a fctx'
591+
n, repr @@ S.threadspawn ~multiple ctx' lval f a fctx'
592592
in
593593
let d, q = map_deadcode f @@ spec_list2 ctx.local fctx.local in
594594
do_sideg ctx !sides;

src/analyses/mallocFresh.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ struct
5252
| None -> ctx.local
5353
| Some lval -> assign_lval (Analyses.ask_of_ctx ctx) lval ctx.local
5454

55-
let threadenter ctx lval f args =
55+
let threadenter ctx ~multiple lval f args =
5656
[D.empty ()]
5757

58-
let threadspawn ctx lval f args fctx =
58+
let threadspawn ctx ~multiple lval f args fctx =
5959
D.empty ()
6060

6161
module A =

src/analyses/malloc_null.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ struct
215215
let name () = "malloc_null"
216216

217217
let startstate v = D.empty ()
218-
let threadenter ctx lval f args = [D.empty ()]
219-
let threadspawn ctx lval f args fctx = ctx.local
218+
let threadenter ctx ~multiple lval f args = [D.empty ()]
219+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
220220
let exitstate v = D.empty ()
221221

222222
let init marshal =

src/analyses/modifiedSinceLongjmp.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct
5757
ctx.local
5858

5959
let startstate v = D.bot ()
60-
let threadenter ctx lval f args = [D.bot ()]
60+
let threadenter ctx ~multiple lval f args = [D.bot ()]
6161
let exitstate v = D.top ()
6262

6363
let query ctx (type a) (q: a Queries.t): a Queries.result =

src/analyses/mutexTypeAnalysis.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ struct
6565
| _ -> ctx.local
6666

6767
let startstate v = D.bot ()
68-
let threadenter ctx lval f args = [D.top ()]
69-
let threadspawn ctx lval f args fctx = ctx.local
68+
let threadenter ctx ~multiple lval f args = [D.top ()]
69+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
7070
let exitstate v = D.top ()
7171

7272
let query ctx (type a) (q: a Queries.t): a Queries.result =

src/analyses/poisonVariables.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct
6565
VS.join au ctx.local
6666

6767
let startstate v = D.bot ()
68-
let threadenter ctx lval f args = [D.bot ()]
68+
let threadenter ctx ~multiple lval f args = [D.bot ()]
6969
let exitstate v = D.top ()
7070

7171
let event ctx e octx =

src/analyses/pthreadSignals.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct
7373
| _ -> ctx.local
7474

7575
let startstate v = Signals.empty ()
76-
let threadenter ctx lval f args = [ctx.local]
76+
let threadenter ctx ~multiple lval f args = [ctx.local]
7777
let exitstate v = Signals.empty ()
7878
end
7979

src/analyses/region.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ struct
175175
let startstate v =
176176
`Lifted (RegMap.bot ())
177177

178-
let threadenter ctx lval f args =
178+
let threadenter ctx ~multiple lval f args =
179179
[`Lifted (RegMap.bot ())]
180-
let threadspawn ctx lval f args fctx = ctx.local
180+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
181181

182182
let exitstate v = `Lifted (RegMap.bot ())
183183

src/analyses/spec.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@ struct
487487

488488

489489
let startstate v = D.bot ()
490-
let threadenter ctx lval f args = [D.bot ()]
491-
let threadspawn ctx lval f args fctx = ctx.local
490+
let threadenter ctx ~multiple lval f args = [D.bot ()]
491+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
492492
let exitstate v = D.bot ()
493493
end
494494

src/analyses/stackTrace.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct
2121
ctx.local (* keep local as opposed to IdentitySpec *)
2222

2323
let startstate v = D.bot ()
24-
let threadenter ctx lval f args = [D.bot ()]
24+
let threadenter ctx ~multiple lval f args = [D.bot ()]
2525
let exitstate v = D.top ()
2626
end
2727

@@ -45,7 +45,7 @@ struct
4545
let startstate v = D.bot ()
4646
let exitstate v = D.top ()
4747

48-
let threadenter ctx lval f args =
48+
let threadenter ctx ~multiple lval f args =
4949
[D.push !Tracing.current_loc ctx.local]
5050
end
5151

src/analyses/symbLocks.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ struct
2929
let name () = "symb_locks"
3030

3131
let startstate v = D.top ()
32-
let threadenter ctx lval f args = [D.top ()]
33-
let threadspawn ctx lval f args fctx = ctx.local
32+
let threadenter ctx ~multiple lval f args = [D.top ()]
33+
let threadspawn ctx ~multiple lval f args fctx = ctx.local
3434
let exitstate v = D.top ()
3535

3636
let branch ctx exp tv = ctx.local

src/analyses/taintPartialContexts.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ struct
8888
d
8989

9090
let startstate v = D.bot ()
91-
let threadenter ctx lval f args =
91+
let threadenter ctx ~multiple lval f args =
9292
[D.bot ()]
93-
let threadspawn ctx lval f args fctx =
93+
let threadspawn ctx ~multiple lval f args fctx =
9494
match lval with
9595
| Some lv -> taint_lval ctx lv
9696
| None -> ctx.local

0 commit comments

Comments
 (0)