Re: [Boost-users] Unable to catch exception using boost::asio

Thanks for continuing to help with this. I had the same thoughts as you, and I've looked into that with no luck. For example, here is the code for ~ProtoBufStreamAdaptor(): ProtoBufStreamAdaptor::~ProtoBufStreamAdaptor(void) {} The original error is related to the client (on the other end of the socket) being interrupted. Presumably some socket operation is throwing an exception, e.g. I'm writing to the socket after the client has disconnected. You mentioned never throwing exceptions in destructors - sounds like good advice, thx. Two points though: 1. If an exception is thrown in a destructor can it not be caught with a try catch( ... )? 2. I'll look over the code more closely and see if there are any destructors throwing.

On Wed, Jul 15, 2009 at 10:10 AM, Alex Black
If a destructor calls functions that may throw, it should use catch(...) and not let exceptions propagate out of the destructor itself. However, when writing or sending data, the user may want to know that the operation has completed successfully. Typically, you'd provide a separate flush function for that use case, which you'd then call in the destructor, as in: foo_sender::~foo_sender() { try { flush(); } catch(...) { } } Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

So when my app crashes, here is the message I see on the console: (if I
don't have a set_terminate handler installed)
terminate called after throwing an instance of
'boost::exception_detail::clone_impl

On Wed, Jul 15, 2009 at 12:10 PM, Alex Black
Since it looks like the callstack is perfectly fine up until something
that happens in HandleGetNeighbors(), perhaps you could put a
breakpoint at the very first line of HandleGetNeighbors() and single
step until something bad happens. I'm not familiar with your code
enough to be able to say for sure, but just because
ProtoBufStreamAdaptor's destructor is empty doesn't mean it's not
throwing. Does it contain members that are also structures, whose
destructors might throw? For example:
struct ProtoBufStreamAdaptor
{
~ProtoBufStreamAdaptor() {}
shared_ptr<blah> blah_;
};
Now even though this has an empty destructor, if it turns out that
blah_ is actually the last shared reference to the instance, it will
invoke blah::~blah(). This can't throw either.
Some debuggers provide mechanisms so that you can stop at the exact
point an exception is thrown, rather than where it is handled. You
might try that as well. If your debugger doesn't support this
natively, then you might be able to achieve the same thing by noting
that the exception claims to be of type
'boost::exception_detail::clone_impl

Good call. Yes, ProtoBufStreamAdaptor has members which may have destructors that throw (e.g. they're not my code, it has one member which is a google protocol buffer class). If it's a 3rd party class that is throwing in its destructor, can I handle that safely? Oh, I guess I can release the pointer in my destructor surrounded by a try-catch... I'm using Eclipse-CDT, and it doesn't have a way to tell GDB to stop on an exception (I'm used to using Visual Studio which does have this feature). Setting a breakpoint on that constructor sounds like a good idea, should have thought of that. Thx. - Alex

Thanks, that fixed it! My destructor now looks like this: try { m_pProtoBufStream.reset(); } catch ( std::exception& e ) { cout << endl << "Unexpected exception in ProtoBufStreamAdaptor::~ProtoBufStreamAdaptor: " << e.what() << endl; } catch ( ... ) { cout << endl << "Unexpected exception in ProtoBufStreamAdaptor::~ProtoBufStreamAdaptor" << endl; } And it does indeed catch an exception. Now my process doesn't die. - Alex

On Wed, Jul 15, 2009 at 11:31 AM, Alex Black
I'd replace this with:
try
{
m_pProtoBufStream.reset();
}
catch ( ... )
{
cout << endl << "Unexpected exception caught in " <<
BOOST_CURRENT_FUNCTION << endl <<
boost::current_exception_diagnostic_information();
}
(you'd need to #include

On Wed, Jul 15, 2009 at 11:05 AM, Zachary Turner
If the exception that's emitted is a Boost exception, you can intercept it before it is thrown by setting a break point in boost::throw_exception(). Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
participants (3)
-
Alex Black
-
Emil Dotchevski
-
Zachary Turner