17c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar/* RUN: %clang_msan -g %s -o %t 27c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar RUN: %clang_msan -g %s -DBUILD_SO -fPIC -o %t-so.so -shared 36a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines RUN: %run %t 2>&1 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 56a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines Regression test for a bug in msan/glibc integration, 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines see https://sourceware.org/bugzilla/show_bug.cgi?id=16291 76a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines and https://code.google.com/p/memory-sanitizer/issues/detail?id=44 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines*/ 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef BUILD_SO 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <assert.h> 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <dlfcn.h> 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stdio.h> 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stdlib.h> 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <pthread.h> 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef long *(* get_t)(); 182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesget_t GetTls; 192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *Thread1(void *unused) { 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines long uninitialized; 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines long *x = GetTls(); 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (*x) 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "bar\n"); 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines *x = uninitialized; 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "stack: %p dtls: %p\n", &x, x); 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *Thread2(void *unused) { 302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines long *x = GetTls(); 312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "stack: %p dtls: %p\n", &x, x); 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (*x) 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "foo\n"); // False negative here. 342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint main(int argc, char *argv[]) { 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines char path[4096]; 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines snprintf(path, sizeof(path), "%s-so.so", argv[0]); 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int i; 412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *handle = dlopen(path, RTLD_LAZY); 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!handle) fprintf(stderr, "%s\n", dlerror()); 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert(handle != 0); 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GetTls = (get_t)dlsym(handle, "GetTls"); 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert(dlerror() == 0); 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_t t; 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_create(&t, 0, Thread1, 0); 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_join(t, 0); 512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_create(&t, 0, Thread2, 0); 522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_join(t, 0); 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else // BUILD_SO 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__thread long huge_thread_local_array[1 << 17]; 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hineslong *GetTls() { 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return &huge_thread_local_array[0]; 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 61