https://bugs.kde.org/show_bug.cgi?id=439897

            Bug ID: 439897
           Summary: Heaptrack produces impossible/incorrect stack traces
           Product: Heaptrack
           Version: unspecified
          Platform: Gentoo Packages
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: m...@milianw.de
          Reporter: k...@mattwhitlock.name
  Target Milestone: ---

SUMMARY

I'm trying to use Heaptrack to find a memory leak in plasmashell, but Heaptrack
is producing some nonsensical stack traces that purport to contain impossible
calls.

STEPS TO REPRODUCE
1. heaptrack plasmashell
2. (use plasmashell for a bit to exercise a suspected leak)
3. kquitapp5 plasmashell
4. heaptrack --analyze heaptrack.plasmashell.*.zst
or heaptrack_print heaptrack.plasmashell.*.zst

OBSERVED RESULT

Analysis contains "impossible" stack traces like (for example):

94095 calls with 0B peak consumption from:
    QString::reallocData(unsigned int, bool)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/text/qstring.cpp:2372
      in /usr/lib64/libQt5Core.so.5
    QString::resize(int)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/text/qstring.cpp:2289
      in /usr/lib64/libQt5Core.so.5
    std::__atomic_base<>::load(std::memory_order) const
      at
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/g++-v11/bits/atomic_base.h:481
      in /usr/lib64/libQt5Core.so.5
    int QAtomicOps<>::loadRelaxed<>(std::atomic<> const&)
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/thread/qatomic_cxx11.h:239
    QBasicAtomicInteger<>::loadRelaxed() const
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/thread/qbasicatomic.h:107
    QtPrivate::RefCount::isShared() const
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/tools/qrefcount.h:101
    QString::detach()
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/text/qstring.h:1088
    QString::data()
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/text/qstring.h:1084
    operator>>(QDataStream&, QString&)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/text/qstring.cpp:10418
    QDataStream& QtPrivate::readArrayBasedContainer<>(QDataStream&, QVector<>&)
      at /usr/include/qt5/QtCore/qdatastream.h:257
      in /usr/lib64/libKF5Service.so.5
    KServicePrivate::load(QDataStream&)
      at ../kservice-5.84.0/src/services/kservice.cpp:324
      in /usr/lib64/libKF5Service.so.5
    KService::KService(QDataStream&, int)
      at ../kservice-5.84.0/src/services/kservice.cpp:384
      in /usr/lib64/libKF5Service.so.5
    KServiceFactory::createEntry(int) const
      at ../kservice-5.84.0/src/services/kservicefactory.cpp:207
      in /usr/lib64/libKF5Service.so.5
    KServiceFactory::serviceOffers(int, int)
      at ../kservice-5.84.0/src/services/kservicefactory.cpp:301
      in /usr/lib64/libKF5Service.so.5
    KServiceTypeTrader::defaultOffers(QString const&, QString const&) const
      at ../kservice-5.84.0/src/services/kservicetypetrader.cpp:114
      in /usr/lib64/libKF5Service.so.5
    KServiceTypeTrader::query(QString const&, QString const&) const
      at ../kservice-5.84.0/src/services/kservicetypetrader.cpp:144
      in /usr/lib64/libKF5Service.so.5
    QString::~QString()
      at /usr/include/qt5/QtCore/qstring.h:1307
      in /usr/lib64/libnotificationmanager.so.1
    NotificationManager::Notification::Private::serviceForDesktopEntry(QString
const&)
      at /usr/include/qt5/QtCore/qstring.h:1307
    QExplicitlySharedDataPointer<>::operator bool() const
      at /usr/include/qt5/QtCore/qshareddata.h:176
      in /usr/lib64/libnotificationmanager.so.1
    NotificationManager::Notification::Private::setDesktopEntry(QString const&)
      at ../plasma-workspace-5.22.3/libnotificationmanager/notification.cpp:303
    QString::~QString()
      at /usr/include/qt5/QtCore/qstring.h:1307
      in /usr/lib64/libnotificationmanager.so.1
    NotificationManager::Notification::Private::processHints(QMap<> const&)
      at ../plasma-workspace-5.22.3/libnotificationmanager/notification.cpp:345
    NotificationManager::ServerPrivate::Notify(QString const&, unsigned int,
QString const&, QString const&, QString const&, QStringList const&, QMap<>
const&, int)
      at ../plasma-workspace-5.22.3/libnotificationmanager/server_p.cpp:184
      in /usr/lib64/libnotificationmanager.so.1
    NotificationsAdaptor::Notify(QString const&, unsigned int, QString const&,
QString const&, QString const&, QStringList const&, QMap<> const&, int)
      at libnotificationmanager/notificationsadaptor.cpp:70
      in /usr/lib64/libnotificationmanager.so.1
    NotificationsAdaptor::qt_static_metacall(QObject*, QMetaObject::Call, int,
void**)
      at libnotificationmanager/notificationsadaptor.moc:185
      in /usr/lib64/libnotificationmanager.so.1
    NotificationsAdaptor::qt_metacall(QMetaObject::Call, int, void**)
      at libnotificationmanager/notificationsadaptor.moc:258
      in /usr/lib64/libnotificationmanager.so.1
    QDBusConnectionPrivate::deliverCall(QObject*, int, QDBusMessage const&,
QVector<> const&, int)
      at
../../../qtbase-everywhere-src-5.15.2/src/dbus/qdbusintegrator.cpp:1001
      in /usr/lib64/libQt5DBus.so.5
    QDBusConnectionPrivate::activateCall(QObject*, int, QDBusMessage const&)
      at ../../../qtbase-everywhere-src-5.15.2/src/dbus/qdbusintegrator.cpp:912
      in /usr/lib64/libQt5DBus.so.5
   
QDBusConnectionPrivate::activateObject(QDBusConnectionPrivate::ObjectTreeNode&,
QDBusMessage const&, int)
      at
../../../qtbase-everywhere-src-5.15.2/src/dbus/qdbusintegrator.cpp:1497
      in /usr/lib64/libQt5DBus.so.5
   
QDBusConnectionPrivate::activateObject(QDBusConnectionPrivate::ObjectTreeNode&,
QDBusMessage const&, int)
      at
../../../qtbase-everywhere-src-5.15.2/src/dbus/qdbusintegrator.cpp:1461
      in /usr/lib64/libQt5DBus.so.5
    QDBusActivateObjectEvent::placeMetaCall(QObject*)
      at
../../../qtbase-everywhere-src-5.15.2/src/dbus/qdbusintegrator.cpp:1617
    QObjectPrivate::Sender::~Sender()
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qobject_p.h:212
      in /usr/lib64/libQt5Core.so.5
    QObject::event(QEvent*)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qobject.cpp:1316
    QCoreApplicationPrivate::setEventSpontaneous(QEvent*, bool)
      at /usr/include/qt5/QtCore/5.15.2/QtCore/private/qcoreapplication_p.h:119
      in /usr/lib64/libQt5Widgets.so.5
    QApplicationPrivate::notify_helper(QObject*, QEvent*)
      at
../../../qtbase-everywhere-src-5.15.2/src/widgets/kernel/qapplication.cpp:3634
    QCoreApplication::notifyInternal2(QObject*, QEvent*)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qcoreapplication.cpp:1063
      in /usr/lib64/libQt5Core.so.5
    QScopedPointerDeleter<>::cleanup(QEvent*)
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/tools/qscopedpointer.h:60
      in /usr/lib64/libQt5Core.so.5
    QScopedPointer<>::~QScopedPointer()
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/tools/qscopedpointer.h:107
    QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qcoreapplication.cpp:1822
    postEventSourceDispatch
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qeventdispatcher_glib.cpp:278
      in /usr/lib64/libQt5Core.so.5
    g_main_dispatch
      at ../glib-2.68.3/glib/gmain.c:3347
      in /usr/lib64/libglib-2.0.so.0
    g_main_context_dispatch
      at ../glib-2.68.3/glib/gmain.c:4055
    g_main_context_iterate
      at ../glib-2.68.3/glib/gmain.c:4131
      in /usr/lib64/libglib-2.0.so.0
    g_main_context_iteration
      at ../glib-2.68.3/glib/gmain.c:4197
      in /usr/lib64/libglib-2.0.so.0
    QEventDispatcherGlib::processEvents(QFlags<>)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qeventdispatcher_glib.cpp:424
      in /usr/lib64/libQt5Core.so.5
    std::__atomic_base<>::load(std::memory_order) const
      at
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/g++-v11/bits/atomic_base.h:481
      in /usr/lib64/libQt5Core.so.5
    int QAtomicOps<>::loadAcquire<>(std::atomic<> const&)
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/thread/qatomic_cxx11.h:251
    QBasicAtomicInteger<>::loadAcquire() const
      at
../../../qtbase-everywhere-src-5.15.2/include/QtCore/../../src/corelib/thread/qbasicatomic.h:110
    QEventLoop::exec(QFlags<>)
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qeventloop.cpp:231
    QCoreApplication::exec()
      at
../../../qtbase-everywhere-src-5.15.2/src/corelib/kernel/qcoreapplication.cpp:1371
      in /usr/lib64/libQt5Core.so.5
    main
      at ../plasma-workspace-5.22.3/shell/main.cpp:254
      in /usr/bin/plasmashell

Notice that QString::~QString() allegedly calls
NotificationManager::Notification::Private::setDesktopEntry(QString const&),
which leads to another call to QString::~QString(), which allegedly calls
KServiceTypeTrader::query(QString const&, QString const&) const.

If we look at the actual implementation of QString::~QString(), we find:

inline QString::~QString() { if (!d->ref.deref()) Data::deallocate(d); }

The deref() call is just an atomic decrement of an integer, and
Data::deallocate(d) just calls ::free(d) after making some assertions. There is
no way that QString::~QString() is calling into those other functions.

You might think that there's some weird interaction between the compiler's
optimizer and the debug info since QString::~QString() is an inlined function,
but /usr/lib64/libnotificationmanager.so.1 was compiled with '-Og -ggdb', which
is supposed to produce sensible debug info.

Another example: std::__atomic_base<>::load(std::memory_order) const supposedly
makes calls to both QEventDispatcherGlib::processEvents(QFlags<>) and
QString::resize(int). That's preposterous.

EXPECTED RESULT

Stack traces should not purport to contain function calls that do not appear in
the source code.


SOFTWARE/OS VERSIONS
Heaptrack Version: 1.2.80 (66a7ba44c)
Linux/KDE Plasma: Gentoo Linux
KDE Plasma Version: 5.22.3
KDE Frameworks Version: 5.84.0
Qt Version: 5.15.2
GCC Version: Gentoo 11.1.0-r1 p2

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to