Thread: [Cppunit-devel] Partial answer: 2.3) Why does the test ExceptionTest.testAssignment failed in CppUni
Brought to you by:
blep
From: Phil T. <phi...@ts...> - 2001-10-04 12:57:22
|
The implementation of the assignment operator for std::exception in MSVCRT seems to be cause of the problem. Comment out the SuperClass::operator= (other) call in Exception::operator=(Exception&) and the test now passes. Examination of MSVCRT disassembly yields some odd-looking (shortcut?) behavior. It looks as though exception::operator=(exception&) resets itself by calling its own destructor (memory is not freed) then calls exception(exception&) to complete the assignment. I can't progress the problem any further at this time but the information above may be of some assistance. Regards, Phil |
From: Baptiste L. <bl...@cl...> - 2001-10-06 08:22:50
|
Thanks for pointing that out Phil. I went a little further, and while the operator =() does weird stuff it does the job. When checkIsSame() is called, members of the original and assigned exception are equal (m_message members that are used by CppUnit::Exception::what() have the same value). I tracked down the problem, and it occurs in checkIsSame(): void ExceptionTest::checkIsSame( CppUnit::Exception &e, CppUnit::Exception &other ) { std::string eWhat( e.what() ); std::string otherWhat( other.what() ); --- 004054DA mov esi,esp 004054DC lea eax,[ebp-38h] 004054DF push eax 004054E0 mov ecx,dword ptr [ebp+0Ch] 004054E3 mov edx,dword ptr [ecx] 004054E5 mov edi,esp 004054E7 mov ecx,dword ptr [ebp+0Ch] 004054EA call dword ptr [edx+4] // here std::exception::what() is called instead of CppUnit::Exception::what() which returns the m_message member. // The weird stuff is that e.what() does call CppUnit::Exception::what() correctly... --- CPPUNIT_ASSERT_EQUAL( eWhat, otherWhat ); CPPUNIT_ASSERT( e.sourceLine() == other.sourceLine() ); } No matter how I twist think around, for other, it is always std::exception::what() that is called ! // Inverting the order of initialisation doesn't change a thing... const char *otherWhat = other.what(); const char *eWhat = e.what(); CPPUNIT_ASSERT_EQUAL( std::string(eWhat), std::string(otherWhat) ); Any idea ? Baptiste. ----- Original Message ----- From: "Phil Taylor" <phi...@ts...> To: <cpp...@li...> Sent: Thursday, October 04, 2001 2:57 PM Subject: [Cppunit-devel] Partial answer: 2.3) Why does the test ExceptionTest.testAssignment failed in CppUnit test > The implementation of the assignment operator for std::exception in > MSVCRT seems to be cause of the problem. Comment out the > SuperClass::operator= (other) call in Exception::operator=(Exception&) > and the test now passes. > > Examination of MSVCRT disassembly yields some odd-looking (shortcut?) > behavior. It looks as though exception::operator=(exception&) resets > itself by calling its own destructor (memory is not freed) then calls > exception(exception&) to complete the assignment. > > I can't progress the problem any further at this time but the > information above may be of some assistance. > > Regards, > Phil > > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppunit-devel > |
From: Baptiste L. <bl...@cl...> - 2001-10-06 10:15:21
|
Went one step further in that quest... When the std::exception::operator =() call the destructor and the constructor to do the 'copy', the constructor reset the virtual table back to std::exception virtual table. Therefore, the previous affectation to CppUnit::Exception virtual table is lost, and all call to any virtual function of std::exception (what() is among them) will lead to a call to the std::exception implementatin instead of the most derived class implementation. I beleive this is a MSVC++ STL bug (I'll tell you, that stuff is pure black magic ;-) ). Has anyone heard of it ? Well, anyway I'll go for the simplest thing that could possibly work and comment out the call to std::exception::operator =() in CppUnit::Exception::operator =() (no data from the base class are use anyway). But at least, now we know what is going wrong ! And we finaly got to see the green bar =) Thanks Phil, Baptiste. ----- Original Message ----- From: "Phil Taylor" <phi...@ts...> To: <cpp...@li...> Sent: Thursday, October 04, 2001 2:57 PM Subject: [Cppunit-devel] Partial answer: 2.3) Why does the test ExceptionTest.testAssignment failed in CppUnit test > The implementation of the assignment operator for std::exception in > MSVCRT seems to be cause of the problem. Comment out the > SuperClass::operator= (other) call in Exception::operator=(Exception&) > and the test now passes. > > Examination of MSVCRT disassembly yields some odd-looking (shortcut?) > behavior. It looks as though exception::operator=(exception&) resets > itself by calling its own destructor (memory is not freed) then calls > exception(exception&) to complete the assignment. > > I can't progress the problem any further at this time but the > information above may be of some assistance. > > Regards, > Phil > > > _______________________________________________ > Cppunit-devel mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppunit-devel > |
From: Baptiste L. <gai...@fr...> - 2001-10-08 12:36:44
|
Quoting Baptiste Lepilleur <bl...@cl...>: It does raise an interesting point about testing in C++. Exception::operator = () test failed, but NotEqualException::operator =() test worked!!! NotEqualException compared the values in the same method where the object were declared, while Exception called an helper method to do the job, passing reference to the Exception objects. That means that in the case of NotEqualException, the compiler knew the actual type of the object and resolved the virtual method call statically. That same test would have failed if the comparison was done in an helper function, since std::exception::operator =() implementation is bugged, leading to a buggy implementation of Exception::operator =(). So we had a passing test that should have failed, but did not because the compiler optimized away the resolution of the virtual call. Disturbing, isn't it ? That does raise interesting question about testing components that subclass third party class. Baptiste. > Went one step further in that quest... > > When the std::exception::operator =() call the destructor and the > constructor to do the 'copy', the constructor reset the virtual table > back > to std::exception > virtual table. Therefore, the previous affectation to > CppUnit::Exception > virtual table is lost, and all call to any virtual function of > std::exception (what() is among them) will lead to a call to the > std::exception implementatin instead of the most derived class > implementation. > > I beleive this is a MSVC++ STL bug (I'll tell you, that stuff is pure > black > magic ;-) ). Has anyone heard of it ? > > Well, anyway I'll go for the simplest thing that could possibly work > and > comment out the call to std::exception::operator =() in > CppUnit::Exception::operator =() (no data from the base class are use > anyway). But at least, now we know what is going wrong ! > > And we finaly got to see the green bar =) > > Thanks Phil, > Baptiste. --- Baptiste Lepilleur <gai...@fr...> http://gaiacrtn.free.fr/index.html Language: English, French |