[Bug] Memory leak on `Poco::Net::SecureStreamSocket`
Author: ghostCreated Oct 5, 2023Updated Sep 3, 2026
Labelsbug
Hi,
I triggered a memory leak with Valgrind when I use this Poco::Net::SecureStreamSocketImpl constructor.
Here follows a sample of code that reproduces the leak:
#include <Poco/Net/Context.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/SecureStreamSocket.h>
#include <Poco/Net/SecureStreamSocketImpl.h>
#include <Poco/Net/StreamSocketImpl.h>
#include <cstdlib>
#include <iostream>
class MyStreamSocketImpl : public Poco::Net::StreamSocketImpl
{
public:
virtual void init(int af) override
{
Poco::Net::StreamSocketImpl::init(af);
// Do specific stuff. This is where I need to execute some specific code
}
};
class MySecureStreamSocketImpl : public Poco::Net::SecureStreamSocketImpl
{
public:
MySecureStreamSocketImpl(Poco::Net::Context::Ptr ctx) : Poco::Net::SecureStreamSocketImpl(new MyStreamSocketImpl(), ctx) {}
};
class MySecureStreamSocket : public Poco::Net::SecureStreamSocket
{
public:
MySecureStreamSocket(Poco::Net::Context::Ptr ctx) : Poco::Net::SecureStreamSocket(new MySecureStreamSocketImpl(ctx)) {}
};
int main()
{
Poco::Net::Context::Ptr context(new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE));
MySecureStreamSocket socket(context);
Poco::Net::HTTPSClientSession session(socket);
session.setHost("www.google.com");
session.setPort(443);
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, "/");
session.sendRequest(req);
Poco::Net::HTTPResponse res;
std::istream &rs = session.receiveResponse(res);
std::cout << res.getStatus() << ": " << res.getReason() << std::endl;
return EXIT_SUCCESS;
}Is it just a wrong usage of the library? I think not, because the first constructor does not have the same behavior and I don't understand why it would be like this.
I built it with the following CMake file :
cmake_minimum_required(VERSION 3.13)
project(poco)
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
set(CMAKE_CXX_STANDARD 20)
find_package(Poco REQUIRED Net NetSSL Util)
add_executable(main main.cpp)
target_link_libraries(main Poco::Net)
target_link_libraries(main Poco::NetSSL)
target_link_libraries(main Poco::Util)Here is the Valgrind output:
$ valgrind --leak-check=full --show-leak-kinds=all build/main
==441986== Memcheck, a memory error detector
==441986== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==441986== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==441986== Command: build/main
==441986==
200: OK
==441986==
==441986== HEAP SUMMARY:
==441986== in use at exit: 40 bytes in 1 blocks
==441986== total heap usage: 16,967 allocs, 16,966 frees, 2,106,698 bytes allocated
==441986==
==441986== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==441986== at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==441986== by 0x10E06A: MySecureStreamSocketImpl::MySecureStreamSocketImpl(Poco::AutoPtr<Poco::Net::Context>) (in /home/pgagelin/workspace/tp-9182/poco-test/build/main)
==441986== by 0x10E179: MySecureStreamSocket::MySecureStreamSocket(Poco::AutoPtr<Poco::Net::Context>) (in /home/pgagelin/workspace/tp-9182/poco-test/build/main)
==441986== by 0x10D860: main (in /home/pgagelin/workspace/tp-9182/poco-test/build/main)
==441986==
==441986== LEAK SUMMARY:
==441986== definitely lost: 40 bytes in 1 blocks
==441986== indirectly lost: 0 bytes in 0 blocks
==441986== possibly lost: 0 bytes in 0 blocks
==441986== still reachable: 0 bytes in 0 blocks
==441986== suppressed: 0 bytes in 0 blocks
==441986==
==441986== For lists of detected and suppressed errors, rerun with: -s
==441986== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)I already opened a pull request with a fix as #4145. The proposed fix raises sanitizers issues, I guess it's not made to be used this way but I don't know how to do it differently
Source: pocoproject/poco