1ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany// Regression test for a leak in tsd: 2ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany// https://code.google.com/p/address-sanitizer/issues/detail?id=233 35d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// RUN: %clangxx_asan -O1 %s -pthread -o %t 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: ASAN_OPTIONS=quarantine_size=1 %run %t 5ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany#include <pthread.h> 6ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany#include <stdio.h> 7ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany#include <stdlib.h> 8ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany#include <assert.h> 95d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include <sanitizer/allocator_interface.h> 10ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany 11ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryanystatic pthread_key_t tsd_key; 12ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany 13ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryanyvoid *Thread(void *) { 14ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany pthread_setspecific(tsd_key, malloc(10)); 15ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany return 0; 16ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany} 17ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany 18ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryanystatic volatile void *v; 19ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany 20ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryanyvoid Dtor(void *tsd) { 21ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany v = malloc(10000); 22ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany free(tsd); 23ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany free((void*)v); // The bug was that this was leaking. 24ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany} 25ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany 26ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryanyint main() { 27ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany assert(0 == pthread_key_create(&tsd_key, Dtor)); 28ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany size_t old_heap_size = 0; 29ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany for (int i = 0; i < 10; i++) { 30ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany pthread_t t; 31ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany pthread_create(&t, 0, Thread, 0); 32ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany pthread_join(t, 0); 335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines size_t new_heap_size = __sanitizer_get_heap_size(); 34ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany fprintf(stderr, "heap size: new: %zd old: %zd\n", new_heap_size, old_heap_size); 35ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany if (old_heap_size) 36ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany assert(old_heap_size == new_heap_size); 37ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany old_heap_size = new_heap_size; 38ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany } 39ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany} 40