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.