Index: lib/asan/asan_posix.cc =================================================================== --- lib/asan/asan_posix.cc +++ lib/asan/asan_posix.cc @@ -40,31 +40,60 @@ // ---------------------- TSD ---------------- {{{1 +#if !SANITIZER_FREEBSD static pthread_key_t tsd_key; +#else +struct Tsd { + void *data; + void (*destructor)(void *tsd); + Tsd() : data(nullptr), destructor(nullptr) {} + ~Tsd() { + if (destructor) + destructor(data); + } +}; + +static thread_local Tsd _tsd; +#endif static bool tsd_key_inited = false; void AsanTSDInit(void (*destructor)(void *tsd)) { CHECK(!tsd_key_inited); tsd_key_inited = true; +#if !SANITIZER_FREEBSD CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); +#else + CHECK_EQ(destructor, &PlatformTSDDtor); + _tsd.destructor = destructor; +#endif } void *AsanTSDGet() { CHECK(tsd_key_inited); +#if !SANITIZER_FREEBSD return pthread_getspecific(tsd_key); +#else + return _tsd.data; +#endif } void AsanTSDSet(void *tsd) { CHECK(tsd_key_inited); +#if !SANITIZER_FREEBSD pthread_setspecific(tsd_key, tsd); +#else + _tsd.data = tsd; +#endif } void PlatformTSDDtor(void *tsd) { +#if !SANITIZER_FREEBSD AsanThreadContext *context = (AsanThreadContext*)tsd; if (context->destructor_iterations > 1) { context->destructor_iterations--; CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); return; } +#endif AsanThread::TSDDtor(tsd); } } // namespace __asan