1c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev// Test that dynamically allocated thread-specific storage is included in the root set. 2b3b46dad13a2111a51fb1a67f36c8b633410e9b7Sergey Matveev// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0" 3c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev// RUN: %clangxx_lsan %s -o %t 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=0" not %run %t 2>&1 | FileCheck %s 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_tls=1" %run %t 2>&1 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: LSAN_OPTIONS="" %run %t 2>&1 7c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev 8c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev#include <assert.h> 9c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev#include <pthread.h> 10c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev#include <stdio.h> 11c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev#include <stdlib.h> 12c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev 13c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev// From glibc: this many keys are stored in the thread descriptor directly. 14c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveevconst unsigned PTHREAD_KEY_2NDLEVEL_SIZE = 32; 15c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev 16c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveevint main() { 17c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev static const unsigned kDummyKeysCount = PTHREAD_KEY_2NDLEVEL_SIZE; 18c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev int res; 19c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev pthread_key_t dummy_keys[kDummyKeysCount]; 20c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev for (unsigned i = 0; i < kDummyKeysCount; i++) { 21c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev res = pthread_key_create(&dummy_keys[i], NULL); 22c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev assert(res == 0); 23c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev } 24c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev pthread_key_t key; 25c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev res = pthread_key_create(&key, NULL); 26c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev assert(key >= PTHREAD_KEY_2NDLEVEL_SIZE); 27c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev assert(res == 0); 28c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev void *p = malloc(1337); 29c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev res = pthread_setspecific(key, p); 30c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev assert(res == 0); 31c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev fprintf(stderr, "Test alloc: %p.\n", p); 32c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev return 0; 33c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev} 34c91a93897a14fcd68bdd835ad6c6a4d12d2f78e6Sergey Matveev// CHECK: Test alloc: [[ADDR:.*]]. 35c085fe807836b566b4fce7ccdfb307bb025693c5Sergey Matveev// CHECK: LeakSanitizer: detected memory leaks 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// CHECK: [[ADDR]] (1337 bytes) 372fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 38