zaphoyd / websocketpp

C++ websocket client/server library
http://www.zaphoyd.com/websocketpp
Other
6.97k stars 1.97k forks source link

io_service::stop leaks memory #490

Open felixguendling opened 8 years ago

felixguendling commented 8 years ago

I'm currently using the 0.3.0-alpha3 version in different projects. It's working fine! Now I'm interested in supporting simple HTTP requests including request bodies. This functionality was added in 0.5.0.

In my projects I try to have a clean valgrind / Clang sanitizer statistic on shutdown. 0.3.0-alpha3 was clean in this sense. Unfortunately, the 0.6.0 version seems to "leak" memory. Probably it's not a repeated leak but it's polluting the valgrind statistic.

I tried to fix this but didn't find the exact reason for this leak. It seems that the initial connection that gets created when the server starts listening won't be freed. That's strange because it's memory-managed (shared pointer).

The following file contains the modified print_server.cpp (new: clean shutdown on SIGINT) and the valgrind output: report.txt

felixguendling commented 8 years ago

Any ideas or hints where to look?

zaphoyd commented 8 years ago

Short answer here is... use connection::close on existing connections and endpoint::stop_listening on the endpoint itself instead of endpoint::stop. Straight up stop forcibly stops a bunch of things in a way that bypasses most, if not all, of the cleanup routines.

At the moment, I would only recommend using endpoint::stop in conditions where you want to kill the entire program right now.

That said, supporting a io_service::stop operation while WebSocket++ is running on the io_service is something that should be done, so I'd like to leave this issue open to track it. My guess that the specific issue here is a circular dependency between a connection and itself that gets cleaned up by the standard connection closing procedures that don't get run when the WebSocket state machine is cut short. RAII/shared pointers cannot fix or prevent this issue directly.

zaphoyd commented 8 years ago

websocketpp::transport::asio::connection cached handlers (m_async_read_handler, lib::clear_function(m_async_write_handler, m_init_handler, m_read_handler, m_write_handler) are the likely culprits for the circular references.

xavigibert commented 8 years ago

I submitted a pull request https://github.com/zaphoyd/websocketpp/pull/525 which fixes this issue.

felixguendling commented 8 years ago

Thank you very much! I will have a look at this soon and probably upgrade to your version.