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

(Response is below)
On Tue, Jul 14, 2009 at 7:49 PM, Alex Black<alex@alexblack.ca> 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; } }

Alex Black wrote:
(Response is below)
On Tue, Jul 14, 2009 at 7:49 PM, Alex Black<alex@alexblack.ca> 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@lists.boost.org 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().
participants (2)
-
Alex Black
-
Etienne Philip Pretorius