summaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/cpp')
-rw-r--r--library/cpp/getopt/small/last_getopt_opts.h18
-rw-r--r--library/cpp/unified_agent_client/client_impl.cpp23
-rw-r--r--library/cpp/yt/memory/ref_counted-inl.h4
-rw-r--r--library/cpp/yt/memory/weak_ptr-inl.h22
-rw-r--r--library/cpp/yt/memory/weak_ptr.h2
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