123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #include "sanitizers.h"
- #include "thread.h"
- #if defined(_asan_enabled_)
- extern "C" {
- void __sanitizer_start_switch_fiber(void** fake_stack_save, const void* bottom, size_t size);
- void __sanitizer_finish_switch_fiber(void* fake_stack_save, const void** old_bottom, size_t* old_size);
- }
- #endif
- #if defined(_tsan_enabled_)
- #if defined(__clang_major__) && (__clang_major__ >= 9)
- extern "C" {
- void* __tsan_get_current_fiber(void);
- void* __tsan_create_fiber(unsigned flags);
- void __tsan_destroy_fiber(void* fiber);
- void __tsan_switch_to_fiber(void* fiber, unsigned flags);
- void __tsan_set_fiber_name(void* fiber, const char* name);
- }
- #else
- namespace {
- void* __tsan_get_current_fiber(void) {
- return nullptr;
- }
- void* __tsan_create_fiber(unsigned) {
- return nullptr;
- }
- void __tsan_destroy_fiber(void*) {
- }
- void __tsan_switch_to_fiber(void*, unsigned) {
- }
- void __tsan_set_fiber_name(void*, const char*) {
- }
- }
- #endif
- #endif
- using namespace NSan;
- TFiberContext::TFiberContext() noexcept
- : Token_(nullptr)
- , IsMainFiber_(true)
- #if defined(_tsan_enabled_)
- , CurrentTSanFiberContext_(__tsan_get_current_fiber())
- #endif
- {
- TCurrentThreadLimits sl;
- Stack_ = sl.StackBegin;
- Len_ = sl.StackLength;
- #if defined(_tsan_enabled_)
- static constexpr char MainFiberName[] = "main_fiber";
- __tsan_set_fiber_name(CurrentTSanFiberContext_, MainFiberName);
- #endif
- }
- TFiberContext::TFiberContext(const void* stack, size_t len, const char* contName) noexcept
- : Token_(nullptr)
- , Stack_(stack)
- , Len_(len)
- , IsMainFiber_(false)
- #if defined(_tsan_enabled_)
- , CurrentTSanFiberContext_(__tsan_create_fiber(/*flags =*/0))
- #endif
- {
- (void)contName;
- #if defined(_tsan_enabled_)
- __tsan_set_fiber_name(CurrentTSanFiberContext_, contName);
- #endif
- }
- TFiberContext::~TFiberContext() noexcept {
- if (!IsMainFiber_) {
- #if defined(_asan_enabled_)
- if (Token_) {
- // destroy saved FakeStack
- void* activeFakeStack = nullptr;
- const void* activeStack = nullptr;
- size_t activeStackSize = 0;
- __sanitizer_start_switch_fiber(&activeFakeStack, (char*)Stack_, Len_);
- __sanitizer_finish_switch_fiber(Token_, &activeStack, &activeStackSize);
- __sanitizer_start_switch_fiber(nullptr, activeStack, activeStackSize);
- __sanitizer_finish_switch_fiber(activeFakeStack, nullptr, nullptr);
- }
- #endif
- #if defined(_tsan_enabled_)
- __tsan_destroy_fiber(CurrentTSanFiberContext_);
- #endif
- }
- }
- void TFiberContext::BeforeFinish() noexcept {
- #if defined(_asan_enabled_)
- __sanitizer_start_switch_fiber(nullptr, nullptr, 0);
- #else
- (void)Token_;
- (void)Stack_;
- (void)Len_;
- #endif
- }
- void TFiberContext::BeforeSwitch(TFiberContext* old) noexcept {
- #if defined(_asan_enabled_)
- __sanitizer_start_switch_fiber(old ? &old->Token_ : nullptr, (char*)Stack_, Len_);
- #else
- (void)old;
- #endif
- #if defined(_tsan_enabled_)
- __tsan_switch_to_fiber(CurrentTSanFiberContext_, /*flags =*/0);
- #endif
- }
- void TFiberContext::AfterSwitch() noexcept {
- #if defined(_asan_enabled_)
- __sanitizer_finish_switch_fiber(Token_, nullptr, nullptr);
- #endif
- }
- void TFiberContext::AfterStart() noexcept {
- #if defined(_asan_enabled_)
- __sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr);
- #endif
- }
- #if defined(_tsan_enabled_)
- extern "C" {
- // This function should not be directly exposed in headers
- // due to signature variations among contrib headers.
- void AnnotateBenignRaceSized(const char* file, int line,
- const volatile void* address,
- size_t size,
- const char* description);
- }
- void NSan::AnnotateBenignRaceSized(const char* file, int line,
- const volatile void* address,
- size_t size,
- const char* description) noexcept {
- ::AnnotateBenignRaceSized(file, line, address, size, description);
- }
- #endif
|