Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
52de056
Simplify Lockset
michael-schwarz Sep 22, 2022
dde2b1a
Steps
michael-schwarz Sep 22, 2022
c982337
Add case where no warning should be issued
michael-schwarz Sep 22, 2022
37155af
More tests
michael-schwarz Sep 22, 2022
24c7563
Rm spurious code
michael-schwarz Sep 22, 2022
06f98a9
Adapt comments
michael-schwarz Sep 22, 2022
28dc103
Cleanup test
michael-schwarz Sep 22, 2022
575cb54
Add warning if MayLockset is not empty
michael-schwarz Sep 22, 2022
430c376
Account for returning from thread via pthread_exit
michael-schwarz Sep 22, 2022
f471f47
Add warning when unlocking mutex that may not held
michael-schwarz Sep 22, 2022
014481e
Rudimentary, flow-insensitive analysis of mutex types
michael-schwarz Sep 25, 2022
8ccfb9e
Fix indentation
michael-schwarz Sep 25, 2022
15131fe
Add test for recurisve mutexes
michael-schwarz Sep 25, 2022
1c17d61
Track value of mutexAttrT locally
michael-schwarz Sep 25, 2022
5f32337
Add mutex type tracking for local mutexes
michael-schwarz Sep 25, 2022
6236e48
Skip 60/05 on OS X
michael-schwarz Sep 25, 2022
e8b09f1
Category for Double Locking
michael-schwarz Sep 25, 2022
95f249a
OS X :(
michael-schwarz Sep 25, 2022
afd4153
Merge branch 'master' into issue_718
michael-schwarz Oct 24, 2022
32257f8
Merge branch 'master' into issue_718
michael-schwarz Nov 27, 2022
8dc1e84
Merge branch 'master' into issue_718
michael-schwarz Jan 5, 2023
ee4b452
Merge branch 'master' into issue_718
michael-schwarz Mar 21, 2023
53112a0
Dynamically lookup constants
michael-schwarz Mar 27, 2023
99f4261
Cleanup
michael-schwarz Mar 27, 2023
792e4ec
Make conditions more clear
michael-schwarz Mar 27, 2023
208fcf1
Slim down tests by removing unused code
michael-schwarz Mar 27, 2023
bab294b
Only trace if tracing is enabled
michael-schwarz Mar 27, 2023
e8d0219
Finally fix it for OS X
michael-schwarz Mar 28, 2023
7e91913
Merge branch 'master' into issue_718
michael-schwarz Mar 28, 2023
5d82c5c
Fix compilation warnings for test cases with GCC.
jerhard Mar 31, 2023
ca53009
Merge branch 'master' into issue_718
michael-schwarz May 24, 2023
01fb38a
Warning for unlocking definitely not-held mutex
michael-schwarz May 24, 2023
282b671
Add comments about other types of mutexes
michael-schwarz May 24, 2023
97713d3
Add further dynamic mutex
michael-schwarz May 24, 2023
3a813de
Change queries, fix unlock for recursive mutexes
michael-schwarz May 24, 2023
b548422
Adapt tests to correct maylockset
michael-schwarz May 24, 2023
cc95869
Fix test 09
michael-schwarz May 24, 2023
283ec75
Merge branch 'master' into issue_718
michael-schwarz May 24, 2023
3d064ce
Make example smaller
michael-schwarz May 24, 2023
e7e15fa
Fix whitespace
michael-schwarz May 25, 2023
550c4f3
Style improvement
michael-schwarz May 25, 2023
f90bbd7
Indentation
michael-schwarz May 25, 2023
aa29d4c
Indentation
michael-schwarz May 25, 2023
1b0ffc4
Fix annotation
michael-schwarz May 25, 2023
9f99115
Comments on why 71/07 contains no assertions.
michael-schwarz May 25, 2023
52c701f
Fix test 71/08 on OS X which doesn't define some constants
michael-schwarz May 25, 2023
fec7dd3
71/07: Do not include pthread.h so OS X tests can have asserts
michael-schwarz May 25, 2023
5758ff7
Ensure `MutexAttr` survives joins
michael-schwarz May 25, 2023
fe5c49f
Support for Lvals
michael-schwarz May 25, 2023
eeb11fa
Support mutexes in structs also for assignments
michael-schwarz May 25, 2023
be5432c
Add comment
michael-schwarz May 25, 2023
fbc3df4
Cleanup
michael-schwarz May 25, 2023
e5c290a
Merge branch 'master' into issue_718
michael-schwarz May 25, 2023
f2fe2bc
derive compare for MutexType
michael-schwarz May 26, 2023
48f154a
Use bespoke V, reduce boilerplate
michael-schwarz May 26, 2023
655c1be
Simplify
michael-schwarz May 26, 2023
01b9841
Attempt at reuse
michael-schwarz May 26, 2023
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
12 changes: 6 additions & 6 deletions src/analyses/mayLocks.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ struct
M.warn ~category:M.Category.Behavior.Undefined.double_locking "Acquiring a (possibly non-recursive) mutex that may be already held";
ctx.local
in
match D.Addr.to_var_must l with
| Some v ->
(let mtype = ctx.ask (Queries.MutexType v) in
match D.Addr.to_var_offset l with
| Some (v,o) ->
(let mtype = ctx.ask (Queries.MutexType (v, MutexTypeAnalysis.offs_no_index o)) in
match mtype with
| `Lifted MutexAttrDomain.MutexKind.Recursive -> ctx.local
| `Lifted MutexAttrDomain.MutexKind.NonRec ->
Expand All @@ -30,9 +30,9 @@ struct

let remove ctx l =
if not (D.mem l ctx.local) then M.warn "Releasing a mutex that is definitely not held";
match D.Addr.to_var_must l with
| Some v ->
(let mtype = ctx.ask (Queries.MutexType v) in
match D.Addr.to_var_offset l with
| Some (v,o) ->
(let mtype = ctx.ask (Queries.MutexType (v, MutexTypeAnalysis.offs_no_index o)) in
match mtype with
| `Lifted MutexAttrDomain.MutexKind.NonRec -> D.remove l ctx.local
| _ -> ctx.local (* we cannot remove them here *))
Expand Down
20 changes: 16 additions & 4 deletions src/analyses/mutexTypeAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ open Analyses
module MAttr = ValueDomain.MutexAttr
module LF = LibraryFunctions

(* Removing indexes here avoids complicated lookups inside the map for a varinfo, at the price that different types of mutexes in arrays are not dinstinguished *)
let rec offs_no_index o =
match o with
| `NoOffset -> `NoOffset
| `Field (f,o) -> `Field (f, offs_no_index o)
| `Index (i,o) -> `Index (Lval.any_index_exp, offs_no_index o)

module Spec : Analyses.MCPSpec with module D = Lattice.Unit and module C = Lattice.Unit =
struct
include Analyses.DefaultSpec
Expand All @@ -14,7 +21,8 @@ struct
let name () = "pthreadMutexType"
module D = Lattice.Unit
module C = Lattice.Unit
module G = MAttr

module G = MapDomain.MapBot_LiftTop (Lval.CilLval) (MAttr)

(* transfer functions *)
let assign ctx (lval:lval) (rval:exp) : D.t =
Expand All @@ -25,7 +33,8 @@ struct
| Const (CInt (c, _, _)) -> MAttr.of_int c
| _ -> `Top)
in
ctx.sideg v kind;
let r = G.singleton ((v,`NoOffset)) kind in
ctx.sideg v r;
ctx.local
| _ -> ctx.local

Expand Down Expand Up @@ -53,7 +62,10 @@ struct
| MutexInit {mutex = mutex; attr = attr} ->
let mutexes = ctx.ask (Queries.MayPointTo mutex) in
let attr = ctx.ask (Queries.EvalMutexAttr attr) in
Queries.LS.iter (function (v, _) -> ctx.sideg v attr) mutexes;
(* It is correct to iter over these sets here, as mutexes need to be intialized before being used, and an analysis that detects usage before initialization is a different analysis. *)
Queries.LS.iter (function (v, o) ->
let r = G.singleton (v, offs_no_index o) attr in
ctx.sideg v r) mutexes;
ctx.local
| _ -> ctx.local

Expand All @@ -64,7 +76,7 @@ struct

let query ctx (type a) (q: a Queries.t): a Queries.result =
match q with
| Queries.MutexType v -> (ctx.global v:MutexAttrDomain.t)
| Queries.MutexType ((v,o):Lval.CilLval.t) -> let r = ctx.global v in (G.find (v,o) r:MutexAttrDomain.t)
| _ -> Queries.Result.top q
end

Expand Down
6 changes: 3 additions & 3 deletions src/domains/queries.ml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ type _ t =
| HeapVar: VI.t t
| IsHeapVar: varinfo -> MayBool.t t (* TODO: is may or must? *)
| IsMultiple: varinfo -> MustBool.t t (* Is no other copy of this local variable reachable via pointers? *)
| MutexType: varinfo -> MutexAttrDomain.t t
| MutexType: Lval.CilLval.t -> MutexAttrDomain.t t
| EvalThread: exp -> ConcDomain.ThreadSet.t t
| EvalMutexAttr: exp -> MutexAttrDomain.t t
| EvalJumpBuf: exp -> JmpBufDomain.JmpBufSet.t t
Expand Down Expand Up @@ -321,7 +321,7 @@ struct
| Any (Invariant i1), Any (Invariant i2) -> compare_invariant_context i1 i2
| Any (InvariantGlobal vi1), Any (InvariantGlobal vi2) -> Stdlib.compare (Hashtbl.hash vi1) (Hashtbl.hash vi2)
| Any (IterSysVars (vq1, vf1)), Any (IterSysVars (vq2, vf2)) -> VarQuery.compare vq1 vq2 (* not comparing fs *)
| Any (MutexType v1), Any (MutexType v2) -> CilType.Varinfo.compare v1 v2
| Any (MutexType v1), Any (MutexType v2) -> Lval.CilLval.compare v1 v2
| Any (MustProtectedVars m1), Any (MustProtectedVars m2) -> compare_mustprotectedvars m1 m2
| Any (MayBeModifiedSinceSetjmp e1), Any (MayBeModifiedSinceSetjmp e2) -> JmpBufDomain.BufferEntry.compare e1 e2
| Any (MustBeSingleThreaded {since_start=s1;}), Any (MustBeSingleThreaded {since_start=s2;}) -> Stdlib.compare s1 s2
Expand Down Expand Up @@ -358,7 +358,7 @@ struct
| Any (EvalJumpBuf e) -> CilType.Exp.hash e
| Any (WarnGlobal vi) -> Hashtbl.hash vi
| Any (Invariant i) -> hash_invariant_context i
| Any (MutexType v) -> CilType.Varinfo.hash v
| Any (MutexType v) -> Lval.CilLval.hash v
| Any (InvariantGlobal vi) -> Hashtbl.hash vi
| Any (MustProtectedVars m) -> hash_mustprotectedvars m
| Any (MayBeModifiedSinceSetjmp e) -> JmpBufDomain.BufferEntry.hash e
Expand Down
56 changes: 56 additions & 0 deletions tests/regression/71-doublelocking/12-rec-dyn-struct.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// PARAM: --set ana.activated[+] 'maylocks' --set ana.activated[+] 'pthreadMutexType'
// Like 06, but tests mutexattr survives joins
#define _GNU_SOURCE
#include<pthread.h>
#include<stdio.h>
#include<unistd.h>
#include <assert.h>

int g;
struct s {
pthread_mutex_t mut;
};

typedef struct s s_t;


void* f1(void* ptr) {
pthread_mutex_t* mut = &(((s_t*) ptr)->mut);

pthread_mutex_lock(mut); //NOWARN
pthread_mutex_lock(mut); //NOWARN
pthread_mutex_unlock(mut);
pthread_mutex_unlock(mut);
return NULL;
}


int main(int argc, char const *argv[])
{
pthread_t t1;
s_t mut_str;

pthread_mutexattr_t attr;

if(argc == 2) {
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
} else {
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
}

pthread_mutex_init(&mut_str.mut, &attr);


pthread_create(&t1,NULL,f1,&mut_str);


pthread_mutex_lock(&mut_str.mut); //NOWARN
pthread_mutex_lock(&mut_str.mut); //NOWARN
pthread_mutex_unlock(&mut_str.mut);
pthread_mutex_unlock(&mut_str.mut);

pthread_join(t1, NULL);


return 0;
}