Boost logo

Boost Users :

Subject: Re: [Boost-users] Unable to catch exception using boost::asio
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-07-15 14:05:24


On Wed, Jul 15, 2009 at 12:10 PM, Alex Black<alex_at_[hidden]> wrote:
>
>>
>> Message: 3
>> Date: Wed, 15 Jul 2009 10:56:22 -0500
>> From: Zachary Turner <divisortheory_at_[hidden]>
>> Subject: Re: [Boost-users] Unable to catch exception using boost::asio
>> To: boost-users_at_[hidden]
>> Message-ID:
>>       <478231340907150856x12c9fd92w3b06630d349eef36_at_[hidden]>
>> Content-Type: text/plain; charset=ISO-8859-1
>>
>> > I wrapped my call to run() in a try-catch, no luck, no exception
>> > appears to be being thrown by io_service.run().
>> >
>> > void CBaseWebServer::RunIoService()
>> > {
>> > ? ? ? ?try
>> > ? ? ? ?{
>> > ? ? ? ? ? ? ? ?m_IoService.run();
>> > ? ? ? ?}
>> > ? ? ? ?catch ( ... )
>> > ? ? ? ?{
>> > ? ? ? ? ? ? ? ?cout << "Unhandled exception in
>> RunIoService"; ? ? ? ?}
>> > } _______________________________________________
>> > Boost-users mailing list
>> > Boost-users_at_[hidden]
>> > http://lists.boost.org/mailman/listinfo.cgi/boost-users
>> >
>>
>>
>> That probably won't help.  Notice that
>> CBaseWebServer::RunIoService() is not in the call stack at
>> the point you're seeing the exception.
>> After looking at your callstack again, I believe you're
>> throwing from a destructor.  In particular, notice in your
>> callstack that you have
>> this:
>>
>> 26 ~ProtoBufStreamAdaptor() /home/noirs/workspace/myfile2.cpp:10
>> 0x000000000042c6e5
>> 25 CWebServer::HandleGetNeighbors()
>> /home/noirs/workspace/myfile3.cpp:215 0x000000000041d2d8
>>
>>
>> These appear to both be in your own code.  My suspicion is
>> that an exception occurs in CWebServer::HandleGetNeighbors(),
>> which causes it to unwind the stack and execute destructors.
>> In particular a destructor for an object of type
>> ProtoBufStreamAdaptor() is called, and this destructor then
>> throws another exception.  At this point your program will
>> definitely terminate immediately.
>>
>> First check the destructor of ProtoBufStreamAdaptor() to see
>> why it's throwing (destructors should _never_ throw under any
>> circumstances), and then check the code of
>> CWebServer::HandleGetNeighbors() to find the original error.
>
> 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.

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<boost::exception_detail::error_info_injector<boost::system::system_error>'.
 So put a breakpoint inside the constructor of
boost::exception_detail::clone_impl and presumably your breakpoint
should get hit at the moment the exception is thrown, and you'll have
a callstack of the offending code.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net