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.

Reply via email to