Boost logo

Boost Users :

Subject: Re: [Boost-users] Unable to catch exception using boost::asio
From: Alex Black (alex_at_[hidden])
Date: 2009-07-15 11:22:09


(Response below)

>
> 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().

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 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