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

--- Comment #12 from Matt Fagnani <matthew.fagn...@utoronto.ca> ---
All of the valgrind runs' first invalid reads were in
KSGRD::SensorAgent::processAnswer at SensorAgent.cpp:186 as in the following.
All of the other invalid reads or writes have
KSGRD::SensorAgent::processAnswer(char const*, int) (SensorAgent.cpp:186) lower
in their traces.

==3167== Invalid read of size 4
==3167==    at 0x52311C6: KSGRD::SensorAgent::processAnswer(char const*, int)
(SensorAgent.cpp:186)
==3167==    by 0x5238E8D: KSGRD::SensorShellAgent::msgRcvd()
(SensorShellAgent.cpp:93)
==3167==    by 0x6959B43: call (qobjectdefs_impl.h:376)
==3167==    by 0x6959B43: QMetaObject::activate(QObject*, int, int, void**)
(qobject.cpp:3754)
==3167==    by 0x695A050: QMetaObject::activate(QObject*, QMetaObject const*,
int, void**) (qobject.cpp:3633)
==3167==    by 0x68C70F4:
QProcess::readyReadStandardOutput(QProcess::QPrivateSignal)
(moc_qprocess.cpp:362)
==3167==    by 0x68CC8AA:
QProcessPrivate::tryReadFromChannel(QProcessPrivate::Channel*)
(qprocess.cpp:1070)
==3167==    by 0x68CCE86: _q_canReadStandardOutput (qprocess.cpp:1081)
==3167==    by 0x68CCE86: QProcess::qt_static_metacall(QObject*,
QMetaObject::Call, int, void**) (moc_qprocess.cpp:207)
==3167==    by 0x6959A15: QMetaObject::activate(QObject*, int, int, void**)
(qobject.cpp:3771)
==3167==    by 0x695A050: QMetaObject::activate(QObject*, QMetaObject const*,
int, void**) (qobject.cpp:3633)
==3167==    by 0x6965BA9: QSocketNotifier::activated(int,
QSocketNotifier::QPrivateSignal) (moc_qsocketnotifier.cpp:136)
==3167==    by 0x6965F71: QSocketNotifier::event(QEvent*)
(qsocketnotifier.cpp:266)
==3167==    by 0x5B1BDA9: QApplicationPrivate::notify_helper(QObject*, QEvent*)
(qapplication.cpp:3727)
==3167==  Address 0x1133204c is 36 bytes inside a block of size 132 free'd
==3167==    at 0x4836BC9: operator delete(void*) (vg_replace_malloc.c:576)
==3167==    by 0x48E5C69: TopLevel::~TopLevel() (ksysguard.h:41)
==3167==    by 0x695A77A: QObject::event(QEvent*) (qobject.cpp:1242)
==3167==    by 0x5B6166C: QWidget::event(QEvent*) (qwidget.cpp:9347)
==3167==    by 0x5C880C2: QMainWindow::event(QEvent*) (qmainwindow.cpp:1348)
==3167==    by 0x50148B9: KMainWindow::event(QEvent*) (in
/usr/lib/libKF5XmlGui.so.5.52.0)
==3167==    by 0x5061E50: KXmlGuiWindow::event(QEvent*) (in
/usr/lib/libKF5XmlGui.so.5.52.0)
==3167==    by 0x48DC18B: TopLevel::event(QEvent*) (ksysguard.cpp:343)
==3167==    by 0x5B1BDA9: QApplicationPrivate::notify_helper(QObject*, QEvent*)
(qapplication.cpp:3727)
==3167==    by 0x5B23E58: QApplication::notify(QObject*, QEvent*)
(qapplication.cpp:3486)
==3167==    by 0x692EE65: QCoreApplication::notifyInternal2(QObject*, QEvent*)
(qcoreapplication.cpp:1048)
==3167==    by 0x6932317: sendEvent (qcoreapplication.h:234)
==3167==    by 0x6932317: QCoreApplicationPrivate::sendPostedEvents(QObject*,
int, QThreadData*) (qcoreapplication.cpp:1745)
==3167==  Block was alloc'd at
==3167==    at 0x4835C89: operator new(unsigned int) (vg_replace_malloc.c:328)
==3167==    by 0x48DEF86: kdemain (ksysguard.cpp:588)
==3167==    by 0x1090CA: main (in /usr/bin/ksysguard)
==3167== 

SensorAgent.cpp:186 is 
req->client()->answerReceived( req->id(), mAnswerBuffer ); 
https://cgit.kde.org/libksysguard.git/tree/ksgrd/SensorAgent.cpp?h=Plasma/5.14

The invalid reads of a variable in SensorAgent.cpp:186 which had already been
freed might be where the invalid reads and writes leading to the segmentation
faults I've observed started. delete req and mAnswerBuffer.clear() followed by
continue are in if blocks before the req->client()->answerReceived( req->id(),
mAnswerBuffer ) line so I'm unsure if that can be reached if those variables
are deleted/freed first. The else of the if block SensorAgent.cpp:186 is in
might be run if mAnswerBuffer.isEmpty() is true which might lead to an empty
mAnswerBuffer being used.

if(!mAnswerBuffer.isEmpty() && mAnswerBuffer[0] == "UNKNOWN COMMAND") {
       /* Notify client that the sensor seems to be no longer available. */
        qCDebug(LIBKSYSGUARD_KSGRD) << "Received UNKNOWN COMMAND for: " <<
req->request();
                req->client()->sensorLost( req->id() );
        } else {
                // Notify client of newly arrived answer.
                req->client()->answerReceived( req->id(), mAnswerBuffer );
        }

Changing that if block to be something like the following might avoid an empty
mAnswerBuffer being used.

if(!mAnswerBuffer.isEmpty()) { 
    if (mAnswerBuffer[0] == "UNKNOWN COMMAND") {
         /* Notify client that the sensor seems to be no longer available. */
        qCDebug(LIBKSYSGUARD_KSGRD) << "Received UNKNOWN COMMAND for: " <<
req->request();
        req->client()->sensorLost( req->id() );
    } 
    else {
        // Notify client of newly arrived answer.
        req->client()->answerReceived( req->id(), mAnswerBuffer );
    }
}

I built the ksysguard packages with AddressSanitizer enabled. When I ran
ksysguard several times with AddressSanitizer enabled and closed it, memory
leaks were shown which were similar to those output by a further valgrind run I
did. No use-after-free errors were shown by AddressSanitizer. I'll attach the
valgrind and AddressSanitizer output showing memory leaks.

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

Reply via email to