1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCTestMemCheckHandler.cxx,v $
6 Date: $Date: 2009-02-05 21:31:37 $
7 Version: $Revision: 1.22 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
18 #include "cmCTestMemCheckHandler.h"
19 #include "cmXMLParser.h"
22 #include "cmGeneratedFileStream.h"
23 #include <cmsys/Process.h>
24 #include <cmsys/RegularExpression.hxx>
25 #include <cmsys/Base64.h>
26 #include "cmMakefile.h"
27 #include "cmXMLSafe.h"
35 const char* ErrorCategory
;
40 static CatToErrorType cmCTestMemCheckBoundsChecker
[] = {
42 {"Write Overrun", cmCTestMemCheckHandler::ABW
},
43 {"Read Overrun", cmCTestMemCheckHandler::ABR
},
44 {"Memory Overrun", cmCTestMemCheckHandler::ABW
},
45 {"Allocation Conflict", cmCTestMemCheckHandler::FMM
},
46 {"Bad Pointer Use", cmCTestMemCheckHandler::FMW
},
47 {"Dangling Pointer", cmCTestMemCheckHandler::FMR
},
51 // parse the xml file storing the installed version of Xcode on
53 class cmBoundsCheckerParser
: public cmXMLParser
56 cmBoundsCheckerParser(cmCTest
* c
) { this->CTest
= c
;}
57 void StartElement(const char* name
, const char** atts
)
59 if(strcmp(name
, "MemoryLeak") == 0)
61 this->Errors
.push_back(cmCTestMemCheckHandler::MLK
);
63 if(strcmp(name
, "ResourceLeak") == 0)
65 this->Errors
.push_back(cmCTestMemCheckHandler::MLK
);
67 if(strcmp(name
, "Error") == 0)
69 this->ParseError(atts
);
71 if(strcmp(name
, "Dangling Pointer") == 0)
73 this->ParseError(atts
);
77 ostr
<< name
<< ":\n";
79 for(; atts
[i
] != 0; i
+=2)
81 ostr
<< " " << cmXMLSafe(atts
[i
])
82 << " - " << cmXMLSafe(atts
[i
+1]) << "\n";
85 this->Log
+= ostr
.str();
87 void EndElement(const char* )
91 const char* GetAttribute(const char* name
, const char** atts
)
94 for(; atts
[i
] != 0; ++i
)
96 if(strcmp(name
, atts
[i
]) == 0)
103 void ParseError(const char** atts
)
105 CatToErrorType
* ptr
= cmCTestMemCheckBoundsChecker
;
106 const char* cat
= this->GetAttribute("ErrorCategory", atts
);
109 this->Errors
.push_back(cmCTestMemCheckHandler::ABW
); // do not know
110 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
111 "No Category found in Bounds checker XML\n" );
114 while(ptr
->ErrorCategory
&& cat
)
116 if(strcmp(ptr
->ErrorCategory
, cat
) == 0)
118 this->Errors
.push_back(ptr
->ErrorCode
);
119 return; // found it we are done
123 if(ptr
->ErrorCategory
)
125 this->Errors
.push_back(cmCTestMemCheckHandler::ABW
); // do not know
126 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
127 "Found unknown Bounds Checker error "
128 << ptr
->ErrorCategory
<< std::endl
);
132 std::vector
<int> Errors
;
136 #define BOUNDS_CHECKER_MARKER \
137 "******######*****Begin BOUNDS CHECKER XML******######******"
138 //----------------------------------------------------------------------
139 static const char* cmCTestMemCheckResultStrings
[] = {
166 //----------------------------------------------------------------------
167 static const char* cmCTestMemCheckResultLongStrings
[] = {
175 "Mismatched deallocation",
183 "Potential Memory Leak",
186 "Invalid syscall param",
188 "Uninitialized Memory Conditional",
189 "Uninitialized Memory Read",
194 //----------------------------------------------------------------------
195 cmCTestMemCheckHandler::cmCTestMemCheckHandler()
197 this->MemCheck
= true;
198 this->CustomMaximumPassedTestOutputSize
= 0;
199 this->CustomMaximumFailedTestOutputSize
= 0;
202 //----------------------------------------------------------------------
203 void cmCTestMemCheckHandler::Initialize()
205 this->Superclass::Initialize();
206 this->CustomMaximumPassedTestOutputSize
= 0;
207 this->CustomMaximumFailedTestOutputSize
= 0;
208 this->MemoryTester
= "";
209 this->MemoryTesterOptionsParsed
.clear();
210 this->MemoryTesterOptions
= "";
211 this->MemoryTesterStyle
= UNKNOWN
;
212 this->MemoryTesterOutputFile
= "";
214 for ( cc
= 0; cc
< NO_MEMORY_FAULT
; cc
++ )
216 this->MemoryTesterGlobalResults
[cc
] = 0;
221 //----------------------------------------------------------------------
222 int cmCTestMemCheckHandler::PreProcessHandler()
224 if ( !this->InitializeMemoryChecking() )
229 if ( !this->ExecuteCommands(this->CustomPreMemCheck
) )
231 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
232 "Problem executing pre-memcheck command(s)." << std::endl
);
238 //----------------------------------------------------------------------
239 int cmCTestMemCheckHandler::PostProcessHandler()
241 if ( !this->ExecuteCommands(this->CustomPostMemCheck
) )
243 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
244 "Problem executing post-memcheck command(s)." << std::endl
);
250 //----------------------------------------------------------------------
251 void cmCTestMemCheckHandler::GenerateTestCommand(
252 std::vector
<const char*>& args
)
254 std::vector
<cmStdString
>::size_type pp
;
255 args
.push_back(this->MemoryTester
.c_str());
256 std::string memcheckcommand
= "";
257 memcheckcommand
= this->MemoryTester
;
258 for ( pp
= 0; pp
< this->MemoryTesterOptionsParsed
.size(); pp
++ )
260 args
.push_back(this->MemoryTesterOptionsParsed
[pp
].c_str());
261 memcheckcommand
+= " ";
262 memcheckcommand
+= cmSystemTools::EscapeSpaces(
263 this->MemoryTesterOptionsParsed
[pp
].c_str());
265 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
, "Memory check command: "
266 << memcheckcommand
<< std::endl
);
269 //----------------------------------------------------------------------
270 void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile
*mf
)
272 this->cmCTestTestHandler::PopulateCustomVectors(mf
);
273 this->CTest
->PopulateCustomVector(mf
, "CTEST_CUSTOM_PRE_MEMCHECK",
274 this->CustomPreMemCheck
);
275 this->CTest
->PopulateCustomVector(mf
, "CTEST_CUSTOM_POST_MEMCHECK",
276 this->CustomPostMemCheck
);
278 this->CTest
->PopulateCustomVector(mf
,
279 "CTEST_CUSTOM_MEMCHECK_IGNORE",
280 this->CustomTestsIgnore
);
283 //----------------------------------------------------------------------
284 void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream
& os
)
286 if ( !this->CTest
->GetProduceXML() )
291 this->CTest
->StartXML(os
, this->AppendXML
);
292 os
<< "<DynamicAnalysis Checker=\"";
293 switch ( this->MemoryTesterStyle
)
295 case cmCTestMemCheckHandler::VALGRIND
:
298 case cmCTestMemCheckHandler::PURIFY
:
301 case cmCTestMemCheckHandler::BOUNDS_CHECKER
:
302 os
<< "BoundsChecker";
307 os
<< "\">" << std::endl
;
309 os
<< "\t<StartDateTime>" << this->StartTest
<< "</StartDateTime>\n"
310 << "\t<StartTestTime>" << this->StartTestTime
<< "</StartTestTime>\n"
312 cmCTestMemCheckHandler::TestResultsVector::size_type cc
;
313 for ( cc
= 0; cc
< this->TestResults
.size(); cc
++ )
315 cmCTestTestResult
*result
= &this->TestResults
[cc
];
316 std::string testPath
= result
->Path
+ "/" + result
->Name
;
317 os
<< "\t\t<Test>" << cmXMLSafe(
318 this->CTest
->GetShortPathToFile(testPath
.c_str()))
319 << "</Test>" << std::endl
;
321 os
<< "\t</TestList>\n";
322 cmCTestLog(this->CTest
, HANDLER_OUTPUT
,
323 "-- Processing memory checking output: ");
324 size_t total
= this->TestResults
.size();
325 size_t step
= total
/ 10;
327 for ( cc
= 0; cc
< this->TestResults
.size(); cc
++ )
329 cmCTestTestResult
*result
= &this->TestResults
[cc
];
330 std::string memcheckstr
;
331 int memcheckresults
[cmCTestMemCheckHandler::NO_MEMORY_FAULT
];
333 bool res
= this->ProcessMemCheckOutput(result
->Output
, memcheckstr
,
335 if ( res
&& result
->Status
== cmCTestMemCheckHandler::COMPLETED
)
339 this->CleanTestOutput(memcheckstr
,
340 static_cast<size_t>(this->CustomMaximumFailedTestOutputSize
));
341 this->WriteTestResultHeader(os
, result
);
342 os
<< "\t\t<Results>" << std::endl
;
343 for ( kk
= 0; cmCTestMemCheckResultLongStrings
[kk
]; kk
++ )
345 if ( memcheckresults
[kk
] )
347 os
<< "\t\t\t<Defect type=\"" << cmCTestMemCheckResultLongStrings
[kk
]
349 << memcheckresults
[kk
]
350 << "</Defect>" << std::endl
;
352 this->MemoryTesterGlobalResults
[kk
] += memcheckresults
[kk
];
355 << "\t\t</Results>\n"
356 << "\t<Log>\n" << memcheckstr
<< std::endl
358 this->WriteTestResultFooter(os
, result
);
361 cmCTestLog(this->CTest
, HANDLER_OUTPUT
, "#" << std::flush
);
365 cmCTestLog(this->CTest
, HANDLER_OUTPUT
, std::endl
);
366 cmCTestLog(this->CTest
, HANDLER_OUTPUT
, "Memory checking results:"
368 os
<< "\t<DefectList>" << std::endl
;
369 for ( cc
= 0; cmCTestMemCheckResultStrings
[cc
]; cc
++ )
371 if ( this->MemoryTesterGlobalResults
[cc
] )
378 cmCTestLog(this->CTest
, HANDLER_OUTPUT
,
379 cmCTestMemCheckResultLongStrings
[cc
] << " - "
380 << this->MemoryTesterGlobalResults
[cc
] << std::endl
);
381 os
<< "\t\t<Defect Type=\"" << cmCTestMemCheckResultLongStrings
[cc
]
382 << "\"/>" << std::endl
;
385 os
<< "\t</DefectList>" << std::endl
;
387 os
<< "\t<EndDateTime>" << this->EndTest
<< "</EndDateTime>" << std::endl
;
388 os
<< "\t<EndTestTime>" << this->EndTestTime
389 << "</EndTestTime>" << std::endl
;
390 os
<< "<ElapsedMinutes>"
391 << static_cast<int>(this->ElapsedTestingTime
/6)/10.0
392 << "</ElapsedMinutes>\n";
394 os
<< "</DynamicAnalysis>" << std::endl
;
395 this->CTest
->EndXML(os
);
400 //----------------------------------------------------------------------
401 bool cmCTestMemCheckHandler::InitializeMemoryChecking()
404 if ( cmSystemTools::FileExists(this->CTest
->GetCTestConfiguration(
405 "MemoryCheckCommand").c_str()) )
408 = cmSystemTools::ConvertToOutputPath(this->CTest
->GetCTestConfiguration(
409 "MemoryCheckCommand").c_str());
411 else if ( cmSystemTools::FileExists(this->CTest
->GetCTestConfiguration(
412 "PurifyCommand").c_str()) )
415 = cmSystemTools::ConvertToOutputPath(this->CTest
->GetCTestConfiguration(
416 "PurifyCommand").c_str());
418 else if ( cmSystemTools::FileExists(this->CTest
->GetCTestConfiguration(
419 "ValgrindCommand").c_str()) )
422 = cmSystemTools::ConvertToOutputPath(this->CTest
->GetCTestConfiguration(
423 "ValgrindCommand").c_str());
425 else if ( cmSystemTools::FileExists(this->CTest
->GetCTestConfiguration(
426 "BoundsCheckerCommand").c_str()) )
429 = cmSystemTools::ConvertToOutputPath(this->CTest
->GetCTestConfiguration(
430 "BoundsCheckerCommand").c_str());
434 cmCTestLog(this->CTest
, WARNING
,
435 "Memory checker (MemoryCheckCommand) "
436 "not set, or cannot find the specified program."
441 if ( this->MemoryTester
[0] == '\"' &&
442 this->MemoryTester
[this->MemoryTester
.size()-1] == '\"' )
445 = this->MemoryTester
.substr(1, this->MemoryTester
.size()-2);
449 if ( this->CTest
->GetCTestConfiguration(
450 "MemoryCheckCommandOptions").size() )
452 this->MemoryTesterOptions
= this->CTest
->GetCTestConfiguration(
453 "MemoryCheckCommandOptions");
455 else if ( this->CTest
->GetCTestConfiguration(
456 "ValgrindCommandOptions").size() )
458 this->MemoryTesterOptions
= this->CTest
->GetCTestConfiguration(
459 "ValgrindCommandOptions");
462 this->MemoryTesterOutputFile
463 = this->CTest
->GetBinaryDir() + "/Testing/Temporary/MemoryChecker.log";
465 if ( this->MemoryTester
.find("valgrind") != std::string::npos
)
467 this->MemoryTesterStyle
= cmCTestMemCheckHandler::VALGRIND
;
468 if ( !this->MemoryTesterOptions
.size() )
470 this->MemoryTesterOptions
= "-q --tool=memcheck --leak-check=yes "
471 "--show-reachable=yes --workaround-gcc296-bugs=yes --num-callers=100";
473 if ( this->CTest
->GetCTestConfiguration(
474 "MemoryCheckSuppressionFile").size() )
476 if ( !cmSystemTools::FileExists(this->CTest
->GetCTestConfiguration(
477 "MemoryCheckSuppressionFile").c_str()) )
479 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
480 "Cannot find memory checker suppression file: "
481 << this->CTest
->GetCTestConfiguration(
482 "MemoryCheckSuppressionFile").c_str() << std::endl
);
485 this->MemoryTesterOptions
+= " --suppressions=" +
486 cmSystemTools::EscapeSpaces(this->CTest
->GetCTestConfiguration(
487 "MemoryCheckSuppressionFile").c_str()) + "";
490 else if ( this->MemoryTester
.find("purify") != std::string::npos
)
492 this->MemoryTesterStyle
= cmCTestMemCheckHandler::PURIFY
;
493 std::string outputFile
=
494 cmSystemTools::EscapeSpaces(this->MemoryTesterOutputFile
.c_str());
497 this->MemoryTesterOptions
+= " /SAVETEXTDATA=" + outputFile
;
499 this->MemoryTesterOptions
+= " -log-file=" + outputFile
;
502 else if ( this->MemoryTester
.find("BC") != std::string::npos
)
504 this->BoundsCheckerXMLFile
= this->MemoryTesterOutputFile
;
505 std::string outputFile
=
506 cmSystemTools::EscapeSpaces(this->MemoryTesterOutputFile
.c_str());
507 std::string dpbdFile
= this->CTest
->GetBinaryDir()
508 + "/Testing/Temporary/MemoryChecker.DPbd";
509 std::string errorFile
= this->CTest
->GetBinaryDir()
510 + "/Testing/Temporary/MemoryChecker.error";
511 errorFile
= cmSystemTools::EscapeSpaces(errorFile
.c_str());
512 this->BoundsCheckerDPBDFile
= dpbdFile
;
513 dpbdFile
= cmSystemTools::EscapeSpaces(dpbdFile
.c_str());
514 this->MemoryTesterStyle
= cmCTestMemCheckHandler::BOUNDS_CHECKER
;
515 this->MemoryTesterOptions
+= " /B " + dpbdFile
;
516 this->MemoryTesterOptions
+= " /X " + outputFile
;
517 this->MemoryTesterOptions
+= " /M ";
521 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
522 "Do not understand memory checker: " << this->MemoryTester
.c_str()
527 this->MemoryTesterOptionsParsed
528 = cmSystemTools::ParseArguments(this->MemoryTesterOptions
.c_str());
529 std::vector
<cmStdString
>::size_type cc
;
530 for ( cc
= 0; cmCTestMemCheckResultStrings
[cc
]; cc
++ )
532 this->MemoryTesterGlobalResults
[cc
] = 0;
537 //----------------------------------------------------------------------
538 bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string
& str
,
539 std::string
& log
, int* results
)
541 std::string::size_type cc
;
542 for ( cc
= 0; cc
< cmCTestMemCheckHandler::NO_MEMORY_FAULT
; cc
++ )
547 if ( this->MemoryTesterStyle
== cmCTestMemCheckHandler::VALGRIND
)
549 return this->ProcessMemCheckValgrindOutput(str
, log
, results
);
551 else if ( this->MemoryTesterStyle
== cmCTestMemCheckHandler::PURIFY
)
553 return this->ProcessMemCheckPurifyOutput(str
, log
, results
);
555 else if ( this->MemoryTesterStyle
==
556 cmCTestMemCheckHandler::BOUNDS_CHECKER
)
558 return this->ProcessMemCheckBoundsCheckerOutput(str
, log
, results
);
562 log
.append("\nMemory checking style used was: ");
563 log
.append("None that I know");
571 //----------------------------------------------------------------------
572 bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
573 const std::string
& str
, std::string
& log
,
576 std::vector
<cmStdString
> lines
;
577 cmSystemTools::Split(str
.c_str(), lines
);
578 cmOStringStream ostr
;
581 cmsys::RegularExpression
pfW("^\\[[WEI]\\] ([A-Z][A-Z][A-Z][A-Z]*): ");
585 for( std::vector
<cmStdString
>::iterator i
= lines
.begin();
586 i
!= lines
.end(); ++i
)
588 int failure
= cmCTestMemCheckHandler::NO_MEMORY_FAULT
;
592 for ( cc
= 0; cc
< cmCTestMemCheckHandler::NO_MEMORY_FAULT
; cc
++ )
594 if ( pfW
.match(1) == cmCTestMemCheckResultStrings
[cc
] )
600 if ( cc
== cmCTestMemCheckHandler::NO_MEMORY_FAULT
)
602 cmCTestLog(this->CTest
, ERROR_MESSAGE
, "Unknown Purify memory fault: "
603 << pfW
.match(1) << std::endl
);
604 ostr
<< "*** Unknown Purify memory fault: " << pfW
.match(1)
608 if ( failure
!= NO_MEMORY_FAULT
)
610 ostr
<< "<b>" << cmCTestMemCheckResultStrings
[failure
] << "</b> ";
614 ostr
<< cmXMLSafe(*i
) << std::endl
;
625 //----------------------------------------------------------------------
626 bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
627 const std::string
& str
, std::string
& log
,
630 std::vector
<cmStdString
> lines
;
631 cmSystemTools::Split(str
.c_str(), lines
);
632 bool unlimitedOutput
= false;
633 if(str
.find("CTEST_FULL_OUTPUT") != str
.npos
||
634 this->CustomMaximumFailedTestOutputSize
== 0)
636 unlimitedOutput
= true;
639 std::string::size_type cc
;
641 cmOStringStream ostr
;
646 cmsys::RegularExpression
valgrindLine("^==[0-9][0-9]*==");
648 cmsys::RegularExpression
vgFIM(
649 "== .*Invalid free\\(\\) / delete / delete\\[\\]");
650 cmsys::RegularExpression
vgFMM(
651 "== .*Mismatched free\\(\\) / delete / delete \\[\\]");
652 cmsys::RegularExpression
vgMLK(
653 "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are definitely lost"
654 " in loss record [0-9][0-9]* of [0-9]");
655 cmsys::RegularExpression
vgPAR(
656 "== .*Syscall param .* contains unaddressable byte\\(s\\)");
657 cmsys::RegularExpression
vgMPK1(
658 "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are possibly lost in"
659 " loss record [0-9][0-9]* of [0-9]");
660 cmsys::RegularExpression
vgMPK2(
661 "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are still reachable"
662 " in loss record [0-9][0-9]* of [0-9]");
663 cmsys::RegularExpression
vgUMC(
664 "== .*Conditional jump or move depends on uninitialised value\\(s\\)");
665 cmsys::RegularExpression
vgUMR1(
666 "== .*Use of uninitialised value of size [0-9][0-9]*");
667 cmsys::RegularExpression
vgUMR2("== .*Invalid read of size [0-9][0-9]*");
668 cmsys::RegularExpression
vgUMR3("== .*Jump to the invalid address ");
669 cmsys::RegularExpression
vgUMR4("== .*Syscall param .* contains "
670 "uninitialised or unaddressable byte\\(s\\)");
671 cmsys::RegularExpression
vgUMR5("== .*Syscall param .* uninitialised");
672 cmsys::RegularExpression
vgIPW("== .*Invalid write of size [0-9]");
673 cmsys::RegularExpression
vgABR("== .*pthread_mutex_unlock: mutex is "
674 "locked by a different thread");
675 std::vector
<std::string::size_type
> nonValGrindOutput
;
676 double sttime
= cmSystemTools::GetTime();
677 cmCTestLog(this->CTest
, DEBUG
, "Start test: " << lines
.size() << std::endl
);
678 std::string::size_type totalOutputSize
= 0;
679 bool outputFull
= false;
680 for ( cc
= 0; cc
< lines
.size(); cc
++ )
682 cmCTestLog(this->CTest
, DEBUG
, "test line "
683 << lines
[cc
] << std::endl
);
685 if ( valgrindLine
.find(lines
[cc
]) )
687 cmCTestLog(this->CTest
, DEBUG
, "valgrind line "
688 << lines
[cc
] << std::endl
);
689 int failure
= cmCTestMemCheckHandler::NO_MEMORY_FAULT
;
690 if ( vgFIM
.find(lines
[cc
]) )
692 failure
= cmCTestMemCheckHandler::FIM
;
694 else if ( vgFMM
.find(lines
[cc
]) )
696 failure
= cmCTestMemCheckHandler::FMM
;
698 else if ( vgMLK
.find(lines
[cc
]) )
700 failure
= cmCTestMemCheckHandler::MLK
;
702 else if ( vgPAR
.find(lines
[cc
]) )
704 failure
= cmCTestMemCheckHandler::PAR
;
706 else if ( vgMPK1
.find(lines
[cc
]) )
708 failure
= cmCTestMemCheckHandler::MPK
;
710 else if ( vgMPK2
.find(lines
[cc
]) )
712 failure
= cmCTestMemCheckHandler::MPK
;
714 else if ( vgUMC
.find(lines
[cc
]) )
716 failure
= cmCTestMemCheckHandler::UMC
;
718 else if ( vgUMR1
.find(lines
[cc
]) )
720 failure
= cmCTestMemCheckHandler::UMR
;
722 else if ( vgUMR2
.find(lines
[cc
]) )
724 failure
= cmCTestMemCheckHandler::UMR
;
726 else if ( vgUMR3
.find(lines
[cc
]) )
728 failure
= cmCTestMemCheckHandler::UMR
;
730 else if ( vgUMR4
.find(lines
[cc
]) )
732 failure
= cmCTestMemCheckHandler::UMR
;
734 else if ( vgUMR5
.find(lines
[cc
]) )
736 failure
= cmCTestMemCheckHandler::UMR
;
738 else if ( vgIPW
.find(lines
[cc
]) )
740 failure
= cmCTestMemCheckHandler::IPW
;
742 else if ( vgABR
.find(lines
[cc
]) )
744 failure
= cmCTestMemCheckHandler::ABR
;
747 if ( failure
!= cmCTestMemCheckHandler::NO_MEMORY_FAULT
)
749 ostr
<< "<b>" << cmCTestMemCheckResultStrings
[failure
] << "</b> ";
753 totalOutputSize
+= lines
[cc
].size();
754 ostr
<< cmXMLSafe(lines
[cc
]) << std::endl
;
758 nonValGrindOutput
.push_back(cc
);
761 // Now put all all the non valgrind output into the test output
764 for(std::vector
<std::string::size_type
>::iterator i
=
765 nonValGrindOutput
.begin(); i
!= nonValGrindOutput
.end(); ++i
)
767 totalOutputSize
+= lines
[*i
].size();
768 cmCTestLog(this->CTest
, DEBUG
, "before xml safe "
769 << lines
[*i
] << std::endl
);
770 cmCTestLog(this->CTest
, DEBUG
, "after xml safe "
771 << cmXMLSafe(lines
[*i
]) << std::endl
);
773 ostr
<< cmXMLSafe(lines
[*i
]) << std::endl
;
774 if(!unlimitedOutput
&& totalOutputSize
>
775 static_cast<size_t>(this->CustomMaximumFailedTestOutputSize
))
779 ostr
<< "Test Output for this test has been truncated see testing"
780 " machine logs for full output,\n";
781 ostr
<< "or put CTEST_FULL_OUTPUT in the output of "
782 "this test program.\n";
786 cmCTestLog(this->CTest
, DEBUG
, "End test (elapsed: "
787 << (cmSystemTools::GetTime() - sttime
) << std::endl
);
798 //----------------------------------------------------------------------
799 bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
800 const std::string
& str
, std::string
& log
,
804 double sttime
= cmSystemTools::GetTime();
805 std::vector
<cmStdString
> lines
;
806 cmSystemTools::Split(str
.c_str(), lines
);
807 cmCTestLog(this->CTest
, DEBUG
, "Start test: " << lines
.size() << std::endl
);
808 std::vector
<cmStdString
>::size_type cc
;
809 for ( cc
= 0; cc
< lines
.size(); cc
++ )
811 if(lines
[cc
] == BOUNDS_CHECKER_MARKER
)
816 cmBoundsCheckerParser
parser(this->CTest
);
817 parser
.InitializeParser();
818 if(cc
< lines
.size())
820 for(cc
++; cc
< lines
.size(); ++cc
)
822 std::string
& theLine
= lines
[cc
];
823 // check for command line arguments that are not escaped
825 if(theLine
.find("TargetArgs=") != theLine
.npos
)
827 // skip this because BC gets it wrong and we can't parse it
829 else if(!parser
.ParseChunk(theLine
.c_str(), theLine
.size()))
831 cmCTestLog(this->CTest
, ERROR_MESSAGE
,
832 "Error in ParseChunk: " << theLine
.c_str()
838 for(cc
=0; cc
< parser
.Errors
.size(); ++cc
)
840 results
[parser
.Errors
[cc
]]++;
843 cmCTestLog(this->CTest
, DEBUG
, "End test (elapsed: "
844 << (cmSystemTools::GetTime() - sttime
) << std::endl
);
847 // only put the output of Bounds Checker if there were
848 // errors or leaks detected
856 cmCTestMemCheckHandler::ProcessOneTest(cmCTestTestProperties
*props
,
857 std::vector
<cmStdString
> &passed
,
858 std::vector
<cmStdString
> &failed
,
859 int count
, int tmsize
)
862 cmCTestTestHandler::ProcessOneTest(props
, passed
, failed
, count
, tmsize
);
863 cmCTestTestResult
& res
= this->TestResults
[this->TestResults
.size()-1];
864 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
, "process test output now: "
865 << props
->Name
.c_str() << " " << res
.Name
.c_str() << std::endl
);
866 if( this->MemoryTesterStyle
== cmCTestMemCheckHandler::BOUNDS_CHECKER
)
868 this->PostProcessBoundsCheckerTest(res
);
870 else if(this->MemoryTesterStyle
== cmCTestMemCheckHandler::PURIFY
)
872 this->PostProcessPurifyTest(res
);
876 // This method puts the bounds checker output file into the output
879 cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult
& res
)
881 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
,
882 "PostProcessBoundsCheckerTest for : "
883 << res
.Name
.c_str() << std::endl
);
884 if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile
.c_str()) )
886 std::string log
= "Cannot find memory tester output file: "
887 + this->MemoryTesterOutputFile
;
888 cmCTestLog(this->CTest
, ERROR_MESSAGE
, log
.c_str() << std::endl
);
891 // put a scope around this to close ifs so the file can be removed
893 std::ifstream
ifs(this->MemoryTesterOutputFile
.c_str());
896 std::string log
= "Cannot read memory tester output file: "
897 + this->MemoryTesterOutputFile
;
898 cmCTestLog(this->CTest
, ERROR_MESSAGE
, log
.c_str() << std::endl
);
901 res
.Output
+= BOUNDS_CHECKER_MARKER
;
904 while ( cmSystemTools::GetLineFromStream(ifs
, line
) )
910 cmSystemTools::Delay(1000);
911 cmSystemTools::RemoveFile(this->BoundsCheckerDPBDFile
.c_str());
912 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
, "Remove: "
913 << this->BoundsCheckerDPBDFile
.c_str() << std::endl
);
914 cmSystemTools::RemoveFile(this->BoundsCheckerXMLFile
.c_str());
915 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
, "Remove: "
916 << this->BoundsCheckerXMLFile
.c_str() << std::endl
);
920 cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult
& res
)
922 cmCTestLog(this->CTest
, HANDLER_VERBOSE_OUTPUT
,
923 "PostProcessPurifyTest for : "
924 << res
.Name
.c_str() << std::endl
);
925 if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile
.c_str()) )
927 std::string log
= "Cannot find memory tester output file: "
928 + this->MemoryTesterOutputFile
;
929 cmCTestLog(this->CTest
, ERROR_MESSAGE
, log
.c_str() << std::endl
);
932 std::ifstream
ifs(this->MemoryTesterOutputFile
.c_str());
935 std::string log
= "Cannot read memory tester output file: "
936 + this->MemoryTesterOutputFile
;
937 cmCTestLog(this->CTest
, ERROR_MESSAGE
, log
.c_str() << std::endl
);
941 while ( cmSystemTools::GetLineFromStream(ifs
, line
) )