diff options
Diffstat (limited to 'library/cpp/yt/memory')
| -rw-r--r-- | library/cpp/yt/memory/atomic_intrusive_ptr-inl.h | 1 | ||||
| -rw-r--r-- | library/cpp/yt/memory/ref.cpp | 5 | ||||
| -rw-r--r-- | library/cpp/yt/memory/ref.h | 3 | ||||
| -rw-r--r-- | library/cpp/yt/memory/ref_counted-inl.h | 4 | ||||
| -rw-r--r-- | library/cpp/yt/memory/unittests/ref_ut.cpp | 2 | ||||
| -rw-r--r-- | library/cpp/yt/memory/weak_ptr-inl.h | 22 | ||||
| -rw-r--r-- | library/cpp/yt/memory/weak_ptr.h | 2 |
7 files changed, 23 insertions, 16 deletions
diff --git a/library/cpp/yt/memory/atomic_intrusive_ptr-inl.h b/library/cpp/yt/memory/atomic_intrusive_ptr-inl.h index d91d20f2fd6..4211806880f 100644 --- a/library/cpp/yt/memory/atomic_intrusive_ptr-inl.h +++ b/library/cpp/yt/memory/atomic_intrusive_ptr-inl.h @@ -3,7 +3,6 @@ // For the sake of sane code completion. #include "atomic_intrusive_ptr.h" #endif -#undef ATOMIC_INTRUSIVE_PTR_INL_H_ #include <util/system/spinlock.h> diff --git a/library/cpp/yt/memory/ref.cpp b/library/cpp/yt/memory/ref.cpp index 8601c2ba3e1..eddae004ca6 100644 --- a/library/cpp/yt/memory/ref.cpp +++ b/library/cpp/yt/memory/ref.cpp @@ -380,11 +380,6 @@ TSharedRef TSharedRef::FromStringImpl(TString str, TRefCountedTypeCookie tagCook return TSharedRef(ref, std::move(holder)); } -TSharedRef TSharedRef::FromString(const char* str) -{ - return FromString(std::string(str)); -} - TSharedRef TSharedRef::FromBlob(TBlob&& blob) { auto ref = TRef::FromBlob(blob); diff --git a/library/cpp/yt/memory/ref.h b/library/cpp/yt/memory/ref.h index 1fc451f50aa..91bce3fde6a 100644 --- a/library/cpp/yt/memory/ref.h +++ b/library/cpp/yt/memory/ref.h @@ -162,9 +162,6 @@ public: //! Same as above but the memory tag is specified in #tagCookie. static TSharedRef FromString(std::string str, TRefCountedTypeCookie tagCookie); - //! Creates a TSharedRef from a zero-terminated C string. - static TSharedRef FromString(const char* str); - //! Creates a TSharedRef for a given blob taking ownership of its content. static TSharedRef FromBlob(TBlob&& blob); diff --git a/library/cpp/yt/memory/ref_counted-inl.h b/library/cpp/yt/memory/ref_counted-inl.h index 94acfc6669b..ce3c686ee28 100644 --- a/library/cpp/yt/memory/ref_counted-inl.h +++ b/library/cpp/yt/memory/ref_counted-inl.h @@ -124,6 +124,10 @@ Y_FORCE_INLINE void DestroyRefCountedImpl(T* obj) // No virtual call when T is final. obj->~T(); + // The ref-counter is a base subobject of *obj, so obj->~T() above poisons it + // under -fsanitize-memory-use-after-dtor. Unpoison before accessing it. + NSan::Unpoison(refCounter, sizeof(TRefCounter)); + // Fast path. Weak refs cannot appear if there are neither strong nor weak refs. if (refCounter->GetWeakRefCount() == 1) { NYT::NDetail::TMemoryReleaser<T>::Do(obj, offset); diff --git a/library/cpp/yt/memory/unittests/ref_ut.cpp b/library/cpp/yt/memory/unittests/ref_ut.cpp index 734fc030d29..175ca2bb00e 100644 --- a/library/cpp/yt/memory/unittests/ref_ut.cpp +++ b/library/cpp/yt/memory/unittests/ref_ut.cpp @@ -13,7 +13,7 @@ namespace { TEST(TSharedRefTest, Save) { - const TSharedRef expected = TSharedRef::FromString("My tests data"); + const TSharedRef expected = TSharedRef::FromString(std::string("My tests data")); TStringStream s; ::Save(&s, expected); // only Save supported for TSharedRef. You can ::Load serialized data to vector. } diff --git a/library/cpp/yt/memory/weak_ptr-inl.h b/library/cpp/yt/memory/weak_ptr-inl.h index 11026dc5fc6..0e5ad795774 100644 --- a/library/cpp/yt/memory/weak_ptr-inl.h +++ b/library/cpp/yt/memory/weak_ptr-inl.h @@ -4,6 +4,8 @@ #include "weak_ptr.h" #endif +#include <util/system/sanitizers.h> + namespace NYT { //////////////////////////////////////////////////////////////////////////////// @@ -16,8 +18,13 @@ template <class T> TWeakPtr<T>::TWeakPtr(T* p) noexcept : T_(p) { -#if defined(_tsan_enabled_) +#if defined(_tsan_enabled_) || defined(_msan_enabled_) if (T_) { + // p may legitimately point to an object whose destructor has already run + // while its ref-counter is still alive (weak count > 0). When T derives + // from TRefCounted virtually, the upcast below reads p's vptr, poisoned + // by -fsanitize-memory-use-after-dtor. Unpoison it (no-op for a live object). + NSan::Unpoison(T_, sizeof(void*)); RefCounter_ = GetRefCounter(T_); } #endif @@ -42,7 +49,7 @@ TWeakPtr<T>::TWeakPtr(const TIntrusivePtr<U>& ptr) noexcept template <class T> TWeakPtr<T>::TWeakPtr(const TWeakPtr& other) noexcept : T_(other.T_) -#if defined(_tsan_enabled_) +#if defined(_tsan_enabled_) || defined(_msan_enabled_) , RefCounter_(other.RefCounter_) #endif { @@ -77,7 +84,7 @@ TWeakPtr<T>::TWeakPtr(TWeakPtr<U>&& other) noexcept T_ = other.T_; other.T_ = nullptr; -#if defined(_tsan_enabled_) +#if defined(_tsan_enabled_) || defined(_msan_enabled_) RefCounter_ = other.RefCounter_; other.RefCounter_ = nullptr; #endif @@ -163,7 +170,7 @@ template <class T> void TWeakPtr<T>::Swap(TWeakPtr& other) noexcept { DoSwap(T_, other.T_); -#if defined(_tsan_enabled_) +#if defined(_tsan_enabled_) || defined(_msan_enabled_) DoSwap(RefCounter_, other.RefCounter_); #endif } @@ -208,12 +215,17 @@ void TWeakPtr<T>::ReleaseRef() if (T_) { // Support incomplete type. if (GetRefCounterImpl()->WeakUnref()) { + // The object's destructor has fully completed at this point + // and has poisoned T_'s vptr word under -fsanitize-memory-use-after-dtor. + // The upcast inside DeallocateRefCounted still needs that word + // to locate the virtual base. + NSan::Unpoison(T_, sizeof(void*)); DeallocateRefCounted(T_); } } } -#if defined(_tsan_enabled_) +#if defined(_tsan_enabled_) || defined(_msan_enabled_) template <class T> const TRefCounter* TWeakPtr<T>::GetRefCounterImpl() const { diff --git a/library/cpp/yt/memory/weak_ptr.h b/library/cpp/yt/memory/weak_ptr.h index d3598f62c74..c98abe15194 100644 --- a/library/cpp/yt/memory/weak_ptr.h +++ b/library/cpp/yt/memory/weak_ptr.h @@ -101,7 +101,7 @@ private: friend class TWeakPtr; T* T_ = nullptr; -#if defined(_tsan_enabled_) +#if defined(_tsan_enabled_) || defined(_msan_enabled_) const TRefCounter* RefCounter_ = nullptr; #endif |
