Skip to content

Commit

Permalink
Merge pull request #1607 from goblint/pthread_self
Browse files Browse the repository at this point in the history
Add `pthread_self` support
  • Loading branch information
sim642 authored Oct 30, 2024
2 parents 9a8dd4e + 1bb8db1 commit a080563
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 3 deletions.
9 changes: 9 additions & 0 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2651,6 +2651,15 @@ struct
| Unknown, "__goblint_assume_join" ->
let id = List.hd args in
Priv.thread_join ~force:true (Analyses.ask_of_ctx ctx) (priv_getg ctx.global) id st
| ThreadSelf, _ ->
begin match lv, ThreadId.get_current (Analyses.ask_of_ctx ctx) with
| Some lv, `Lifted tid ->
set ~ctx st (eval_lv ~ctx st lv) (Cilfacade.typeOfLval lv) (Thread (ValueDomain.Threads.singleton tid))
| Some lv, _ ->
invalidate_ret_lv st
| None, _ ->
st
end
| Alloca size, _ -> begin
match lv with
| Some lv ->
Expand Down
4 changes: 2 additions & 2 deletions src/cdomain/value/cdomains/threadIdDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ struct
(v, None)

let is_main = function
| ({vname; _}, None) -> List.mem vname @@ GobConfig.get_string_list "mainfun"
| ({vname; _}, None) -> GobConfig.get_bool "ana.thread.include-node" && List.mem vname @@ GobConfig.get_string_list "mainfun"
| _ -> false

let is_unique _ = false (* TODO: should this consider main unique? *)
let is_unique = is_main
let may_create _ _ = true
let is_must_parent _ _ = false
end
Expand Down
1 change: 1 addition & 0 deletions src/util/library/libraryDesc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type special =
| ThreadCreate of { thread: Cil.exp; start_routine: Cil.exp; arg: Cil.exp; multiple: bool }
| ThreadJoin of { thread: Cil.exp; ret_var: Cil.exp; }
| ThreadExit of { ret_val: Cil.exp; }
| ThreadSelf
| Globalize of Cil.exp
| Signal of Cil.exp
| Broadcast of Cil.exp
Expand Down
2 changes: 1 addition & 1 deletion src/util/library/libraryFunctions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ let pthread_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[
("pthread_attr_setstacksize", unknown [drop "attr" [w]; drop "stacksize" []]);
("pthread_attr_getscope", unknown [drop "attr" [r]; drop "scope" [w]]);
("pthread_attr_setscope", unknown [drop "attr" [w]; drop "scope" []]);
("pthread_self", unknown []);
("pthread_self", special [] ThreadSelf);
("pthread_sigmask", unknown [drop "how" []; drop "set" [r]; drop "oldset" [w]]);
("pthread_setspecific", unknown ~attrs:[InvalidateGlobals] [drop "key" []; drop "value" [w_deep]]);
("pthread_getspecific", unknown ~attrs:[InvalidateGlobals] [drop "key" []]);
Expand Down
29 changes: 29 additions & 0 deletions tests/regression/51-threadjoins/09-join-main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//PARAM: --set ana.activated[+] threadJoins
#include <pthread.h>
#include <stdio.h>

pthread_t mainid;

int g = 10;

void *t_fun(void *arg) {
int r = pthread_join(mainid, NULL); // TSan doesn't like this...
printf("j: %d\n", r);
g++; // NORACE
printf("t_fun: %d\n", g);
return NULL;
}


int main(void) {
mainid = pthread_self();

pthread_t id2;
pthread_create(&id2, NULL, t_fun, NULL);

g++; // NORACE
printf("main: %d\n", g);

pthread_exit(NULL); // exit main thread but keep id2 alive, otherwise main returning kills id2
return 0;
}
29 changes: 29 additions & 0 deletions tests/regression/51-threadjoins/10-join-main-plain.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//PARAM: --set ana.activated[+] threadJoins --set ana.thread.domain plain
#include <pthread.h>
#include <stdio.h>

pthread_t mainid;

int g = 10;

void *t_fun(void *arg) {
int r = pthread_join(mainid, NULL); // TSan doesn't like this...
printf("j: %d\n", r);
g++; // RACE (imprecise by plain thread IDs)
printf("t_fun: %d\n", g);
return NULL;
}


int main(void) {
mainid = pthread_self();

pthread_t id2;
pthread_create(&id2, NULL, t_fun, NULL);

g++; // NORACE
printf("main: %d\n", g);

pthread_exit(NULL); // exit main thread but keep id2 alive, otherwise main returning kills id2
return 0;
}
29 changes: 29 additions & 0 deletions tests/regression/51-threadjoins/11-join-main-plain-no-node.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//PARAM: --set ana.activated[+] threadJoins --set ana.thread.domain plain --disable ana.thread.include-node
#include <pthread.h>
#include <stdio.h>

pthread_t mainid;

int g = 10;

void *t_fun(void *arg) {
int r = pthread_join(mainid, NULL); // TSan doesn't like this...
printf("j: %d\n", r);
g++; // RACE (imprecise by plain thread IDs)
printf("t_fun: %d\n", g);
return NULL;
}


int main(void) {
mainid = pthread_self();

pthread_t id2;
pthread_create(&id2, NULL, t_fun, NULL);

g++; // RACE (imprecise by plain thread IDs not knowing if main is actual main or spawned by program)
printf("main: %d\n", g);

pthread_exit(NULL); // exit main thread but keep id2 alive, otherwise main returning kills id2
return 0;
}

0 comments on commit a080563

Please sign in to comment.