diff options
Diffstat (limited to 'library/cpp')
| -rw-r--r-- | library/cpp/getopt/small/last_getopt_opts.h | 18 | ||||
| -rw-r--r-- | library/cpp/unified_agent_client/client_impl.cpp | 23 | ||||
| -rw-r--r-- | library/cpp/yt/memory/ref_counted-inl.h | 4 | ||||
| -rw-r--r-- | library/cpp/yt/memory/weak_ptr-inl.h | 22 | ||||
| -rw-r--r-- | library/cpp/yt/memory/weak_ptr.h | 2 |
5 files changed, 56 insertions, 13 deletions
diff --git a/library/cpp/getopt/small/last_getopt_opts.h b/library/cpp/getopt/small/last_getopt_opts.h index fd0ef978c1f..868477ec79e 100644 --- a/library/cpp/getopt/small/last_getopt_opts.h +++ b/library/cpp/getopt/small/last_getopt_opts.h @@ -463,6 +463,24 @@ namespace NLastGetopt { } /** + * Add section with examples. + * + * @param examples text of this section + */ + void SetExamples(std::string_view examples) { + SetExamples(TString(examples)); + } + + /** + * Add section with examples. + * + * @param examples text of this section + */ + void SetExamples(const char* examples) { + SetExamples(TString(examples)); + } + + /** * Set minimal number of free args * * @param min new value diff --git a/library/cpp/unified_agent_client/client_impl.cpp b/library/cpp/unified_agent_client/client_impl.cpp index ffe16d8da37..dc4241344ff 100644 --- a/library/cpp/unified_agent_client/client_impl.cpp +++ b/library/cpp/unified_agent_client/client_impl.cpp @@ -8,6 +8,7 @@ #include <contrib/libs/grpc/src/core/lib/iomgr/executor.h> #include <util/charset/utf8.h> +#include <util/generic/scope.h> #include <util/generic/size_literals.h> #include <util/system/env.h> @@ -513,14 +514,22 @@ namespace NUnifiedAgent::NPrivate { } void TClientSession::CheckGrpcCallInactivity() { - with_lock(Lock) { - if (Closed || !Started) { - return; - } - const auto timeout = Client->GetParameters().GrpcCallInactivityTimeout; - if (timeout == TDuration::Zero()) { - return; + if (!Lock.TryAcquire()) { + TSpinWait sw; + + while (Lock.IsLocked() || !Lock.TryAcquire()) { + if (ForkInProgress.load()) { + return; + } + sw.Sleep(); } + } + Y_DEFER { + Lock.Release(); + }; + + const auto timeout = Client->GetParameters().GrpcCallInactivityTimeout; + if (!Closed && Started && timeout != TDuration::Zero()) { if (NegotiatedProtocol.Defined() && *NegotiatedProtocol > 0 && ActiveGrpcCall && !CloseStarted && 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/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 |
