Discussion:
[asio-users] Segmentation Fault in Desctructor of io_service (only if building code as shared object)
Sandra Schreiner
2016-03-03 09:36:31 UTC
Permalink
Hello,

I'm using Boost::ASIO for TLS connections in my client and server application. Everything works fine as long as I build the AsioTLSServer Code together with the test application (one executable).
Unfortunately I experience a weird problem if I build the exactly same AsioTLSServer as a shared object and try to use it together with the test application (one executable with main and one .so with server) :
As a consequence of calling AsioTLSServer destructor at the end of the application a segmentation fault in boost::asio::detail::task_io_service::shutdown_service() occurs.
What i tested so far:
- use shared_ptr for sessions (in this case the segmentation fault occurs when entering instead of leaving ~AsioTLSServer )
- called io_service.stop() in~AsioTLSServer (but the service should be stopped at this point anyway because the sockets are closed)
- passed io_service from main application to AsioTLSServer instead of using a member variable + running io_service in separate thread from main method (as shown here http://stackoverflow.com/questions/27697973/shared-from-this-causing-bad-weak-ptr)
nothing of this helped to solve the segmentation fault in my shared object.
I also checked the compiler flags to see if anything is different from building the executable and the shared object, but they seemed the same (I can provide a diff of the cmake output if this helps).
What am I doing wrong? Maybe the order of the member variables causes the error (see code below)?

Many thanks in advance.

Sandra

int main(){
try {
AsioTLSServer s(8977);
std::cout << "Start: " << "\n";
s.start();
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "End Main: " << "\n";
}
catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; }
return 0;
}

-------------------------- AsioTLSServer ------------------------------
private:
boost::asio::io_service mIoService;
std::shared_ptr<boost::asio::ip::tcp::acceptor> mAcceptorPtr;
std::shared_ptr<boost::asio::ssl::context> mContextPtr;
std::shared_ptr<std::thread> mServerThreadPtr;
std::vector<AsioSession*> mSessions;

public:

void AsioTLSServer::start(){
std::lock_guard<std::mutex> lock(mStartMutex);
if(mStopped)
{
mStopped = false;
std::cout << "server start" << std::endl;
mAcceptorPtr.reset(new boost::asio::ip::tcp::acceptor(mIoService,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), mPort)));
accept();
std::cout << "start io_service thread" << std::endl;
mServerThreadPtr.reset(new std::thread([this](){
mIoService.reset();
mIoService.run();
}));
}
}

void AsioTLSServer::accept(){
std::cout << "accept enter" << std::endl;
AsioSession *new_session = new AsioSession(mIoService, *mContextPtr);
mSessions.push_back(new_session);
mAcceptorPtr->async_accept(new_session->socket(),
boost::bind(&AsioTLSServer::acceptCallback, this, new_session,
boost::asio::placeholders::error));
}

void AsioTLSServer::stop(){
std::lock_guard<std::mutex> lock(mStopMutex);
if(!mStopped){
mStopped = true;
std::cout << "server stop() " << "\n";
mAcceptorPtr->close();
for(AsioSession* ptr: mSessions){
if(ptr != nullptr){
delete ptr; //is closing tls and tcp socket
ptr = nullptr;
}
}
mSessions.clear();
}
joinThread();
}

AsioTLSServer::~AsioTLSServer(){
std::cout << "~server() " << "\n";
stop();
}



------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
asio-users mailing list
asio-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Sandra Schreiner
2016-03-04 11:46:42 UTC
Permalink
Hello,

Just for your information:

I solved the problem by following this guidance from the asio documentation:

"By default, Boost.Asio is a header-only library. However, some developers may prefer to build Boost.Asio using separately compiled source code. To do this, add #include <boost/asio/impl/src.hpp> to one (and only one) source file in a program, then build the program with BOOST_ASIO_SEPARATE_COMPILATION defined in the project/compiler settings. Alternatively, BOOST_ASIO_DYN_LINK may be defined to build a separately-compiled Boost.Asio as part of a shared library."

To be more precise: I used the BOOST_ASIO_DYN_LINK flag and included the implementation. Now all the strange behaviour in my shared library is gone.

Best regards,
Sandra
________________________________________
Von: Sandra Schreiner [***@stud.hs-kl.de]
Gesendet: Donnerstag, 3. März 2016 10:36
An: asio-***@lists.sourceforge.net
Betreff: [asio-users] Segmentation Fault in Desctructor of io_service (only if building code as shared object)

Hello,

I'm using Boost::ASIO for TLS connections in my client and server application. Everything works fine as long as I build the AsioTLSServer Code together with the test application (one executable).
Unfortunately I experience a weird problem if I build the exactly same AsioTLSServer as a shared object and try to use it together with the test application (one executable with main and one .so with server) :
As a consequence of calling AsioTLSServer destructor at the end of the application a segmentation fault in boost::asio::detail::task_io_service::shutdown_service() occurs.
What i tested so far:
- use shared_ptr for sessions (in this case the segmentation fault occurs when entering instead of leaving ~AsioTLSServer )
- called io_service.stop() in~AsioTLSServer (but the service should be stopped at this point anyway because the sockets are closed)
- passed io_service from main application to AsioTLSServer instead of using a member variable + running io_service in separate thread from main method (as shown here http://stackoverflow.com/questions/27697973/shared-from-this-causing-bad-weak-ptr)
nothing of this helped to solve the segmentation fault in my shared object.
I also checked the compiler flags to see if anything is different from building the executable and the shared object, but they seemed the same (I can provide a diff of the cmake output if this helps).
What am I doing wrong? Maybe the order of the member variables causes the error (see code below)?

Many thanks in advance.

Sandra

int main(){
try {
AsioTLSServer s(8977);
std::cout << "Start: " << "\n";
s.start();
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "End Main: " << "\n";
}
catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; }
return 0;
}

-------------------------- AsioTLSServer ------------------------------
private:
boost::asio::io_service mIoService;
std::shared_ptr<boost::asio::ip::tcp::acceptor> mAcceptorPtr;
std::shared_ptr<boost::asio::ssl::context> mContextPtr;
std::shared_ptr<std::thread> mServerThreadPtr;
std::vector<AsioSession*> mSessions;

public:

void AsioTLSServer::start(){
std::lock_guard<std::mutex> lock(mStartMutex);
if(mStopped)
{
mStopped = false;
std::cout << "server start" << std::endl;
mAcceptorPtr.reset(new boost::asio::ip::tcp::acceptor(mIoService,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), mPort)));
accept();
std::cout << "start io_service thread" << std::endl;
mServerThreadPtr.reset(new std::thread([this](){
mIoService.reset();
mIoService.run();
}));
}
}

void AsioTLSServer::accept(){
std::cout << "accept enter" << std::endl;
AsioSession *new_session = new AsioSession(mIoService, *mContextPtr);
mSessions.push_back(new_session);
mAcceptorPtr->async_accept(new_session->socket(),
boost::bind(&AsioTLSServer::acceptCallback, this, new_session,
boost::asio::placeholders::error));
}

void AsioTLSServer::stop(){
std::lock_guard<std::mutex> lock(mStopMutex);
if(!mStopped){
mStopped = true;
std::cout << "server stop() " << "\n";
mAcceptorPtr->close();
for(AsioSession* ptr: mSessions){
if(ptr != nullptr){
delete ptr; //is closing tls and tcp socket
ptr = nullptr;
}
}
mSessions.clear();
}
joinThread();
}

AsioTLSServer::~AsioTLSServer(){
std::cout << "~server() " << "\n";
stop();
}



------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
asio-users mailing list
asio-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio



------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
asio-users mailing list
asio-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio

Loading...