1e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// Regression test for thread lifetime tracking. Thread data should be
2e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// considered live during the thread's termination, at least until the
3e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// user-installed TSD destructors have finished running (since they may contain
4e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// additional cleanup tasks). LSan doesn't actually meet that goal 100%, but it
5e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// makes its best effort.
6e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0"
7e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// RUN: %clangxx_lsan %s -o %t
82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: LSAN_OPTIONS=$LSAN_BASE:use_tls=1 %run %t
92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: LSAN_OPTIONS=$LSAN_BASE:use_tls=0 not %run %t 2>&1 | FileCheck %s
10e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
11e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev#include <assert.h>
12e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev#include <pthread.h>
13e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev#include <stdio.h>
14e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev#include <stdlib.h>
15e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
16e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev#include "sanitizer/lsan_interface.h"
17e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
18e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveevpthread_key_t key;
19e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev__thread void *p;
20e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
21e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveevvoid key_destructor(void *arg) {
22e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  // Generally this may happen on a different thread.
23e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  __lsan_do_leak_check();
24e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev}
25e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
26e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveevvoid *thread_func(void *arg) {
27e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  p = malloc(1337);
28e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  fprintf(stderr, "Test alloc: %p.\n", p);
29e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  int res = pthread_setspecific(key, (void*)1);
30e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  assert(res == 0);
31e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  return 0;
32e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev}
33e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
34e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveevint main() {
35e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  int res = pthread_key_create(&key, &key_destructor);
36e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  assert(res == 0);
37e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  pthread_t thread_id;
38e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  res = pthread_create(&thread_id, 0, thread_func, 0);
39e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  assert(res == 0);
40e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  res = pthread_join(thread_id, 0);
41e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  assert(res == 0);
42e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev  return 0;
43e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev}
44e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// CHECK: Test alloc: [[ADDR:.*]].
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// CHECK: [[ADDR]] (1337 bytes)
46