With the MP attached to this bug, the leaks are gone, except for a spurious one on shutdown that can be attributed to CURL. Quoting from the original MP discussion here:
Running the load test in a loop, after maybe a hundred iterations or so, I got a valgrind complaint:
==29504==
==29504== HEAP SUMMARY:
==29504== in use at exit: 161,360 bytes in 1,769 blocks
==29504== total heap usage: 325,601 allocs, 323,832 frees, 54,917,164 bytes allocated
==29504==
==29504== 161,296 (73 direct, 161,223 indirect) bytes in 1 blocks are definitely lost in loss record 64 of 64
==29504== at 0x4C2B100: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29504== by 0x4E8A699: boost::asio::detail::thread_info_base::allocate(boost::asio::detail::thread_info_base*, unsigned long) (thread_info_base.hpp:60)
==29504== by 0x4E8A7A8: boost::asio::asio_handler_allocate(unsigned long, ...) (handler_alloc_hook.ipp:50)
==29504== by 0x4E883DE: void* boost_asio_handler_alloc_helpers::allocate<curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}>(unsigned long, curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}&) (handler_alloc_helpers.hpp:37)
==29504== by 0x4E87F56: void boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime> >::async_wait<curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}>(boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime> >::implementation_type&, curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}&) (deadline_timer_service.hpp:185)
==29504== by 0x4E87CA1: boost::asio::async_result<boost::asio::handler_type<curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}, void (boost::system::error_code)>::type>::type boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> >::async_wait<curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}>(boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime> >::implementation_type&, boost::asio::handler_type&&) (deadline_timer_service.hpp:149)
==29504== by 0x4E87B93: boost::asio::async_result<boost::asio::handler_type<curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}, void (boost::system::error_code)>::type>::type boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >::async_wait<curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&)::{lambda(boost::system::error_code const&)#1}>(boost::asio::handler_type&&) (basic_deadline_timer.hpp:508)
==29504== by 0x4E86A33: curl::multi::Handle::Private::Timeout::Private::async_wait_for(std::weak_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&) (multi.cpp:402)
==29504== by 0x4E86730: curl::multi::Handle::Private::Timeout::async_wait_for(std::shared_ptr<curl::multi::Handle::Private> const&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&) (multi.cpp:371)
==29504== by 0x4E86C13: curl::multi::Handle::Private::timer_callback(void*, long, void*) (multi.cpp:436)
==29504== by 0x656F204: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==29504== by 0x6570C19: curl_multi_remove_handle (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==29504==
==29504== LEAK SUMMARY:
==29504== definitely lost: 73 bytes in 1 blocks
==29504== indirectly lost: 161,223 bytes in 1,766 blocks
==29504== possibly lost: 0 bytes in 0 blocks
==29504== still reachable: 64 bytes in 2 blocks
==29504== suppressed: 0 bytes in 0 blocks
==29504== Reachable blocks (those to which a pointer was found) are not shown.
==29504== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==29504==
==29504== For counts of detected and suppressed errors, rerun with: -v
==29504== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
With the MP attached to this bug, the leaks are gone, except for a spurious one on shutdown that can be attributed to CURL. Quoting from the original MP discussion here:
Running the load test in a loop, after maybe a hundred iterations or so, I got a valgrind complaint:
==29504== valgrind/ vgpreload_ memcheck- amd64-linux. so) asio::detail: :thread_ info_base: :allocate( boost:: asio::detail: :thread_ info_base* , unsigned long) (thread_ info_base. hpp:60) asio::asio_ handler_ allocate( unsigned long, ...) (handler_ alloc_hook. ipp:50) handler_ alloc_helpers: :allocate< curl::multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&) #1}>(unsigned long, curl::multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&)#1}&) (handler_ alloc_helpers. hpp:37) asio::detail: :deadline_ timer_service< boost:: asio::time_ traits< boost:: posix_time: :ptime> >::async_ wait<curl: :multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&) #1}>(boost: :asio:: detail: :deadline_ timer_service< boost:: asio::time_ traits< boost:: posix_time: :ptime> >::implementati on_type& , curl::multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&)#1}&) (deadline_ timer_service. hpp:185) asio::async_ result< boost:: asio::handler_ type<curl: :multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&)#1}, void (boost: :system: :error_ code)>: :type>: :type boost:: asio::deadline_ timer_service< boost:: posix_time: :ptime, boost:: asio::time_ traits< boost:: posix_time: :ptime> >::async_ wait<curl: :multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&) #1}>(boost: :asio:: detail: :deadline_ timer_service< boost:: asio::time_ traits< boost:: posix_time: :ptime> >::implementati on_type& , boost:: asio::handler_ type&&) (deadline_ timer_service. hpp:149) asio::async_ result< boost:: asio::handler_ type<curl: :multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&)#1}, void (boost: :system: :error_ code)>: :type>: :type boost:: asio::basic_ deadline_ timer<boost: :posix_ time::ptime, boost:: asio::time_ traits< boost:: posix_time: :ptime> , boost:: asio::deadline_ timer_service< boost:: posix_time: :ptime, boost:: asio::time_ traits< boost:: posix_time: :ptime> > >::async_ wait<curl: :multi: :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) ::{lambda( boost:: system: :error_ code const&) #1}>(boost: :asio:: handler_ type&&) (basic_ deadline_ timer.hpp: 508) :Handle: :Private: :Timeout: :Private: :async_ wait_for( std::weak_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) (multi.cpp:402) :Handle: :Private: :Timeout: :async_ wait_for( std::shared_ ptr<curl: :multi: :Handle: :Private> const&, std::chrono: :duration< long, std::ratio<1l, 1000l> > const&) (multi.cpp:371) :Handle: :Private: :timer_ callback( void*, long, void*) (multi.cpp:436) x86_64- linux-gnu/ libcurl. so.4.3. 0) remove_ handle (in /usr/lib/ x86_64- linux-gnu/ libcurl. so.4.3. 0) leak-kinds= all
==29504== HEAP SUMMARY:
==29504== in use at exit: 161,360 bytes in 1,769 blocks
==29504== total heap usage: 325,601 allocs, 323,832 frees, 54,917,164 bytes allocated
==29504==
==29504== 161,296 (73 direct, 161,223 indirect) bytes in 1 blocks are definitely lost in loss record 64 of 64
==29504== at 0x4C2B100: operator new(unsigned long) (in /usr/lib/
==29504== by 0x4E8A699: boost::
==29504== by 0x4E8A7A8: boost::
==29504== by 0x4E883DE: void* boost_asio_
==29504== by 0x4E87F56: void boost::
==29504== by 0x4E87CA1: boost::
==29504== by 0x4E87B93: boost::
==29504== by 0x4E86A33: curl::multi:
==29504== by 0x4E86730: curl::multi:
==29504== by 0x4E86C13: curl::multi:
==29504== by 0x656F204: ??? (in /usr/lib/
==29504== by 0x6570C19: curl_multi_
==29504==
==29504== LEAK SUMMARY:
==29504== definitely lost: 73 bytes in 1 blocks
==29504== indirectly lost: 161,223 bytes in 1,766 blocks
==29504== possibly lost: 0 bytes in 0 blocks
==29504== still reachable: 64 bytes in 2 blocks
==29504== suppressed: 0 bytes in 0 blocks
==29504== Reachable blocks (those to which a pointer was found) are not shown.
==29504== To see them, rerun with: --leak-check=full --show-
==29504==
==29504== For counts of detected and suppressed errors, rerun with: -v
==29504== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)