I have a directory that throws some read errors when I perform an `ls` in this dir. This is how the read erros look like: "ls: cannot read symbolic link 'core': Protocol error" Before you say "Well, your system is broken! Hahaha!", let me explain this in more detail. First of all this is an mounted network resource that I don't manage. So I'm not responsible for this bug. I just have to deal with it. Secondly, several other file managers are more fault tolerant, e.g. Dolphin or mc. I wish that Krusader would also just ignore those read errors and show me all valid files and directories instead of crashing. Here is the stacktrace (using the git version): $ gdb krusader/krusader GNU gdb (Ubuntu 8.0.1-0ubuntu1) 8.0.1 Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from krusader/krusader...(no debugging symbols found)...done. (gdb) run Starting program: /home/stefan/software/krusader/krusader-build/krusader/krusader [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". kf5.kio.core: Refilling KProtocolInfoFactory cache in the hope to find "krarc" kf5.kio.core: Refilling KProtocolInfoFactory cache in the hope to find "iso" [New Thread 0x7fffe2e14700 (LWP 17956)] [New Thread 0x7fffd8174700 (LWP 17957)] [New Thread 0x7fffd7973700 (LWP 17958)] [New Thread 0x7fffd7172700 (LWP 17959)] [New Thread 0x7fffd6971700 (LWP 17960)] [New Thread 0x7fffc4f54700 (LWP 17962)] 14:18:10.466-warning default unknown@0 # can't locate layout.xml Thread 1 "krusader" received signal SIGSEGV, Segmentation fault. 0x0000555555710ab5 in FileSystem::createLocalFileItem(QString const&, QString const&, bool) () (gdb) where #0 0x0000555555710ab5 in FileSystem::createLocalFileItem(QString const&, QString const&, bool) () #1 0x000055555572411c in DefaultFileSystem::createLocalFileItem(QString const&) () #2 0x0000555555724aa5 in DefaultFileSystem::refreshLocal(QUrl const&, bool) () #3 0x00005555557263b4 in DefaultFileSystem::refreshInternal(QUrl const&, bool) () #4 0x00005555557120b1 in FileSystem::scanOrRefresh(QUrl const&, bool) () #5 0x000055555562c3c0 in ListPanelFunc::doRefresh() () #6 0x0000555555638a35 in ListPanelFunc::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) [clone .part.26] () #7 0x0000555555638dfa in ListPanelFunc::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) () #8 0x00007ffff243d8e5 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #9 0x00007ffff244a3b7 in QTimer::timeout(QTimer::QPrivateSignal) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #10 0x00007ffff244a718 in QTimer::timerEvent(QTimerEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #11 0x00007ffff243e40b in QObject::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #12 0x00007ffff33a346c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #13 0x00007ffff33aad34 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #14 0x00007ffff240ede8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #15 0x00007ffff246691e in QTimerInfoList::activateTimers() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #16 0x00007ffff24670e1 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #17 0x00007fffeca62fb7 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #18 0x00007fffeca631f0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #19 0x00007fffeca6327c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #20 0x00007ffff246747f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #21 0x00007ffff240ce3a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #22 0x00007ffff2415da4 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #23 0x00005555555e46ae in main () (gdb) list
I completely forgot to mention the behavior of krusader. So, krusader works fine as long as I do not enter directories with read errors, but once I do it immediately crashes with an segmentation fault.
Stefan, how would you repro such a read error locally without a network resource?
@Nikita That's a good question. Unfortunately, I don't have an answer to it.
Could you provide debug build backtrace which includes line numbers? createLocalFileItem function is not small. In addition, you can try one of the following approaches to repro locally: https://unix.stackexchange.com/questions/77492/special-file-that-causes-i-o-error/144200
OK, here is the backtrace with line numbers: #0 0x0000555555710ab5 in memset (__len=2957657807, __ch=0, __dest=0x7fff4fb58670) at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:71 #1 FileSystem::createLocalFileItem (name=..., directory=..., virt=virt@entry=false) at /home/stefan/software/krusader/krusader/FileSystem/filesystem.cpp:240 #2 0x000055555572411c in DefaultFileSystem::createLocalFileItem (this=this@entry=0x555556222f50, name=...) at /home/stefan/software/krusader/krusader/FileSystem/defaultfilesystem.cpp:408 #3 0x0000555555724aa5 in DefaultFileSystem::refreshLocal (this=this@entry=0x555556222f50, directory=..., onlyScan=onlyScan@entry=false) at /home/stefan/software/krusader/krusader/FileSystem/defaultfilesystem.cpp:383 #4 0x00005555557263b4 in DefaultFileSystem::refreshInternal (this=0x555556222f50, directory=..., onlyScan=<optimized out>) at /home/stefan/software/krusader/krusader/FileSystem/defaultfilesystem.cpp:212 #5 0x00005555557120b1 in FileSystem::scanOrRefresh (this=0x555556222f50, directory=..., onlyScan=onlyScan@entry=false) at /home/stefan/software/krusader/krusader/FileSystem/filesystem.cpp:142 #6 0x000055555562c3c0 in FileSystem::refresh (directory=..., this=<optimized out>) at /home/stefan/software/krusader/krusader/Panel/../FileSystem/filesystem.h:131 #7 ListPanelFunc::doRefresh (this=0x5555561ec570) at /home/stefan/software/krusader/krusader/Panel/panelfunc.cpp:320 #8 0x0000555555638a35 in ListPanelFunc::qt_static_metacall (_o=<optimized out>, _id=<optimized out>, _a=<optimized out>, _c=QMetaObject::InvokeMetaMethod) at /home/stefan/software/krusader/krusader-build/krusader/Panel/Panel_autogen/EWIEGA46WW/moc_panelfunc.cpp:302 #9 0x0000555555638dfa in ListPanelFunc::qt_static_metacall (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at /home/stefan/software/krusader/krusader-build/krusader/Panel/Panel_autogen/EWIEGA46WW/moc_panelfunc.cpp:250 #10 0x00007ffff243d8e5 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #11 0x00007ffff244a3b7 in QTimer::timeout(QTimer::QPrivateSignal) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #12 0x00007ffff244a718 in QTimer::timerEvent(QTimerEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #13 0x00007ffff243e40b in QObject::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #14 0x00007ffff33a346c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #15 0x00007ffff33aad34 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #16 0x00007ffff240ede8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #17 0x00007ffff246691e in QTimerInfoList::activateTimers() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #18 0x00007ffff24670e1 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #19 0x00007fffeca62fb7 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #20 0x00007fffeca631f0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #21 0x00007fffeca6327c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #22 0x00007ffff246747f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #23 0x00007ffff240ce3a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #24 0x00007ffff2415da4 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #25 0x00005555555e46ae in main (argc=<optimized out>, argv=<optimized out>) at /home/stefan/software/krusader/krusader/main.cpp:350
Interesting. What does `readlink core` output?
$ readlink -v core readlink: core: Protocol error
Stefan, could you please test the following patch? https://phabricator.kde.org/D10761?download=true Instructions on how to apply: 1. Save locally as D10761.diff. 2. cd into git clone of krusader, current master. 3. patch -Np1 < /path/to/D10761.diff
OK, I checked out the new git master version, applied the patch, compiled and started the project. Unfortunately, krusader crashed in the buggy directory again: #0 0x0000555555711074 in memset (__len=2957657807, __ch=0, __dest=0x7fff4fb586b0) at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:71 #1 FileSystem::createLocalFileItem (name=..., directory=..., virt=virt@entry=false) at /home/stefan/software/krusader/krusader/FileSystem/filesystem.cpp:240 #2 0x00005555557246ec in DefaultFileSystem::createLocalFileItem (this=this@entry=0x555555f00660, name=...) at /home/stefan/software/krusader/krusader/FileSystem/defaultfilesystem.cpp:408 #3 0x0000555555725075 in DefaultFileSystem::refreshLocal (this=this@entry=0x555555f00660, directory=..., onlyScan=onlyScan@entry=false) at /home/stefan/software/krusader/krusader/FileSystem/defaultfilesystem.cpp:383 #4 0x0000555555726984 in DefaultFileSystem::refreshInternal (this=0x555555f00660, directory=..., onlyScan=<optimized out>) at /home/stefan/software/krusader/krusader/FileSystem/defaultfilesystem.cpp:212 #5 0x0000555555712681 in FileSystem::scanOrRefresh (this=0x555555f00660, directory=..., onlyScan=onlyScan@entry=false) at /home/stefan/software/krusader/krusader/FileSystem/filesystem.cpp:142 #6 0x000055555562c440 in FileSystem::refresh (directory=..., this=<optimized out>) at /home/stefan/software/krusader/krusader/Panel/../FileSystem/filesystem.h:131 #7 ListPanelFunc::doRefresh (this=0x555555f41ff0) at /home/stefan/software/krusader/krusader/Panel/panelfunc.cpp:320 #8 0x0000555555638ab5 in ListPanelFunc::qt_static_metacall (_o=<optimized out>, _id=<optimized out>, _a=<optimized out>, _c=QMetaObject::InvokeMetaMethod) at /home/stefan/software/krusader-build/krusader/Panel/Panel_autogen/EWIEGA46WW/moc_panelfunc.cpp:302 #9 0x0000555555638e7a in ListPanelFunc::qt_static_metacall (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at /home/stefan/software/krusader-build/krusader/Panel/Panel_autogen/EWIEGA46WW/moc_panelfunc.cpp:250 #10 0x00007ffff243d8e5 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #11 0x00007ffff244a3b7 in QTimer::timeout(QTimer::QPrivateSignal) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #12 0x00007ffff244a718 in QTimer::timerEvent(QTimerEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #13 0x00007ffff243e40b in QObject::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #14 0x00007ffff33a346c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #15 0x00007ffff33aad34 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #16 0x00007ffff240ede8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #17 0x00007ffff246691e in QTimerInfoList::activateTimers() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #18 0x00007ffff24670e1 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #19 0x00007fffeca62fb7 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #20 0x00007fffeca631f0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #21 0x00007fffeca6327c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #22 0x00007ffff246747f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #23 0x00007ffff240ce3a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #24 0x00007ffff2415da4 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #25 0x00005555555e470e in main (argc=<optimized out>, argv=<optimized out>) at /home/stefan/software/krusader/krusader/main.cpp:350
Thanks for testing! This is an interesting case. lstat finishes without an error, however coreutils are able to spot a problem. I'm planning to prepare another change that will produce an extensive debug output.
OK, waiting for more patches to test...
And thanks for your effort!
Updated the patch. No debug output yet, however this includes another possible fix. Please apply the same way and test it. Thanks!
That's it! You fixed the crash! Thank you very much!
You are welcome! Thanks for testing. I'll do a bit of refactoring and push the change for review then.
Git commit dd7d756f65137ccaf0df7b126fd375201f86c061 by Nikita Melnichenko. Committed on 02/03/2018 at 07:04. Pushed by melnichenko into branch 'master'. Fixed a crash when browsing dirs with malformed symlinks Two major changes for improved stability: * check the status of lstat and show a "broken" file entry * use new readLinkSafely function which does not consider stat_p.st_size but gradually increases buffer until the link destination path fits into the buffer - this helps in case st_size contains garbage (some network fs don't care about setting the right size) As a complementary bonus, the change fixes the following warning: filesystem.cpp:239:35: warning: variable length array ‘buffer’ is used FIXED: [ 389413 ] Krusader crashes when entering directories with read errors Related: bug 390994 Differential Revision: https://phabricator.kde.org/D10761 M +8 -0 krusader/FileSystem/fileitem.cpp M +3 -1 krusader/FileSystem/fileitem.h M +58 -23 krusader/FileSystem/filesystem.cpp M +4 -1 krusader/FileSystem/filesystem.h https://commits.kde.org/krusader/dd7d756f65137ccaf0df7b126fd375201f86c061