Boost logo

Boost Users :

Subject: Re: [Boost-users] Unable to catch exception using boost::asio
From: Etienne Philip Pretorius (icewolfhunter_at_[hidden])
Date: 2009-07-15 10:04:38


Alex Black wrote:
> (Response is below)
>
>
>> On Tue, Jul 14, 2009 at 7:49 PM, Alex Black<alex_at_[hidden]> wrote:
>>>>> I'm using boost::asio for sockets, writing a response out to a
>>> client.
>>>>> If the client stops part way through getting the
>> response, then my
>>>>> server process dies:
>>>>>
>>>>> terminate called after throwing an instance of
>>>>>
>> 'boost::exception_detail::clone_impl<boost::exception_detail::error_in
>>>>> fo_injector<boost::system::system_error>
>>>>>> '
>>>>> ? what():? Broken pipe
>>>>>
>>>>> The code though is surrounded by try catch like this:
>>>>>
>>>>> try
>>>>> {
>>>>> ??? ...
>>>>> }
>>>>> catch ( std::exception& e )
>>>>> {
>>>>> ??? cout << e.what() << endl;
>>>>> }
>>>>> catch ( ... )
>>>>> {
>>>>> ???? cout << "unexpected exception" << endl; }
>>>>>
>>>>> How do I prevent my process from aborting/terminating like this?
>>> v
>>>
>>>> Have you verified that the code inside the try block executes on the
>>> same thread that the exception is occuring in?
>>>
>>> Not explicitly, how would I do that?
>>>
>>> thx
>>>
>> First put a breakpoint inside the try block. When it gets
>> hit use whatever mechanism your debugger provides to see what
>> thread you're in. In windows using MSVC, for example, you'd
>> just add a watch for a variable called $TID which a special
>> pseudo-variable that shows you the thread id. For other
>> debuggers you'd have to consult the manual.
>> Next register an unhandled exception handler.
>>
>> #include <exception>
>>
>> void unhandled_exception_handler()
>> {
>> std::cout << "Got an unhandled exception!" << std::endl; }
>>
>> int main(int argc, char** argv)
>> {
>> std::set_terminate(unhandled_exception_handler);
>>
>> //rest of your program.
>> }
>>
>> Then put a breakpoint inside unhandled_exception_handler and
>> when it gets hit walk up the callstack in the debugger to see
>> where the exception is occuring. In addition you can
>> determine the thread id again using the same method you used
>> in the first step. My guess is that they're not in the same
>> thread. I'm not sure if it applies to your scenario, but
>> remember that the operation's completion handler is invoked
>> on is not necessarily the same thread that the request is
>> issued on depending on how you're using the io_service
>> object. So while you have a try {} catch(...) {} in the
>> completion handler, if the exception is on the other thread
>> that does you no good.
>>
>
> Thanks for the tip, I didn't know about set_terminate, I made that
> change.
>
> I put a breakpoint in my terminate handler, and the callstack looks
> like:
>
> 32 unhandled_exception_handler() /home/noirs/workspace/myfile.cpp:35
> 0x0000000000438764
> 31 <symbol is not available> 0x00007f9ceb0d04b6
> 30 <symbol is not available> 0x00007f9ceb0cf6ab
> 29 __gxx_personality_v0() 0x00007f9ceb0d0278
> 28 <symbol is not available> 0x00007f9ceab7cff3
> 27 _Unwind_Resume() 0x00007f9ceab7d0b8
> 26 ~ProtoBufStreamAdaptor() /home/noirs/workspace/myfile2.cpp:10
> 0x000000000042c6e5
> 25 CWebServer::HandleGetNeighbors()
> /home/noirs/workspace/myfile3.cpp:215 0x000000000041d2d8
> 24 CWebServer::OnHttpRequest() /home/noirs/workspace/myfile3.cpp:89
> 0x000000000041e790
> 23 CBaseWebServer::HandleHTTPRequest()
> /home/noirs/workspace/myfile4.cpp:92 0x00000000004092ef
> 22 CBaseWebServer::HandleAccept() /home/noirs/workspace/myfile4.cpp:61
> 0x0000000000409a9e
>
> HandleAccept looks like:
>
> void CBaseWebServer::HandleAccept(shared_ptr<tcp::socket> pSocket, const
> boost::system::error_code& error)
> { if ( !error )
> {
> try
> {
> HandleHTTPRequest(pSocket);
>
> StartAccept();
> }
> catch ( ... )
> {
> cout << "Unhandled exception in HandleAccept";
> }
> }
> else
> {
> cout << "HandleAccept received error: " <<
> error.message().c_str() << endl;
> }
> }
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users

Um, broken pipe = closed file desciptor.

Check if the socket is actually valid in the shard_ptr...

BTW, are you using Async operations.... if so then the exception will
not originate from your code but from io_service.run().


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