KDirWatch: fix memory leak on destruction.
authorDavid Faure <faure@kde.org>
Sun, 5 Feb 2017 10:49:07 +0000 (11:49 +0100)
committerMaximiliano Curia <maxy@debian.org>
Fri, 31 Mar 2017 13:53:53 +0000 (14:53 +0100)
Summary:
The Entry class owns the Client instances, so it should delete the
remaining instances in its destructor, for the case where they haven't
been removed one by one. The line of code removeEntries(nullptr) was
probably means to remove them one by one, but it was a no-op (the code
for that method doesn't expect nullptr as argument) and it would be
slow anyway. We don't need to call inotify_remove for every path,
when we're just cleaning up in a global static after qApp destruction.

Detected by a clang-sanitizer build on http://ci-logs.kde.flaska.net
and reproduced locally with valgrind.

Test Plan:
./kdirwatch_*_unittest now passes in valgrind without memory
leaks being reported

Reviewers: aacid, mpyne

Reviewed By: aacid, mpyne

Subscribers: markg, #frameworks

Tags: #frameworks

Differential Revision: https://phabricator.kde.org/D4439

Gbp-Pq: Name KDirWatch-fix-memory-leak-on-destruction.patch

src/lib/io/kdirwatch.cpp
src/lib/io/kdirwatch_p.h

index 241aeec0270b19192d49e201cc8464898234f83f..99da8095b5028de6a9566a500420871b01ed1dda 100644 (file)
@@ -244,9 +244,6 @@ KDirWatchPrivate::~KDirWatchPrivate()
 {
     timer.stop();
 
-    /* remove all entries being watched */
-    removeEntries(0);
-
 #if HAVE_FAM
     if (use_fam && sn) {
         FAMClose(&fc);
@@ -452,6 +449,11 @@ void KDirWatchPrivate::inotifyEventReceived()
 #endif
 }
 
+KDirWatchPrivate::Entry::~Entry()
+{
+    qDeleteAll(m_clients);
+}
+
 /* In FAM mode, only entries which are marked dirty are scanned.
  * We first need to mark all yet nonexistent, but possible created
  * entries as dirty...
index 8a7da91e7e9bd3115cf008fa8e3bb047e64da001..33e240415bdc8e11594d273f944dc7809bab3393 100644 (file)
@@ -83,8 +83,9 @@ public:
     class Entry
     {
     public:
+        ~Entry();
         // instances interested in events
-        QList<Client *> m_clients;
+        QList<Client *> m_clients; // owned by Entry
         // nonexistent entries of this directory
         QList<Entry *> m_entries;
         QString path;