Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Possible memory leak on QDnsLookup?
Qt 6.11 is out! See what's new in the release blog

Possible memory leak on QDnsLookup?

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Comandillos
    wrote on last edited by
    #1

    Hi there, i'v been developing a small DNS server for caching some request in local (dnsmasq / BIND like). For that, I use a QMap for caching request and a QDnsLookup for domains I can't resolve locally.

    Everything works fine, until QDnsLookup gets in. I'v been profiling the application for memory leaks and i'v discovered everytime I call the method 'lookup' from a QDnsLookup instance, a memory leak of ~9kb appears. The slot where I connect the lookup instance is totally empty, and I free the instance correctly.

    If I don't call the 'lookup' method, no memory leaks appears, so I was thinking about QDnsLookup class having a memory leak.

    This is the class that I use as the DNS resolver

    #include "dnsresolver.h"
    
    quint32 DNSResolver::resolveDomain(QString domain)
    {
        if (cacheResolved){
            return cache->value(domain).toIPv4Address();
        }else{
            lookup->lookup();
            return 0;
        }
    }
    
    void DNSResolver::handleExternalResolve()
    {
        if (!lookup->hostAddressRecords().isEmpty()){
            auto record = lookup->hostAddressRecords().first();
            auto host = record.value();
    
            dnspack->addArecord(host.toIPv4Address());
            cache->insert(dnspack->domain, host);
        }
    
        delete lookup;
        emit sendResponse(*dnspack->datagram, senderHost.toIPv4Address(), senderPort);
    }
    
    DNSResolver::DNSResolver(t_resolve t, QObject *parent)
        : QThread(parent)
    {
        this->socket = t.socket;
        this->datagram = t.datagram;
        this->senderHost = t.senderHost;
        this->cache = t.cache;
        this->senderPort = t.senderPort;
    
        // Alloc a DNS packet for parsing
        dnspack = new DNS;
        dnspack->parse(&datagram);
        dnspack->makeAnswer();
    
        // Check if we can resolve by cache
        cacheResolved = cache->contains(dnspack->domain);
    
        if (!cacheResolved){
            // Alloc a external lookup object
            this->lookup = new QDnsLookup(QDnsLookup::A, dnspack->domain, QHostAddress(FORWARDING_DNS_SERVER));
            connect(lookup, SIGNAL(finished()), this, SLOT(handleExternalResolve()));
        }
    
    }
    
    DNSResolver::~DNSResolver()
    {
        delete dnspack;
    }
    
    void DNSResolver::run()
    {
        auto ip = resolveDomain(dnspack->domain);
        if (ip != 0){
            dnspack->addArecord(ip);
            emit sendResponse(*dnspack->datagram, senderHost.toIPv4Address(), senderPort);
        }
    }
    

    Thanks!!!!

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      What version of Qt are you using ? On what platform ?

      Can you reproduce that with a smaller example ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Comandillos
        wrote on last edited by Comandillos
        #3

        Qt 5.8, macOS 10.12.4.
        That's only a simple use case, but as I said, the problem can be reproduced just instancing a QDnsLookup instance and calling the lookup method. This is an smaller example.

        #include "dnsresolver.h"
        
        DnsResolver::DnsResolver(QObject *parent) : QObject(parent)
        {
            lookup = new QDnsLookup(QDnsLookup::A, "qt.io",QHostAddress("8.8.8.8"));
            connect(lookup, SIGNAL(finished()), this, SLOT(handleLookup()));
            lookup->lookup();
        }
        
        void DnsResolver::handleLookup()
        {
            // I use sleep for letting the profiler inspect the memory trace with enough time
            QThread::sleep(10);
        
            // I won't use lookup anymore
            delete lookup;
        
            // Let's close the app
            QCoreApplication::quit();
        }
        
        

        This code gives me a memory leak of 944 bytes on 'libresolv'. I don't know if it's Qt problem or 'libresolv' problem (I don't know what's even libresolv).

        Here's the profiler message.

        Profiler message image

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Which version of libresolv is it exactly ?

          AFAIK, that's the library that currently implements the name resolution and related stuff on Linux style OSs.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved