diff --git a/test/core/event_engine/event_engine_test_utils.cc b/test/core/event_engine/event_engine_test_utils.cc index cc036ad5d3b..1de11122b19 100644 --- a/test/core/event_engine/event_engine_test_utils.cc +++ b/test/core/event_engine/event_engine_test_utils.cc @@ -41,6 +41,7 @@ #include "src/core/lib/gprpp/notification.h" #include "src/core/lib/gprpp/time.h" #include "src/core/lib/resource_quota/memory_quota.h" +#include "test/core/test_util/build.h" // IWYU pragma: no_include @@ -77,7 +78,10 @@ std::string GetNextSendMessage() { } void WaitForSingleOwner(std::shared_ptr engine) { + int n = 0; while (engine.use_count() > 1) { + ++n; + if (n == 100) AsanAssertNoLeaks(); GRPC_LOG_EVERY_N_SEC(2, GPR_INFO, "engine.use_count() = %ld", engine.use_count()); absl::SleepFor(absl::Milliseconds(100)); diff --git a/test/core/test_util/build.cc b/test/core/test_util/build.cc index 04d39e9574d..2ae07567d5b 100644 --- a/test/core/test_util/build.cc +++ b/test/core/test_util/build.cc @@ -12,62 +12,80 @@ // See the License for the specific language governing permissions and // limitations under the License. -bool BuiltUnderValgrind() { -#ifdef RUNNING_ON_VALGRIND - return true; -#else - return false; -#endif -} +#include "test/core/test_util/build.h" -bool BuiltUnderTsan() { +// Define GRPC_BUILD_HAS_ASAN as 1 or 0 depending on if we're building under +// ASAN. #if defined(__has_feature) -#if __has_feature(thread_sanitizer) - return true; +#if __has_feature(address_sanitizer) +#define GRPC_BUILD_HAS_ASAN 1 #else - return false; +#define GRPC_BUILD_HAS_ASAN 0 #endif #else -#ifdef THREAD_SANITIZER - return true; +#ifdef ADDRESS_SANITIZER +#define GRPC_BUILD_HAS_ASAN 1 #else - return false; +#define GRPC_BUILD_HAS_ASAN 0 #endif #endif -} -bool BuiltUnderAsan() { +// Define GRPC_BUILD_HAS_TSAN as 1 or 0 depending on if we're building under +// TSAN. #if defined(__has_feature) -#if __has_feature(address_sanitizer) - return true; +#if __has_feature(thread_sanitizer) +#define GRPC_BUILD_HAS_TSAN 1 #else - return false; +#define GRPC_BUILD_HAS_TSAN 0 #endif #else -#ifdef ADDRESS_SANITIZER - return true; +#ifdef THREAD_SANITIZER +#define GRPC_BUILD_HAS_TSAN 1 #else - return false; +#define GRPC_BUILD_HAS_TSAN 0 #endif #endif -} -bool BuiltUnderMsan() { +// Define GRPC_BUILD_HAS_MSAN as 1 or 0 depending on if we're building under +// MSAN. #if defined(__has_feature) #if __has_feature(memory_sanitizer) - return true; +#define GRPC_BUILD_HAS_MSAN 1 #else - return false; +#define GRPC_BUILD_HAS_MSAN 0 #endif #else #ifdef MEMORY_SANITIZER +#define GRPC_BUILD_HAS_MSAN 1 +#else +#define GRPC_BUILD_HAS_MSAN 0 +#endif +#endif + +#if GRPC_BUILD_HAS_ASAN +#include +#endif + +bool BuiltUnderValgrind() { +#ifdef RUNNING_ON_VALGRIND return true; #else return false; #endif +} + +bool BuiltUnderTsan() { return GRPC_BUILD_HAS_TSAN != 0; } + +bool BuiltUnderAsan() { return GRPC_BUILD_HAS_ASAN != 0; } + +void AsanAssertNoLeaks() { +#if GRPC_BUILD_HAS_ASAN + __lsan_do_leak_check(); #endif } +bool BuiltUnderMsan() { return GRPC_BUILD_HAS_MSAN != 0; } + bool BuiltUnderUbsan() { #ifdef GRPC_UBSAN return true; diff --git a/test/core/test_util/build.h b/test/core/test_util/build.h index 20bc21954ff..8574dfe8d3c 100644 --- a/test/core/test_util/build.h +++ b/test/core/test_util/build.h @@ -30,4 +30,7 @@ bool BuiltUnderMsan(); // Returns whether this is built under UndefinedBehaviorSanitizer bool BuiltUnderUbsan(); +// Force a leak check if built under ASAN. If there are leaks, crash. +void AsanAssertNoLeaks(); + #endif // GRPC_TEST_CORE_TEST_UTIL_BUILD_H