11#pragma once
22#include < boost/context/stack_context.hpp>
3+ #include < base/sanitizer_defs.h>
4+ #include < cstddef>
5+
6+ #if __has_include(<sanitizer/asan_interface.h>) && defined(ADDRESS_SANITIZER)
7+ # include < sanitizer/asan_interface.h>
8+ #endif
39
410// / This is an implementation of allocator for fiber stack.
511// / The reference implementation is protected_fixedsize_stack from boost::context.
@@ -16,10 +22,31 @@ class FiberStack
1622
1723 explicit FiberStack (size_t stack_size_ = default_stack_size);
1824
19- boost::context::stack_context allocate () const ;
25+ boost::context::stack_context allocate ();
2026 void deallocate (boost::context::stack_context & sctx) const ;
2127
28+ // / Unpoison the fiber stack memory for ASan.
29+ // /
30+ // / ASan's use-after-scope detection poisons stack memory when local variables
31+ // / go out of scope. On fiber stacks, this poisoning persists across context
32+ // / switches (yield/resume), causing false positives when the same stack addresses
33+ // / are reused by new frames in subsequent fiber resumes.
34+ // /
35+ // / This must be called before each fiber resume to clear stale scope poisoning.
36+ // / See https://github.com/google/sanitizers/issues/189
37+ void beforeResume () const
38+ {
39+ #if defined(ADDRESS_SANITIZER)
40+ if (stack_base)
41+ ASAN_UNPOISON_MEMORY_REGION (stack_base, stack_allocation_size);
42+ #endif
43+ }
44+
2245private:
2346 const size_t stack_size;
2447 const size_t page_size;
48+
49+ // / Tracked allocation for ASan unpoisoning.
50+ void * stack_base = nullptr ;
51+ size_t stack_allocation_size = 0 ;
2552};
0 commit comments