1 | /* RUN: %clang_msan -g %s -o %t |
2 | RUN: %clang_msan -g %s -DBUILD_SO -fPIC -o %t-so.so -shared |
3 | RUN: %run %t 2>&1 |
4 | |
5 | Regression test for a bug in msan/glibc integration, |
6 | see https://sourceware.org/bugzilla/show_bug.cgi?id=16291 |
7 | and https://github.com/google/sanitizers/issues/547 |
8 | |
9 | XFAIL: target={{.*freebsd.*}} |
10 | UNSUPPORTED: target=powerpc{{.*}} |
11 | |
12 | // Reports use-of-uninitialized-value, not analyzed |
13 | XFAIL: target={{.*netbsd.*}} |
14 | |
15 | */ |
16 | |
17 | #ifndef BUILD_SO |
18 | #include <assert.h> |
19 | #include <dlfcn.h> |
20 | #include <stdio.h> |
21 | #include <stdlib.h> |
22 | #include <pthread.h> |
23 | |
24 | typedef long *(* get_t)(); |
25 | get_t GetTls; |
26 | void *Thread1(void *unused) { |
27 | long uninitialized; |
28 | long *x = GetTls(); |
29 | if (*x) |
30 | fprintf(stderr, format: "bar\n" ); |
31 | *x = uninitialized; |
32 | fprintf(stderr, format: "stack: %p dtls: %p\n" , &x, x); |
33 | return 0; |
34 | } |
35 | |
36 | void *Thread2(void *unused) { |
37 | long *x = GetTls(); |
38 | fprintf(stderr, format: "stack: %p dtls: %p\n" , &x, x); |
39 | if (*x) |
40 | fprintf(stderr, format: "foo\n" ); // False negative here. |
41 | return 0; |
42 | } |
43 | |
44 | int main(int argc, char *argv[]) { |
45 | char path[4096]; |
46 | snprintf(s: path, maxlen: sizeof(path), format: "%s-so.so" , argv[0]); |
47 | int i; |
48 | |
49 | void *handle = dlopen(file: path, RTLD_LAZY); |
50 | if (!handle) fprintf(stderr, format: "%s\n" , dlerror()); |
51 | assert(handle != 0); |
52 | GetTls = (get_t)dlsym(handle: handle, name: "GetTls" ); |
53 | assert(dlerror() == 0); |
54 | |
55 | pthread_t t; |
56 | pthread_create(newthread: &t, attr: 0, start_routine: Thread1, arg: 0); |
57 | pthread_join(th: t, thread_return: 0); |
58 | pthread_create(newthread: &t, attr: 0, start_routine: Thread2, arg: 0); |
59 | pthread_join(th: t, thread_return: 0); |
60 | return 0; |
61 | } |
62 | #else // BUILD_SO |
63 | __thread long huge_thread_local_array[1 << 17]; |
64 | long *GetTls() { |
65 | return &huge_thread_local_array[0]; |
66 | } |
67 | #endif |
68 | |