This is an automated email from the ASF dual-hosted git repository. adar pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 263c3aa894c087691ef2c4463d46a52a94f12c2b Author: Adar Dembo <[email protected]> AuthorDate: Mon Mar 30 15:10:18 2020 -0700 KUDU-3093: another band-aid for this DebugUtilTest.TestSignalStackTrace A TSAN build yielded a stack trace like: @ 0x444a88 __tsan::ProcessPendingSignals() @ 0x4541c1 __interceptor_pthread_mutex_trylock @ 0x7fbca26124e1 kudu::Mutex::TryAcquire() @ 0x7fbca2612893 kudu::Mutex::Acquire() @ 0x4fe036 kudu::MutexLock::MutexLock() @ 0x504abd kudu::CountDownLatch::WaitUntil() @ 0x504a5f kudu::CountDownLatch::WaitFor() @ 0x4f04a9 kudu::(anonymous namespace)::SleeperThread() ... Rather than find the synchronization primitive frame least likely to be inlined, let's take a more comprehensive approach and search for multiple candidate frames, including SleeperThread. I tested this locally in DEBUG, RELEASE, ASAN, and TSAN modes. Change-Id: Ia4ca0f48ba1d7ad4cea40b70af271d7948f78a57 Reviewed-on: http://gerrit.cloudera.org:8080/15605 Reviewed-by: Alexey Serbin <[email protected]> Tested-by: Kudu Jenkins --- src/kudu/util/debug-util-test.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/kudu/util/debug-util-test.cc b/src/kudu/util/debug-util-test.cc index 2227a19..c69dbbc 100644 --- a/src/kudu/util/debug-util-test.cc +++ b/src/kudu/util/debug-util-test.cc @@ -40,6 +40,7 @@ #include <gtest/gtest.h> #include "kudu/gutil/ref_counted.h" +#include "kudu/gutil/strings/substitute.h" #include "kudu/gutil/walltime.h" #include "kudu/util/array_view.h" #include "kudu/util/countdown_latch.h" @@ -53,6 +54,7 @@ using std::string; using std::vector; +using strings::Substitute; DECLARE_int32(test_timeout_after); DECLARE_int32(stress_cpu_threads); @@ -121,11 +123,16 @@ TEST_F(DebugUtilTest, TestSignalStackTrace) { // to start up and actually call our function. // // Note: due to RELEASE build inlining, we need to make sure to pick a stack - // frame that isn't optimized away. - static constexpr const char* kTestThreadStackFrame = + // frame that isn't optimized away. Different compilers behave differently, so + // we'll use a regular expression to get maximal coverage. + static constexpr const char* kTestThreadOneStackFrame = + "SleeperThread"; + static constexpr const char* kTestThreadAnotherStackFrame = "kudu::ConditionVariable::WaitUntil()"; + static const string kStackFrameRegExp = Substitute( + "$0|$1", kTestThreadOneStackFrame, kTestThreadAnotherStackFrame); ASSERT_EVENTUALLY([&]() { - ASSERT_STR_CONTAINS(DumpThreadStack(t->tid()), kTestThreadStackFrame); + ASSERT_STR_MATCHES(DumpThreadStack(t->tid()), kStackFrameRegExp); }); // Test that we can change the signal and that the stack traces still work, @@ -140,7 +147,7 @@ TEST_F(DebugUtilTest, TestSignalStackTrace) { ASSERT_FALSE(IsSignalHandlerRegistered(SIGUSR2)); // Stack traces should work using the new handler. - ASSERT_STR_CONTAINS(DumpThreadStack(t->tid()), kTestThreadStackFrame); + ASSERT_STR_MATCHES(DumpThreadStack(t->tid()), kStackFrameRegExp); // Switch back to SIGUSR2 and ensure it changes back. ASSERT_OK(SetStackTraceSignal(SIGUSR2)); @@ -148,7 +155,7 @@ TEST_F(DebugUtilTest, TestSignalStackTrace) { ASSERT_FALSE(IsSignalHandlerRegistered(SIGHUP)); // Stack traces should work using the new handler. - ASSERT_STR_CONTAINS(DumpThreadStack(t->tid()), kTestThreadStackFrame); + ASSERT_STR_MATCHES(DumpThreadStack(t->tid()), kStackFrameRegExp); // Register our own signal handler on SIGHUP, and ensure that // we get a bad Status if we try to use it.
