|
Boost Users : |
Subject: Re: [Boost-users] Unable to catch exception using boost::asio
From: Alex Black (alex_at_[hidden])
Date: 2009-07-15 09:56:44
(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 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