72 lines · cpp
1// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s2// REQUIRES: linux3#include "test.h"4 5#include <pthread.h>6#include <sys/types.h>7#include <unistd.h>8 9long count_memory_mappings() {10 pid_t my_pid = getpid();11 char proc_file_name[128];12 snprintf(proc_file_name, sizeof(proc_file_name), "/proc/%d/maps", my_pid);13 14 FILE *proc_file = fopen(proc_file_name, "r");15 long line_count = 0;16 int c;17 do {18 c = fgetc(proc_file);19 if (c == '\n') {20 line_count++;21 }22 } while (c != EOF);23 fclose(proc_file);24 25 return line_count;26}27 28void fiber_iteration() {29 void *orig_fiber = __tsan_get_current_fiber();30 void *fiber = __tsan_create_fiber(0);31 32 pthread_mutex_t mutex;33 pthread_mutex_init(&mutex, NULL);34 35 // Running some code on the fiber that triggers handling of pending signals.36 __tsan_switch_to_fiber(fiber, 0);37 pthread_mutex_lock(&mutex);38 pthread_mutex_unlock(&mutex);39 __tsan_switch_to_fiber(orig_fiber, 0);40 41 // We expect the fiber to clean up all resources (here the sigcontext) when destroyed.42 __tsan_destroy_fiber(fiber);43}44 45// Magic-Number for some warmup iterations,46// as tsan maps some memory for the first runs.47const size_t num_warmup = 100;48 49int main() {50 for (size_t i = 0; i < num_warmup; i++) {51 fiber_iteration();52 }53 54 long memory_mappings_before = count_memory_mappings();55 fiber_iteration();56 fiber_iteration();57 long memory_mappings_after = count_memory_mappings();58 59 // Is there a better way to detect a resource leak in the60 // ThreadState object? (i.e. a mmap not being freed)61 if (memory_mappings_before == memory_mappings_after) {62 fprintf(stderr, "PASS\n");63 } else {64 fprintf(stderr, "FAILED\n");65 }66 67 return 0;68}69 70// CHECK-NOT: WARNING: ThreadSanitizer:71// CHECK: PASS72