Relevant part of the code snippet. The above code snippet results in generating the following error in Win VC 8 compiler during exit. Making the assertion pass in destructor fixes the crash. This error is observed only in the windows and it works fine in linux.
class BasicMathTest: public TestFixture
{
CPPUNIT_TEST_SUITE(BasicMathTest);
CPPUNIT_TEST(testAdd);
CPPUNIT_TEST(testMultiply);
CPPUNIT_TEST(testDivide);
CPPUNIT_TEST_SUITE_END();
class A
{
public:
~A()
{
CPPUNIT_ASSERT_MESSAGE( "BasicMath::Addition", 0 );
}
};
A ob;
public:
virtual void setUp( void );
virtual void tearDown( void );
void testAdd( void );
void testMultiply( void );
void testDivide( void );
private:
BasicMath *obj;
};
int main()
{
TestRunner testrunner;
Test *tests = TestFactoryRegistry::getRegistry().makeTest();
testrunner.addTest( tests );
testrunner.run( m_testResult );
m_outputter->write();
return !m_collector.wasSuccessful();
}
The constructor and the destructor of a TestFixture are not protected against exceptions. If you want to use assertions in this stage you'd need to change the code so you can move the code that uses assertions (throws an exception) into setUp/tearDown.
Actually it might not even terminate with an unhandled exception and instead crash because you might get a second exception while unwinding the stack. To separate the state for different tests the test fixture is wrapped into a functor and each test gets a new instance that is stored in a vector. This hows once more that it is nearly always a bad idea to throw an exception in a destructor.
Related
I would like my C++ code to stop running with proper object cleanup if a certain condition is met; in a constructor of a class.
class A {
public:
int somevar;
void fun() {
// something
}
};
class B {
public:
B() {
int possibility;
// some work
if (possibility == 1) {
// I want to end the program here
kill code;
}
}
};
int main() {
A a;
B b;
return 0;
}
How can I terminate my code at that point doing proper cleanup. It's known that, std::exit does not perform any sort of stack unwinding, and no alive object on the stack will call its respective destructor to perform cleanup. So std::exit is not a good idea.
You should throw an exception, when the constructor fails, like this:
B() {
if(somethingBadHappened)
{
throw myException();
}
}
Be sure to catch exceptions in main() and all thread entry functions.
Read more in Throwing exceptions from constructors. Read about Stack unwinding in How can I handle a destructor that fails.
It is not possible to perform just from a constructor. If you throw an exception then applications need to set up a proper exception handling code at entry points, because if you just thrown an exception that won't be handled then compiler is allowed to skip stack unwinding and cleanup.
If you don't want to use use exceptions, you can have an init method in class B that returns a return code:
class B {
public:
B(/*parameters that will be used by init*/) : ...
int init(); // actually initialize instance and return non 0 upon failure
}
I have a test class which contains SetUp() and TearDown(), with certain inputs and is run with a variety of different inputs. When certain inputs are used, an exception will be thrown within SetUp() rather than in the body. This is expected and though it is not strictly part of the test, I would prefer not to have to move my SetUp() code into the body of the test just for this specific instance. However, I can't find a way of catching the exception here. My code is similar to the following:
struct MyInputs {
int first_;
const char* second_;
const char* third_;
};
The test class is pretty standard gtest boilerplate:
class MyTestClass : public ::testing::TestWithParam<MyInputs> {
public:
virtual void SetUp();
virtual void TearDown() {};
// etc...
}
void MyTestClass::SetUp() {
// Do some stuff here using MyInputs.first_ which may throw
// a "thrown from here" exception
}
I have a standard test closure though it's irrelevant to the problem here really - it doesn't get this far.
TEST_P(MyTestClass,aSpecificTest) {
// ... some stuff ...
}
Then I create the loop with multiple inputs:
INSTANTIATE_TEST_CASE_P(MultipleTests,
MyTestClass,
::testing::Values( MyInputs( 1234, "ABC", "XXX"), // <-- No exception thrown
MyInputs( 5678, "DEF", "ZZZ") ) ); // <-- Exception thrown
When I run the code, I get the error:
C++ exception with description "thrown from here" thrown in SetUp().
when it hits the 'bad' input. Is there a way I can catch this and either ignore or set an EXPECT_ type clause? I realise that I can simply put a try/catch in the SetUp(), but was rather hoping that I could use EXPECT_THROW somewhere to incorporate into the test.
I wrote the simple app base on pjsip (pjsua2).
If I close my app when I have active calls I have memory access error in Endpoint::on_call_state(pjsua_call_id call_id, pjsip_event *e)
I try before closing do
Endpoint::instance().hangupAllCalls();
pj_thread_sleep(2000);
Some time 2 sec enough time for closing and app closed correctly, but some time doesn't.
What correct way to close the pjsua2 app?
And how waiting what all calls are hangup?
From my expirience of working with PJSUA2, the correct way to exit is to ensure that destructors of all calls are called before pj::Account destructor and desturctor for pj::Account is called before pj::Endpoint destructor.
In my applications I have integer calls counter and exit bool flag in pj::Account derived class like:
class MyAccount : public pj::Account
{
public:
...
void incrementCallsCount() { ++_callsCount; }
void decrementCallsCount() { --_callsCount; }
size_t getCallsCount() const { return _callsCount; }
...
void setWantExit(boot wantExitFlag) { _wantExitFlag = wantExitFlag; }
void onIncomingCall(pj::OnIncomingCallParam &prm)
{
if (_wantExitFlag)
return;
MyCall *call = MyCall::create(*this, prm.callId);
// Do your stuff with call:
// - add to map id->call
// - answer SIP 180 Ringing / SIP 200 OK
}
...
private:
std::atomic<size_t> _callsCount;
bool _wantExitFlag;
};
In constructor of pj::Call derived class I call incrementCallsCount() and in destructor I call decrementCallsCount() like:
class MyCall : public pj::Call
{
public:
typedef pj::Call base_class;
static MyCall *create(MyAccount &account, int callId)
{
return new MyCall(account, callId);
}
virtual void onCallState(pj::OnCallStateParam& prm)
{
pj::CallInfo ci = getInfo();
if (ci.state == PJSIP_INV_STATE_DISCONNECTED)
{
// You may call some onDisconnected() handler function here
delete this;
return;
}
}
...
private:
MyCall(MyAccount &account, int callId)
: base_class(account, callId)
, _myAccount(account)
{
_myAccount.incrementCallsCount();
}
virtual ~MyCall()
{
_myAccount.decrementCallsCount();
}
MyAccount &_myAccount;
};
Note that constructor and destructor declared as private, to ensure that users create calls by static fuction MyCall::create() only! MyCall class takes responsibility for memory management: call deleted only when PJSUA2 tells to delete call (PJSIP_INV_STATE_DISCONNECTED call state).
With this functions and classes in mind, if you just want to exit from application almost immediately, you should:
Stop creating MyCall in MyAccount by _myAccount.setWantExit(true). When pj::Call::onIncomingCall() function returns immediately, PJSUA2 hande this by executing hangup() for the call immediately.
call Endpoint::instance().hangupAllCalls()
wait until MyAccount::getCallsCount() will return 0
ensure MyAccount's destructor is called before Enpoint's destructor
exit application
Can we use the destructor of an exception as a place to put some clean-up code?
In this manner we may allow the client to control the finalization step as opposed to RAII.
Is this a good or a bad design?
Is this a correct solution in the context of OOP and C++?
I'm currently working on an asynchronous procedure which itself starts asynchronously multiple tasks.
The pattern looks as follows:
struct IAsyncResult
{
...
virtual void EndCall() const;
}
typedef std::shared_ptr<IAsyncResult> IAsyncResultPtr;
struct IAsyncTask
{
virtual IAsyncResultPtr BeginTask() = 0;
virtual void EndTask(IAsyncResultPtr async) const = 0;
}
class CompositeTask : public IAsyncTask
{
…
}
Unfortunately I’m unable to guarantee that each subtask’s BeginTask method will not fail. So it is possible that N-1 subtasks would start successfully and the Nth fail.
In general it is vital to be sure that no background tasks are running before the client’s code finishes. But sometimes the client doesn’t care if some tasks fail.
So my current solution involves a custom exception which is thrown from the CompositeTask’s BeginAsync method in case if one task failed to start. This allows a client to control the clean-up stage:
class composite_async_exception : public std::exception
{
std::vector<IAsyncResultPtr> successfully_started_tasks;
mutable bool manage_cleanup;
public:
composite_async_exception(std::vector<IAsyncResultPtr> const& _successfully_started_tasks)
: successfully_started_tasks(_successfully_started_tasks)
, manage_cleanup(true)
{
}
virtual ~composite_async_exception() throw()
{
if(!manage_cleanup)
return;
for( auto task = successfully_started_tasks.begin(); task != successfully_started_tasks.end(); ++task)
{
task->CancelTask();
}
}
void Giveup() const throw()
{
manage_cleanup = false;
}
};
And the client uses the code as shown:
try
{
compositeTask.BeginAsync();
}
catch(composite_async_exception const& ex)
{
//prevent the exception to cancel tasks
ex.Giveup();
// some handling
}
Are there some best practices to handle such a situation?
The exception is eligible to be copied, the destructor would be called multiple times then. In your case that seem not to be a problem.
Exception handling mechanism might stop your tasks by destroying temporary exception object aborting your tasks at throw point, not at handling one.
To verify this one should read standard, which I'm too lazy to do.
Googlemock is incorrectly reporting problem at test exit. What am I doing wrong? I have scoured the googlemock documentation, but there is no good complete example, and nothing describing the problem I am having.
The error I get is:
googlemocktest.cpp(53): ERROR: this mock object should be deleted but never is.
Its address is #0018FDC4.
ERROR: 1 leaked mock object found at program exit.
The code for a simple test is:
#include <string>
#include <iostream>
#include <memory>
#include "gmock/gmock.h"
class IBar
{
public:
virtual ~IBar() {}
virtual void b() = 0;
virtual int c(std::string) = 0;
};
class Foo
{
private:
IBar *bar_;
public:
Foo(IBar *bar);
int a();
};
Foo::Foo(IBar *bar)
: bar_(bar)
{
}
int Foo::a()
{
// bar_->b();
return bar_->c("hello");
}
class BarMock : public IBar
{
public:
MOCK_METHOD0(b, void());
MOCK_METHOD1(c, int(std::string));
};
using ::testing::Return;
void TestAFunctionInFoo()
{
try
{
BarMock barMock;
std::unique_ptr<Foo> newFoo(new Foo(&barMock));
EXPECT_CALL(barMock, b());
EXPECT_CALL(barMock, c("hello")).WillOnce(Return(42));
newFoo->a();
}
catch (std::exception& e)
{
std::cout << "Mock exception caught: " << e.what() << std::endl;
}
catch (...)
{
}
}
int main(int argc, char* argv[])
{
::testing::GTEST_FLAG(throw_on_failure) = true;
::testing::InitGoogleMock(&argc, &argv[0]);
TestAFunctionInFoo();
return 0;
}
I have verified with a debugger that IBar::~IBar() is indeed getting called. But I still get this error message. If I uncomment the call to IBar::b() in Foo::a(), then there is no test failure so the catch statement doesn't get called. IBar::~IBar() is called, but there is no error message indicating a mock object isn't deleted.
Thank you very, very much for your help!
It happens because you have enabled throw_on_failure flag - as it's mentioned in Google Mock ForDummies:
This approach has a catch: it makes Google Mock throw an exception from a mock object's destructor sometimes.
Since an exception is thrown from destructor, mock object is never fully deleted and framework complains about it when program ends.
The simplest solution to this problem is to use Google Test as unit testing framework and have throw_on_failure flag disabled (default state) - GTest automatically fails test if mock expectations are not met within.
If you cannot use Google Test because you're using another framework (e.g. CppUnit) you can rewrite your test body this way:
void TestAFunctionInFoo()
{
::testing::GTEST_FLAG(throw_on_failure) = true;
BarMock barMock;
try
{
std::unique_ptr<Foo> newFoo(new Foo(&barMock));
EXPECT_CALL(barMock, b());
EXPECT_CALL(barMock, c("hello")).WillOnce(Return(42));
newFoo->a();
::testing::Mock::VerifyAndClearExpectations(&barMock);
}
catch (std::exception& e)
{
// expectations failed - do whatever you want
}
::testing::GTEST_FLAG(throw_on_failure) = false;
}
VerifyAndClearExpectations(void*) checks if given mock expectations are met - if not and throw_on_failure flag is enabled it throws an exception.
This way your mock object will be destroyed properly, and you will still have an exception if something has gone wrong.
BTW: Avoid using catch (...) { } - it's generally bad idea, which in most cases proves poor code quality.