Overview
Features
Download
Documentation
Community
Add-Ons & Services

HTTP Server and memory leak

Please post support and help requests here.

HTTP Server and memory leak

Postby helthans » 12 Jun 2014, 15:23

I have implemented a HTTP server in an Qt project. The only problem is that it also gives me a memory leak. I cannot really grasp why I get this memory leak and obviously don't know how to change my code such it doesn't leak.
I have run valgrind and it points to the following line in my code (shown in boldface):

m_server = new Poco::Net::HTTPServer(new RequestHandlerFactory,
Poco::Net::ServerSocket(addr),
new Poco::Net::HTTPServerParams);

Can anyone please guide me how to solve this issue???

Below is the header file:
Code: Select all
#ifndef POCOWEBSERVERMODULE_POCOWEBSERVERPLUGIN_H
#define POCOWEBSERVERMODULE_POCOWEBSERVERPLUGIN_H

#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/NetException.h"
#include <QObject>
#include <QDateTime>
#include <QNetworkInterface>

class PocoWebServerPlugin: public QObject
{
    Q_OBJECT
    Q_INTERFACES(PocoWebServerModule::PocoWebServerInterface)
    Q_INTERFACES(LibBeat::PlayerPlugin)
    Q_PLUGIN_METADATA(IID "dk.beatpro.Plugin.PocoWebServer")

public:
    explicit PocoWebServerPlugin(QObject *parent = 0);
    ~PocoWebServerPlugin();

    bool initialize();

private:
    Poco::Net::HTTPServer *m_server;
    QString ipAddress();
};



And the source code:
Code: Select all
PocoWebServerPlugin::PocoWebServerPlugin(QObject *parent) :
    QObject(parent)
{
    m_server = 0;
}

bool PocoWebServerPlugin::initialize()
{
    QString ipA = PocoWebServerPlugin::ipAddress();

    Poco::Net::SocketAddress addr(ipA.toStdString(),8080);
    try {
        m_server = new Poco::Net::HTTPServer(new RequestHandlerFactory,
                                                Poco::Net::ServerSocket(addr),
                                             new Poco::Net::HTTPServerParams);

        m_server->start();

    }
    catch (std::exception e) {
        qDebug() << "Could not start server.";
    }
    qDebug() << Q_FUNC_INFO << "Listening at " << QString::fromStdString(addr.toString());
    logMessageM(LogModule::Information, "POCO Web server plugin initialized");
    return true;
}

QString PocoWebServerPlugin::ipAddress()
{
    QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();

    QHostAddress ipAddr; // By default is null address

    for (int i=0; i<ifaces.size(); i++) {

        unsigned int flags = ifaces[i].flags();
        bool isRunning = (bool)(flags & QNetworkInterface::IsRunning);
        bool isP2P = (bool)(flags & QNetworkInterface::IsPointToPoint);
        bool isLoopBack = (bool)(flags & QNetworkInterface::IsLoopBack);
        if (!isRunning) // ignore if not running
            continue;

        if (!ifaces[i].isValid() || isLoopBack || isP2P) // only valid which are not loop-back or P2P
            continue;

        QList<QHostAddress> addresses = ifaces[i].allAddresses();
        for (int j=0; j<addresses.size(); j++) {
            if (!addresses[j].toIPv4Address()) // ignore if non-IP4
                continue;
            if(addresses[j].isLoopback())
                continue;
            if (!addresses[j].isInSubnet(QHostAddress::parseSubnet("10.0.0.0/24")))
                continue;
            ipAddr = addresses[j];
            break;
        }
    }
    if (ipAddr.isNull())
        ipAddr.setAddress(QHostAddress::LocalHost);

    return ipAddr.toString();
}

PocoWebServerPlugin::~PocoWebServerPlugin()
{
    qDebug() << "PocoWebServer Plugin destructor called";
    try
    {
        m_server->stop();
        delete m_server;
        m_server = 0;
    }
    catch(std::exception e)
    {
        qDebug() << "Could not stop server";
    }

}
helthans
 
Posts: 14
Joined: 05 Nov 2013, 15:07

Re: HTTP Server and memory leak

Postby alex » 13 Jun 2014, 04:16

I think it is a false alarm by valgrind. Newly created HTTPServerParams pointers is passed to HTTPServer constructor as AutoPtr, then to TCPServer and ends up being shared as AutoPtr between HTTPServerConnectionFactory and TCPServerDispatcher. All those are Poco::AutoPtr smart pointers so there will be no leak.

As a side-note, there is a potential problem with two new calls in HTTPServer construction; multiple new or having any other potentially-throwing functionality together with new in function arguments can leak if exception occurs during evaluation. To make sure there will be no leaks in case of exceptions, it is better to allocate first and then pass in pointers, in your case:

Code: Select all
HTTPRequestHandlerFactory::Ptr pFactory = new RequestHandlerFactory;
HTTPServerParams::Ptr pParams = new Poco::Net::HTTPServerParams;
m_server = new Poco::Net::HTTPServer(pFactory, Poco::Net::ServerSocket(addr), pParams);


See Exception-Safe Function Calls for more details.
alex
 
Posts: 1130
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: HTTP Server and memory leak

Postby helthans » 13 Jun 2014, 07:53

Thanks for the reply and a good point.
I have manually monitored the memory usage of my application and noticed a growing memory usage, which I have been hunting for a while.
As valgrind only reported issues with my http server implementation (which came as a surprise in the first place), and when disabling this part of my code the memory usage seemed to become stable, my initial conclusion was that there was a problem for this part of my code.
Now after running the application over the night without the http server code I have noticed that the memory usage is still an issue, I must agree that you are most properly right regarding false alarm.
helthans
 
Posts: 14
Joined: 05 Nov 2013, 15:07


Return to Support

Who is online

Users browsing this forum: No registered users and 1 guest