Repository: kudu Updated Branches: refs/heads/master 21a01cff6 -> 9a12926f8
test_main: avoid signals for timeout handling Previously we used setitimer() to trigger test timeouts after the appropriate delay. However, this caused the timeout code to run in a signal handler, which TSAN flagged as unsafe because it allocates memory. This changes it to just use its own thread which sleeps before aborting the process after the prescribed timeout. The resulting behavior should be the same, though will avoid a bunch of confusing spew in TSAN builds that time out. Change-Id: I0af2485c14db366a409ba1409fa01314396d030a Reviewed-on: http://gerrit.cloudera.org:8080/4415 Tested-by: Kudu Jenkins Reviewed-by: Alexey Serbin <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/kudu/repo Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/f9dcf6bb Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/f9dcf6bb Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/f9dcf6bb Branch: refs/heads/master Commit: f9dcf6bb19a64fd38a2045a329c5cf2fa317440d Parents: 21a01cf Author: Todd Lipcon <[email protected]> Authored: Wed Sep 14 09:47:47 2016 -0700 Committer: Todd Lipcon <[email protected]> Committed: Wed Sep 14 19:59:43 2016 +0000 ---------------------------------------------------------------------- src/kudu/util/test_main.cc | 49 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kudu/blob/f9dcf6bb/src/kudu/util/test_main.cc ---------------------------------------------------------------------- diff --git a/src/kudu/util/test_main.cc b/src/kudu/util/test_main.cc index f1b3763..cc5f7f0 100644 --- a/src/kudu/util/test_main.cc +++ b/src/kudu/util/test_main.cc @@ -18,11 +18,8 @@ #include <gflags/gflags.h> #include <glog/logging.h> #include <gtest/gtest.h> -#include <signal.h> -#include <sys/time.h> #include <thread> -#include "kudu/gutil/atomicops.h" #include "kudu/util/pstack_watcher.h" #include "kudu/util/flags.h" #include "kudu/util/status.h" @@ -34,12 +31,23 @@ DEFINE_int32(stress_cpu_threads, 0, "Number of threads to start that burn CPU in an attempt to " "stimulate race conditions"); -// Start timer that kills the process if --test_timeout_after is exceeded before +namespace kudu { + +// Start thread that kills the process if --test_timeout_after is exceeded before // the tests complete. -static void CreateAndStartTimer(); +static void CreateAndStartTimeoutThread() { + if (FLAGS_test_timeout_after == 0) return; + std::thread([=](){ + SleepFor(MonoDelta::FromSeconds(FLAGS_test_timeout_after)); + // Dump a pstack to stdout. + WARN_NOT_OK(PstackWatcher::DumpStacks(), "Unable to print pstack"); + + // ...and abort. + LOG(FATAL) << "Maximum unit test time exceeded (" << FLAGS_test_timeout_after << " sec)"; + }).detach(); +} +} // namespace kudu -// Gracefully kill the process. -static void KillTestOnTimeout(int signum); static void StartStressThreads() { for (int i = 0; i < FLAGS_stress_cpu_threads; i++) { @@ -60,7 +68,7 @@ int main(int argc, char **argv) { kudu::ParseCommandLineFlags(&argc, &argv, true); // Create the test-timeout timer. - CreateAndStartTimer(); + kudu::CreateAndStartTimeoutThread(); StartStressThreads(); @@ -68,28 +76,3 @@ int main(int argc, char **argv) { return ret; } - -static void CreateAndStartTimer() { - struct sigaction action; - struct itimerval timer; - - // Create the test-timeout timer. - memset(&action, 0, sizeof(action)); - action.sa_handler = &KillTestOnTimeout; - CHECK_ERR(sigaction(SIGALRM, &action, nullptr)) << "Unable to set timeout action"; - - timer.it_interval.tv_sec = 0; // No repeat. - timer.it_interval.tv_usec = 0; - timer.it_value.tv_sec = FLAGS_test_timeout_after; // Fire in timeout seconds. - timer.it_value.tv_usec = 0; - - CHECK_ERR(setitimer(ITIMER_REAL, &timer, nullptr)) << "Unable to set timeout timer"; -} - -static void KillTestOnTimeout(int signum) { - // Dump a pstack to stdout. - WARN_NOT_OK(kudu::PstackWatcher::DumpStacks(), "Unable to print pstack"); - - // ...and abort. - LOG(FATAL) << "Maximum unit test time exceeded (" << FLAGS_test_timeout_after << " sec)"; -}
