This is an automated email from the ASF dual-hosted git repository. alexey pushed a commit to branch branch-1.9.x in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 01dd2bec4b5c076d7d58d514ae846378994e712a Author: Alexey Serbin <[email protected]> AuthorDate: Tue Mar 12 20:47:27 2019 -0700 KUDU-2743 [subprocess] test to repro deadlock in Subproces::Run() Added a test to reproduce deadlock when fork()-ed but not yet exec()-ed subprocess tries to log on a failed execve() call. The test is disabled because it fails. The follow-up changelist will fix the problem and re-enable the test. Change-Id: Ie88073bb7fcccf24b4451fe3c4e4cd8bd471ca67 Reviewed-on: http://gerrit.cloudera.org:8080/12740 Reviewed-by: Adar Dembo <[email protected]> Tested-by: Alexey Serbin <[email protected]> (cherry picked from commit 33479893bd6037c463e7cb89b08e1e016565e2c3) (cherry picked from commit 4bec64a8e0c22924d1addce8d19942147b191391) Reviewed-on: http://gerrit.cloudera.org:8080/12786 Reviewed-by: Andrew Wong <[email protected]> --- src/kudu/util/subprocess-test.cc | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/kudu/util/subprocess-test.cc b/src/kudu/util/subprocess-test.cc index 24d7cb3..a9b7aac 100644 --- a/src/kudu/util/subprocess-test.cc +++ b/src/kudu/util/subprocess-test.cc @@ -37,6 +37,7 @@ #include "kudu/gutil/macros.h" #include "kudu/gutil/strings/substitute.h" +#include "kudu/util/barrier.h" #include "kudu/util/env.h" #include "kudu/util/monotime.h" #include "kudu/util/path_util.h" @@ -352,6 +353,51 @@ TEST_F(SubprocessTest, TestSubprocessInterruptionHandling) { } } +TEST_F(SubprocessTest, DISABLED_TestSubprocessDeadlockOnLogging) { + int kNumLoggingThreads = 8; + // Participants are the logging threads and the main test thread. + Barrier barrier(kNumLoggingThreads + 1); + + // It should not take too long to run the scenario unless it's deadlocked. + alarm(15); + SCOPED_CLEANUP({ + alarm(0); + }); + + // Adding multiple threads writing logs. Each thread sleeps a bit after each + // message to get off from CPU. + atomic<bool> stop_logging(false); + vector<thread> threads; + for (auto i = 0; i < kNumLoggingThreads; ++i) { + const auto thread_idx = i; + threads.emplace_back([&barrier, &stop_logging, thread_idx] () { + barrier.Wait(); + size_t msg_id = 0; + while (!stop_logging) { + LOG(INFO) << Substitute("$0: $1", thread_idx, msg_id++); + SleepFor(MonoDelta::FromNanoseconds(thread_idx)); + } + }); + } + + SCOPED_CLEANUP({ + stop_logging = true; + for (auto& thread : threads) { + thread.join(); + } + }); + + barrier.Wait(); + // Prior to the patch that fixed the problem, it was enough to have just one + // iteration to have the spawned process deadlocked. However, it does not hurt + // to run several iterations to give the issue, if any, a greater chance to + // manifest itself. + for (auto i = 0; i < 32; ++i) { + auto s = Subprocess::Call("./nonexistent.file"); + ASSERT_TRUE(s.IsRuntimeError()) << s.ToString(); + } +} + #ifdef __linux__ // This test requires a system with /proc/<pid>/stat. TEST_F(SubprocessTest, TestGetProcfsState) {
