From 17d4d1730705b55fa10716c31c21f3e1e65d479c Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Mon, 9 Sep 2019 10:53:37 +0200 Subject: [PATCH] Avoid the Defer-Disconnect destructor pattern with Boost.Coroutines Exceptions in Disconnect() might be thrown (this has been reworked into error_code locally) which are swallowed inside the Destructor for being dangerous. On the other hand, swallowing them may corrupt the stack unwinding operation from the coroutine layer. The best is to avoid Defer inside lib/remote and call Disconnect() directly after breaking from other operations. refs #7351 refs #7431 --- lib/remote/apilistener.cpp | 5 ++++- lib/remote/httpserverconnection.cpp | 4 ++-- lib/remote/jsonrpcconnection.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index 661a4eaaf..5a2ca048c 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -553,7 +553,10 @@ void ApiListener::NewClientHandlerInternal(boost::asio::yield_context yc, const Defer shutDownIfNeeded ([&sslConn, &willBeShutDown, &yc]() { if (!willBeShutDown) { - sslConn.async_shutdown(yc); + // Ignore the error, but do not throw an exception being swallowed at all cost. + // https://github.com/Icinga/icinga2/issues/7351 + boost::system::error_code ec; + sslConn.async_shutdown(yc[ec]); } }); diff --git a/lib/remote/httpserverconnection.cpp b/lib/remote/httpserverconnection.cpp index 01b32f403..6052f923a 100644 --- a/lib/remote/httpserverconnection.cpp +++ b/lib/remote/httpserverconnection.cpp @@ -478,8 +478,6 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) namespace beast = boost::beast; namespace http = beast::http; - Defer disconnect ([this]() { Disconnect(); }); - try { beast::flat_buffer buf; @@ -563,6 +561,8 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) << "Unhandled exception while processing HTTP request: " << ex.what(); } } + + Disconnect(); } void HttpServerConnection::CheckLiveness(boost::asio::yield_context yc) diff --git a/lib/remote/jsonrpcconnection.cpp b/lib/remote/jsonrpcconnection.cpp index e63f1183a..e8279eac2 100644 --- a/lib/remote/jsonrpcconnection.cpp +++ b/lib/remote/jsonrpcconnection.cpp @@ -60,8 +60,6 @@ void JsonRpcConnection::Start() void JsonRpcConnection::HandleIncomingMessages(boost::asio::yield_context yc) { - Defer disconnect ([this]() { Disconnect(); }); - for (;;) { String message; @@ -97,12 +95,12 @@ void JsonRpcConnection::HandleIncomingMessages(boost::asio::yield_context yc) l_TaskStats.InsertValue(Utility::GetTime(), 1); } + + Disconnect(); } void JsonRpcConnection::WriteOutgoingMessages(boost::asio::yield_context yc) { - Defer disconnect ([this]() { Disconnect(); }); - Defer signalWriterDone ([this]() { m_WriterDone.Set(); }); do { @@ -136,6 +134,8 @@ void JsonRpcConnection::WriteOutgoingMessages(boost::asio::yield_context yc) } } } while (!m_ShuttingDown); + + Disconnect(); } double JsonRpcConnection::GetTimestamp() const -- 2.40.0