瀏覽代碼

CTest: Use integer-representable value for "infinite" timeout

Refactoring in commit 66419bc046 (CTest: convert timeouts to
std::chrono::duration, 2017-11-20) changed out "infinite" timeout to a
value not representable by a 64-bit integer.  This causes undefined
behavior when e.g. KWSys Process converts the duration to a `long` to
interact with system APIs.  Use the old `1.0e7` maximum value.
Brad King 7 年之前
父節點
當前提交
ba6caafa42
共有 4 個文件被更改,包括 15 次插入25 次删除
  1. 2 6
      Source/CTest/cmCTestRunTest.cxx
  2. 2 9
      Source/CTest/cmCTestScriptHandler.cxx
  3. 9 10
      Source/cmCTest.cxx
  4. 2 0
      Source/cmCTest.h

+ 2 - 6
Source/CTest/cmCTestRunTest.cxx

@@ -1,9 +1,5 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifdef _WIN32
-/* windows.h defines min() and max() macros that interfere. */
-#define NOMINMAX
-#endif
 #include "cmCTestRunTest.h"
 
 #include "cmCTest.h"
@@ -678,7 +674,7 @@ bool cmCTestRunTest::ForkProcess(std::chrono::duration<double> testTimeOut,
   // determine how much time we have
   std::chrono::duration<double> timeout =
     this->CTest->GetRemainingTimeAllowed();
-  if (timeout != std::chrono::duration<double>::max()) {
+  if (timeout != cmCTest::MaxDuration()) {
     timeout -= std::chrono::minutes(2);
   }
   if (this->CTest->GetTimeOut() > std::chrono::duration<double>::zero() &&
@@ -702,7 +698,7 @@ bool cmCTestRunTest::ForkProcess(std::chrono::duration<double> testTimeOut,
     this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index
       << ": "
       << "Test timeout computed to be: "
-      << (timeout == std::chrono::duration<double>::max()
+      << (timeout == cmCTest::MaxDuration()
             ? std::string("infinite")
             : std::to_string(
                 std::chrono::duration_cast<std::chrono::seconds>(timeout)

+ 2 - 9
Source/CTest/cmCTestScriptHandler.cxx

@@ -1,12 +1,5 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
-
-#ifdef _WIN32
-/* windows.h defines min() and max() macros, unless told to otherwise. This
- * interferes with std::min() and std::max() at the very least. */
-#define NOMINMAX
-#endif
-
 #include "cmCTestScriptHandler.h"
 
 #include "cmsys/Directory.hxx"
@@ -970,13 +963,13 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce(
 std::chrono::duration<double> cmCTestScriptHandler::GetRemainingTimeAllowed()
 {
   if (!this->Makefile) {
-    return std::chrono::duration<double>::max();
+    return cmCTest::MaxDuration();
   }
 
   const char* timelimitS = this->Makefile->GetDefinition("CTEST_TIME_LIMIT");
 
   if (!timelimitS) {
-    return std::chrono::duration<double>::max();
+    return cmCTest::MaxDuration();
   }
 
   auto timelimit = std::chrono::duration<double>(atof(timelimitS));

+ 9 - 10
Source/cmCTest.cxx

@@ -1,11 +1,5 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifdef _WIN32
-/* windows.h defines min() and max() macros by default. This interferes with
- * C++ functions names.
- */
-#define NOMINMAX
-#endif
 #include "cmCTest.h"
 
 #include "cm_curl.h"
@@ -1089,7 +1083,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
 
   // determine how much time we have
   std::chrono::duration<double> timeout = this->GetRemainingTimeAllowed();
-  if (timeout != std::chrono::duration<double>::max()) {
+  if (timeout != cmCTest::MaxDuration()) {
     timeout -= std::chrono::minutes(2);
   }
   if (this->TimeOut > std::chrono::duration<double>::zero() &&
@@ -1107,7 +1101,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
   }
   cmCTestLog(
     this, HANDLER_VERBOSE_OUTPUT, "Test timeout computed to be: "
-      << (timeout == std::chrono::duration<double>::max()
+      << (timeout == cmCTest::MaxDuration()
             ? std::string("infinite")
             : std::to_string(
                 std::chrono::duration_cast<std::chrono::seconds>(timeout)
@@ -1130,7 +1124,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
         // invocations. Since --build-generator is required this is a
         // good place to check for it, and to add the arguments in
         if (strcmp(i, "--build-generator") == 0 &&
-            timeout != std::chrono::duration<double>::max() &&
+            timeout != cmCTest::MaxDuration() &&
             timeout > std::chrono::duration<double>::zero()) {
           args.push_back("--test-timeout");
           std::ostringstream msg;
@@ -2805,7 +2799,7 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
 std::chrono::duration<double> cmCTest::GetRemainingTimeAllowed()
 {
   if (!this->GetHandler("script")) {
-    return std::chrono::duration<double>::max();
+    return cmCTest::MaxDuration();
   }
 
   cmCTestScriptHandler* ch =
@@ -2814,6 +2808,11 @@ std::chrono::duration<double> cmCTest::GetRemainingTimeAllowed()
   return ch->GetRemainingTimeAllowed();
 }
 
+std::chrono::duration<double> cmCTest::MaxDuration()
+{
+  return std::chrono::duration<double>(1.0e7);
+}
+
 void cmCTest::OutputTestErrors(std::vector<char> const& process_output)
 {
   std::string test_outputs("\n*** Test Failed:\n");

+ 2 - 0
Source/cmCTest.h

@@ -208,6 +208,8 @@ public:
    */
   std::chrono::duration<double> GetRemainingTimeAllowed();
 
+  static std::chrono::duration<double> MaxDuration();
+
   /**
    * Open file in the output directory and set the stream
    */