[Cmake-commits] [cmake-commits] zach.mullen committed cmCTestMultiProcessHandler.cxx 1.31 1.32 cmCTestMultiProcessHandler.h 1.14 1.15

cmake-commits at cmake.org cmake-commits at cmake.org
Mon Nov 2 12:52:53 EST 2009


Update of /cvsroot/CMake/CMake/Source/CTest
In directory public:/mounts/ram/cvs-serv21570

Modified Files:
	cmCTestMultiProcessHandler.cxx cmCTestMultiProcessHandler.h 
Log Message:
Added logic to check for cycles in the test dependency graph before any tests are run.  Previously a cycle resulted in a segfault from stack overflow.


Index: cmCTestMultiProcessHandler.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CTest/cmCTestMultiProcessHandler.cxx,v
retrieving revision 1.31
retrieving revision 1.32
diff -C 2 -d -r1.31 -r1.32
*** cmCTestMultiProcessHandler.cxx	27 Oct 2009 14:16:01 -0000	1.31
--- cmCTestMultiProcessHandler.cxx	2 Nov 2009 17:52:48 -0000	1.32
***************
*** 16,19 ****
--- 16,20 ----
  #include "cmSystemTools.h"
  #include <stdlib.h>
+ #include <stack>
  
  cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
***************
*** 57,60 ****
--- 58,65 ----
  {
    this->CheckResume();
+   if(!this->CheckCycles())
+     {
+     return;
+     }
    this->TestHandler->SetMaxIndex(this->FindMaxIndex());
    this->StartNextTests();
***************
*** 341,345 ****
    int count = 0;
    for (PropertiesMap::iterator it = this->Properties.begin();
!        it != this->Properties.end(); it ++ )
      {
      count++;
--- 346,350 ----
    int count = 0;
    for (PropertiesMap::iterator it = this->Properties.begin();
!        it != this->Properties.end(); ++it)
      {
      count++;
***************
*** 434,435 ****
--- 439,484 ----
    return max;
  }
+ 
+ //Returns true if no cycles exist in the dependency graph
+ bool cmCTestMultiProcessHandler::CheckCycles()
+ {
+   cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, 
+              "Checking test dependency graph..." << std::endl);
+   for(TestMap::iterator it = this->Tests.begin();
+       it != this->Tests.end(); ++it)
+     {
+     //DFS from each element to itself
+     std::stack<int> s;
+     std::vector<int> visited;
+     s.push(it->first);
+     visited.push_back(it->first);
+ 
+     while(!s.empty())
+       {
+       int test = s.top();
+       s.pop();
+       
+       for(TestSet::iterator d = this->Tests[test].begin();
+           d != this->Tests[test].end(); ++d)
+         {
+         s.push(*d);
+         for(std::vector<int>::iterator v = visited.begin();
+             v != visited.end(); ++v)
+           {
+           if(*v == *d)
+             {
+             //cycle exists
+             cmCTestLog(this->CTest, ERROR_MESSAGE, "Error: a cycle exists in "
+               "the test dependency graph for the test \""
+               << this->Properties[*d]->Name << "\"." << std::endl
+               << "Please fix the cycle and run ctest again." << std::endl);
+             return false;
+             }
+           }
+         visited.push_back(*d);
+         }
+       visited.pop_back();
+       }
+     }
+   return true;
+ }

Index: cmCTestMultiProcessHandler.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CTest/cmCTestMultiProcessHandler.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -C 2 -d -r1.14 -r1.15
*** cmCTestMultiProcessHandler.h	28 Sep 2009 15:43:01 -0000	1.14
--- cmCTestMultiProcessHandler.h	2 Nov 2009 17:52:50 -0000	1.15
***************
*** 77,80 ****
--- 77,82 ----
    //Check if we need to resume an interrupted test set
    void CheckResume();
+   //Check if there are any circular dependencies
+   bool CheckCycles();
    int FindMaxIndex();
    inline size_t GetProcessorsUsed(int index);



More information about the Cmake-commits mailing list