53 lines · c
1// Test that dylibs interposing write, and then calling functions intercepted2// by TSan don't deadlock (self-lock)3 4// RUN: %clang_tsan %s -o %t5// RUN: %clang_tsan %s -o %t.dylib -fno-sanitize=thread -dynamiclib -DSHARED_LIB6 7// Note that running the below command with out `lock_during_write` should8// deadlock (self-lock)9// RUN: env DYLD_INSERT_LIBRARIES=%t.dylib TSAN_OPTIONS=verbosity=2:lock_during_write=disable_for_current_process %run %t 2>&1 | FileCheck %s10//11// UNSUPPORTED: ios12 13#include <stdio.h>14 15#if defined(SHARED_LIB)16 17// dylib implementation - interposes write() calls18# include <os/lock.h>19# include <unistd.h>20 21struct interpose_substitution {22 const void *replacement;23 const void *original;24};25 26# define INTERPOSE(replacement, original) \27 __attribute__((used)) static const struct interpose_substitution \28 substitution_##original[] \29 __attribute__((section("__DATA, __interpose"))) = { \30 {(const void *)(replacement), (const void *)(original)}}31 32static ssize_t my_write(int fd, const void *buf, size_t count) {33 struct os_unfair_lock_s lock = OS_UNFAIR_LOCK_INIT;34 os_unfair_lock_lock(&lock);35 printf("Interposed write called: fd=%d, count=%zu\n", fd, count);36 ssize_t res = write(fd, buf, count);37 os_unfair_lock_unlock(&lock);38 return res;39}40INTERPOSE(my_write, write);41 42#else // defined(SHARED_LIB)43 44int main() {45 printf("Write test completed\n");46 return 0;47}48 49#endif // defined(SHARED_LIB)50 51// CHECK: Interposed write called: fd={{[0-9]+}}, count={{[0-9]+}}52// CHECK: Write test completed53