CCBUG: 390288
Checking for nullptr will avoid the crash and return an empty
QModelIndex.
Details
- Reviewers
dfaure - Group Reviewers
Frameworks
Ask @Valdo if the bug can be reproduced.
Diff Detail
- Repository
- R241 KIO
- Branch
- kate (branched from master)
- Lint
No Linters Available - Unit
No Unit Test Coverage
It would be much better to fix those two issues instead...
kf5.kio.core: Refilling KProtocolInfoFactory cache in the hope to find ""
(which sounds like a wrongly constructed URL with no scheme)
kf5.kio.widgets: Items emitted in directory QUrl("smb://") but that directory isn't in KDirModel! Root directory: QUrl("smb:///")
(which might or might not be a consequence of the previous issue)
I tried testing
kdialog --getexistingdirectory smb://
but this gives an error here "Unable to find any workgroups in your local network." even with samba started locally. Don't know why.
I tried testing
kdialog --getexistingdirectory smb://but this gives an error here "Unable to find any workgroups in your local network." even with samba started locally. Don't know why.
I get always a crash trying kdialog --getexistingdirectory smb://, only executed directly or under valgrind, but not under gdb when I get that message also.
8150== Process terminating with default action of signal 11 (SIGSEGV)
8150== Access not within mapped region at address 0x28
8150== at 0x62701D6: QObject::isWidgetType() const (qobject.h:147)
8150== by 0x627022C: QWidget* qobject_cast<QWidget*>(QObject*) (qwidget.h:741)
8150== by 0x627072B: QtPrivate::QVariantValueHelper<QWidget*>::object(QVariant const&) (qvariant.h:709)
8150== by 0x62704BD: QtPrivate::ObjectInvoker<QtPrivate::QVariantValueHelper<QWidget*>, QVariant const&, QWidget*>::invoke(QVariant const&) (qvariant.h:102)
8150== by 0x627037B: QWidget* qvariant_cast<QWidget*>(QVariant const&) (qvariant.h:835)
8150== by 0x62702D5: QWidget* QVariant::value<QWidget*>() const (qvariant.h:352)
8150== by 0x626FF64: KJobWidgets::window(KJob*) (kjobwidgets.cpp:35)
8150== by 0x6268028: KDialogJobUiDelegate::window() const (kdialogjobuidelegate.cpp:144)
8150== by 0x62680E6: KDialogJobUiDelegate::showErrorMessage() (kdialogjobuidelegate.cpp:162)
8150== by 0x4F48236: KDirLister::handleError(KIO::Job*) (kdirlister.cpp:81)
8150== by 0x5F9F573: KCoreDirListerCache::slotResult(KJob*) (kcoredirlister.cpp:1334)
8150== by 0x5FAAC6E: KCoreDirListerCache::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (moc_kcoredirlister_p.cpp:136)
8150== by 0x921B029: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib64/libQt5Core.so.5.10.0)
8150== by 0x8A798DC: KJob::result(KJob*, KJob::QPrivateSignal) (moc_kjob.cpp:569)
8150== by 0x8A778B4: KJob::finishJob(bool) (kjob.cpp:114)
8150== by 0x8A77F9A: KJob::emitResult() (kjob.cpp:298)
8150== by 0x5F592AB: KIO::SimpleJob::slotFinished() (simplejob.cpp:232)
8150== by 0x5F52050: KIO::ListJob::slotFinished() (listjob.cpp:247)
8150== by 0x5F593C6: KIO::SimpleJob::slotError(int, QString const&) (simplejob.cpp:245)
8150== by 0x5F5BA92: QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<int, QString const&>, void, void (KIO::SimpleJob::*)(int, QString const&)>::call(void (KIO::SimpleJob::*)(int, QString const&), KIO::SimpleJob*, void**) (qobjectdefs_impl.h:136)
8150== by 0x5F5B8EF: void QtPrivate::FunctionPointer<void (KIO::SimpleJob::*)(int, QString const&)>::call<QtPrivate::List<int, QString const&>, void>(void (KIO::SimpleJob::*)(int, QString const&), KIO::SimpleJob*, void**) (qobjectdefs_impl.h:169)
8150== by 0x5F5B65C: QtPrivate::QSlotObject<void (KIO::SimpleJob::*)(int, QString const&), QtPrivate::List<int, QString const&>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:398)
8150== by 0x921B12B: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib64/libQt5Core.so.5.10.0)
8150== by 0x5F3DF91: KIO::SlaveInterface::error(int, QString const&) (moc_slaveinterface.cpp:425)
8150== by 0x5F3BCA5: KIO::SlaveInterface::dispatch(int, QByteArray const&) (slaveinterface.cpp:192)
8150== by 0x5F3B766: KIO::SlaveInterface::dispatch() (slaveinterface.cpp:89)
8150== by 0x5F3FF43: KIO::Slave::gotInput() (slave.cpp:406)
8150== by 0x5FD44FE: KIO::Slave::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (moc_slave.cpp:89)
8150== by 0x921B029: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib64/libQt5Core.so.5.10.0)
8150== by 0x5EE55D4: KIO::Connection::readyRead() (moc_connection_p.cpp:143)
8150== by 0x5EE43C0: KIO::ConnectionPrivate::dequeue() (connection.cpp:46)
8150== by 0x5EE53E5: KIO::Connection::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (moc_connection_p.cpp:87)
When KDialogJobUiDelegate::showErrorMessage() is called, the job is already finished and deleted.
At KIO::SlaveInterface::dispatch(), (slaveinterface.cpp:89) the last data is:
dispatch= 102 data= "\x00\x00\x00\xA3\x00\x00\x00\xC2\x00U\x00n\x00""a\x00""b\x00l\x00""e\x00 \x00t\x00o\x00 \x00""f\x00i\x00n\x00""d\x00 \x00""a\x00n\x00y\x00 \x00w\x00o\x00r\x00k\x00g\x00r\x00o\x00u\x00p\x00s\x00 \x00i\x00n\x00 \x00y\x00o\x00u\x00r\x00 \x00l\x00o\x00""c\x00""a\x00l\x00 \x00n\x00""e\x00t\x00w\x00o\x00r\x00k\x00.\x00 \x00T\x00h\x00i\x00s\x00 \x00m\x00i\x00g\x00h\x00t\x00 \x00""b\x00""e\x00 \x00""c\x00""a\x00u\x00s\x00""e\x00""d\x00 \x00""b\x00y\x00 \x00""a\x00n\x00 \x00""e\x00n\x00""a\x00""b\x00l\x00""e\x00""d\x00 \x00""f\x00i\x00r\x00""e\x00w\x00""a\x00l\x00l\x00."
I'm not sure the job could have been deleted before KDialogJobUiDelegate::showErrorMessage() since much of the call stack before then involves making method calls on the job. KDirLister::handleError(KIO::Job*) (kdirlister.cpp:81) makes a call to job->error() right before calling handleError, for instance.
Is it possible that the widget itself has been deleted early somehow? Does the job run on a different event loop (due to threading or similar)?
I think valgrind has some flags you can use to try to generate a backtrace for where a freed block of memory was freed from, which might be useful for debugging.
Thanks. The parameter is --read-var-info=yes, but it confirms my assumption, the job is already deleted and its space used by many others before the crash.
With --tool=helgrind it shows more than 4.500 errors.
With -tool=drd it shows more than 90.000 errors.
Therefore I'll try to fix as many of them as possible, step by step, if it's possible.
helgrind and drd are for multithreading data races, but KDirModel can't be used in a multithreading context, so I'm not sure why you're mentioning those tools.
If you do want to detect data races, please note that helgrind and drd have lots of false positives (if you really want to use helgrind, read https://www.kdab.com/~dfaure/helgrind.html), and a much better tool is clang's thread-sanitizer. Downside: you need to build your own Qt first, with -platform linux-clang-libc++ -sanitize thread. Upside: the apps run much faster than with helgrind, and the reports are much more useful.
I pushed https://commits.kde.org/kio/d219f304319cb61aa51aae78c46872cbe49f8ff0 instead, you can drop this.