Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(no joke) nautilus crash #139

Closed
damianatorrpm opened this issue Nov 20, 2017 · 17 comments
Closed

(no joke) nautilus crash #139

damianatorrpm opened this issue Nov 20, 2017 · 17 comments

Comments

@damianatorrpm
Copy link
Contributor

damianatorrpm commented Nov 20, 2017

Something is not correct with the copy/cut->paste in libfm-qt

  1. Open pcmanfm-qt
  2. Open nautilus
  3. Cut/Copy a file in pcmanfm-qt
  4. Click into nautilus to paste the file //all good
  5. compile libfm-qt-master/src/test/test-folderview.cpp
  6. copy/cut a file there
  7. Click into nautilus to paste the file //nautilus crashes with
ERROR:../src/nautilus-file.c:584:nautilus_file_new_from_filename: assertion failed: (filename[0] != '\0')
Aborted (core dumped)

This seems to be an issue with the clipboard implementation of libfm-qt as the following example program crashes for me too. I suspect depending on the place of the crash that somehow the clipboard data does not look exactly like it should or _convertPath not converting like expected.

....
    Q_INVOKABLE void pasteFiles(QString pathToSomeFile) //like "/home/you/testfolder/test.txt
   {
  auto uri  = Fm::FilePath::fromPathStr(pathToSomeFile.toLocal8Bit().constData());
  auto home = Fm::FilePath::homeDir();
   Fm::pasteFilesFromClipboard(home);
      }
....

where the crash is interestingly in path.h::386 which serves the same purpose as the thing nautilus crashes with

  static Path newForGfile(GFile* gf) {
    return Path::wrapPtr(fm_path_new_for_gfile(gf));
  }
Thread 1 (Thread 0x7ffff7fb3f40 (LWP 25276)):
#0  0x00007ffff7baf7c3 in fm_path_ref () at /lib64/libfm.so.4
#1  0x00007ffff7bb049a in fm_path_new_for_uri () at /lib64/libfm.so.4
#2  0x00007ffff7bb02d2 in fm_path_new_for_str () at /lib64/libfm.so.4
#3  0x00007ffff7bb0590 in fm_path_new_for_gfile () at /lib64/libfm.so.4
#4  0x000000000046f460 in Fm::Path::newForGfile(_GFile*) (gf=0x835580) at ../untitled1/path.h:387
#5  0x000000000046f734 in Fm::_convertPath(Fm::FilePath const&) (path=...) at ../untitled1/core/compat_p.h:19
        __PRETTY_FUNCTION__ = "Fm::Path Fm::_convertPath(const Fm::FilePath&)"
#6  0x000000000046f7de in Fm::_convertPathList(std::vector<Fm::FilePath, std::allocator<Fm::FilePath> > const&) (srcFiles=...) at ../untitled1/core/compat_p.h:25
        file = @0xbd59f0: {gfile_ = {gobj_ = 0x835580}, static homeDir_ = {gfile_ = {gobj_ = 0x954300}, static homeDir_ = <same as static member of an already seen type>}}
        __for_range = @0x7fffffffb0b0: {<std::_Vector_base<Fm::FilePath, std::allocator<Fm::FilePath> >> = {_M_impl = {<std::allocator<Fm::FilePath>> = {<__gnu_cxx::new_allocator<Fm::FilePath>> = {<No data fields>}, <No data fields>}, _M_start = 0xbd59f0, _M_finish = 0xbd59f8, _M_end_of_storage = 0xbd59f8}}, <No data fields>}
        __for_begin = {_M_current = 0xbd59f0}
        __for_end = {_M_current = 0xbd59f8}
        ret = {dataPtr_ = 0x7fffd001b700}
#7  0x00000000004bae2c in Fm::FileOperation::FileOperation(Fm::FileOperation::Type, std::vector<Fm::FilePath, std::allocator<Fm::FilePath> >, QObject*) (this=0x3213ac0, type=Fm::FileOperation::Move, srcFiles=..., parent=0x0) at ../untitled1/fileoperation.cpp:37
#8  0x00000000004bc11d in Fm::FileOperation::moveFiles(std::vector<Fm::FilePath, std::allocator<Fm::FilePath> >, Fm::FilePath) (srcFiles=..., dest=...) at ../untitled1/fileoperation.cpp:254
        op = 0x7fffffffb298
#9  0x00000000004d3e8e in Fm::pasteFilesFromClipboard(Fm::FilePath const&, QWidget*) (destPath=..., parent=0x0) at ../untitled1/utilities.cpp:111
        __PRETTY_FUNCTION__ = "void Fm::pasteFilesFromClipboard(const Fm::FilePath&, QWidget*)"
        clipboard = 0x8b8870
        data = 0x32123f0
        paths = {<std::_Vector_base<Fm::FilePath, std::allocator<Fm::FilePath> >> = {_M_impl = {<std::allocator<Fm::FilePath>> = {<__gnu_cxx::new_allocator<Fm::FilePath>> = {<No data fields>}, <No data fields>}, _M_start = 0x2f039e0, _M_finish = 0x2f039e8, _M_end_of_storage = 0x2f039e8}}, <No data fields>}
        isCut = true
#10 0x00000000004e7a7c in Fm::ProxyFolderModel::pasteFiles(QString) (this=0x898490, filePath=...) at ../untitled1/proxyfoldermodel.h:92
        folderPath = {gfile_ = {gobj_ = 0x95b220}, static homeDir_ = {gfile_ = {gobj_ = 0x954300}, static homeDir_ = <same as static member of an already seen type>}}
        home = {gfile_ = {gobj_ = 0x954300}, static homeDir_ = {gfile_ = {gobj_ = 0x954300}, static homeDir_ = <same as static member of an already seen type>}}
        clipboard = 0x8b8870
        data = 0x32123f0
        __PRETTY_FUNCTION__ = "void Fm::ProxyFolderModel::pasteFiles(QString)"
#11 0x00000000004e7293 in Fm::ProxyFolderModel::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x898490, _c=QMetaObject::InvokeMetaMethod, _id=4, _a=0x7fffffffb490) at moc_proxyfoldermodel.cpp:116
        _t = 0x898490
@tsujan
Copy link
Member

tsujan commented Nov 20, 2017

Nautilus' problem is Nautilus' (no joke).

The above backtrace shows an issue in libfm's fm_path_new_for_uri(), which is called by libfm-qt's newForGfile(). Perhaps, char* uri and FmPath* root_path are both null when that function is called.

@tsujan
Copy link
Member

tsujan commented Nov 20, 2017

@palinek? You see hidden NULLs better than I do.

@palinek
Copy link
Contributor

palinek commented Nov 21, 2017

I see the crash of nautilus here and managed it to not crash with this:

diff --git a/src/utilities.cpp b/src/utilities.cpp
index c4351b2..4f52190 100644
--- a/src/utilities.cpp
+++ b/src/utilities.cpp
@@ -114,7 +114,8 @@ void pasteFilesFromClipboard(const Fm::FilePath& destPath, QWidget* parent) {
     }
 }
 
-void copyFilesToClipboard(const Fm::FilePathList& files) {
+static void setFilesToClipboard(const Fm::FilePathList& files, bool isCut)
+{
     QClipboard* clipboard = QApplication::clipboard();
     QMimeData* data = new QMimeData();
     QByteArray ba;
@@ -124,28 +125,26 @@ void copyFilesToClipboard(const Fm::FilePathList& files) {
     data->setData(QStringLiteral("text/x-libfmqt-pid"), ba.setNum(QCoreApplication::applicationPid()));
     // Gnome, LXDE, and XFCE
     // Note: the standard text/urilist format uses CRLF for line breaks, but gnome format uses LF only
-    data->setData("x-special/gnome-copied-files", QByteArray("copy\n") + urilist.replace("\r\n", "\n"));
+    QByteArray gnome_copied_files;
+    gnome_copied_files.reserve(5/*copy/cut\n*/ + urilist.size() + files.size() + 1);
+    gnome_copied_files += isCut ? "cut\n" : "copy\n";
+    gnome_copied_files += urilist.replace("\r\n", "\n");
+    // Note: the trailing \n can make nautilus crash on assertion
+    gnome_copied_files.chop(1);
+    data->setData("x-special/gnome-copied-files", gnome_copied_files);
     // The KDE way
     data->setData("text/uri-list", urilist);
-    // data->setData(QStringLiteral("application/x-kde-cutselection"), QByteArrayLiteral("0"));
+    if (isCut)
+        data->setData(QStringLiteral("application/x-kde-cutselection"), QByteArrayLiteral("1"));
     clipboard->setMimeData(data);
 }
 
-void cutFilesToClipboard(const Fm::FilePathList& files) {
-    QClipboard* clipboard = QApplication::clipboard();
-    QMimeData* data = new QMimeData();
-    QByteArray ba;
-    auto urilist = pathListToUriList(files);
+void copyFilesToClipboard(const Fm::FilePathList& files) {
+    setFilesToClipboard(files, false);
+}
 
-    // Add current pid to trace cut/copy operations to current app
-    data->setData(QStringLiteral("text/x-libfmqt-pid"), ba.setNum(QCoreApplication::applicationPid()));
-    // Gnome, LXDE, and XFCE
-    // Note: the standard text/urilist format uses CRLF for line breaks, but gnome format uses LF only
-    data->setData("x-special/gnome-copied-files", QByteArray("cut\n") + urilist.replace("\r\n", "\n"));
-    // The KDE way
-    data->setData("text/uri-list", urilist);
-    data->setData(QStringLiteral("application/x-kde-cutselection"), QByteArrayLiteral("1"));
-    clipboard->setMimeData(data);
+void cutFilesToClipboard(const Fm::FilePathList& files) {
+    setFilesToClipboard(files, true);
 }
 
 bool isCurrentPidClipboardData(const QMimeData& data) {

... the problem with nautilus is, that it doesn't allow the trailing '\n' in x-special/gnome-copied-files after the last file -> it parses and uses an empty string as file URI and fails at some internal assertion then. In the patch above I've changed the x-special/gnome-copied-files assembly to strip the trailing '\n'.

But I wasn't able to reproduce the crash of pcmanfm-qt/libfm-qt...

UPDATE:
https://github.com/lxde/libfm-qt/tree/clipboard_fixes

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

@palinek I don't understand how https://github.com/lxde/libfm-qt/tree/clipboard_fixes may prevent a crash in Naultilus!

As for a crash in libfm-qt, the only possibility that comes to my mind is that, somehow, _fm_path_finalize() (in libfmfm-path.c) may be called early -- something like lxde/libfm#19.

@palinek
Copy link
Contributor

palinek commented Nov 21, 2017

I don't understand how https://github.com/lxde/libfm-qt/tree/clipboard_fixes may prevent a crash in Naultilus!

Because nautilus doesn't expect, that the data in x-special/gnome-copied-files may have a trailing '\n'.
E.g.:

  • current master libfm-qt assembles it: cut\nfile:///home/foo/tmp/bla\n
  • nautilus assembles it: cut\nfile:///home/foo/tmp/bla

=> so if file(s) is/are cut in pcmafm-qt/libfm-qt ... nautilus parses it as the last one file being an empty string ... and somewhere deeper in the code is assertion that the file can't be empty string ... that's all

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

OK. A workaround for Nautilus in libfm-qt! I'm a little suspicious but if it has no side effect....

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

Oh, I'm very suspicious now:

I cut a file in pcmanfm-qt and pasted it in spacefm. Everything was OK. After that, I installed that crap that's called Nautilus and run it from terminal. Crash:

ERROR:../nautilus/src/nautilus-file.c:584:nautilus_file_new_from_filename: assertion failed: (filename[0] != '\0')
Aborted (core dumped)

And the trace:

#0  0x00007ff9c33128a0 in raise () at /usr/lib/libc.so.6
#1  0x00007ff9c3313f09 in abort () at /usr/lib/libc.so.6
#2  0x00007ff9c2e15c06 in g_assertion_message () at /usr/lib/libglib-2.0.so.0
#3  0x00007ff9c2e15fcc in g_assertion_message_expr () at /usr/lib/libglib-2.0.so.0
#4  0x00005575c2d3a6f2 in  ()
#5  0x00005575c2d3a8d5 in nautilus_file_list_from_uri_list ()
#6  0x00005575c2dd45e0 in  ()
#7  0x00007ff9c284ca8c in  () at /usr/lib/libgtk-3.so.0
#8  0x00007ff9c0df26f5 in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
#9  0x00007ff9c0e060b0 in  () at /usr/lib/libgobject-2.0.so.0
#10 0x00007ff9c0e0a696 in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#11 0x00007ff9c0e0b62c in g_signal_emit_by_name () at /usr/lib/libgobject-2.0.so.0
#12 0x00007ff9c2760f65 in  () at /usr/lib/libgtk-3.so.0
#13 0x00007ff9c27651d0 in  () at /usr/lib/libgtk-3.so.0
#14 0x00007ff9c26d01f8 in  () at /usr/lib/libgtk-3.so.0
#15 0x00007ff9c0e0ac01 in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#16 0x00007ff9c0e0b920 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#17 0x00007ff9c2823385 in  () at /usr/lib/libgtk-3.so.0
#18 0x00007ff9c26cf130 in gtk_main_do_event () at /usr/lib/libgtk-3.so.0
#19 0x00007ff9c21d79f6 in  () at /usr/lib/libgdk-3.so.0
#20 0x00007ff9c220a375 in  () at /usr/lib/libgdk-3.so.0
#21 0x00007ff9c2e20270 in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
#22 0x00007ff9c2e21f69 in  () at /usr/lib/libglib-2.0.so.0
#23 0x00007ff9c2e21fae in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#24 0x00007ff9c10735ae in g_application_run () at /usr/lib/libgio-2.0.so.0
#25 0x00005575c2d00102 in main ()

I don't think it's worth changing libfm-qt.

@palinek
Copy link
Contributor

palinek commented Nov 21, 2017

Yes, that's the trace...:

#0  0x00007f9cd951bfff in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007f9cd951d42a in __GI_abort () at abort.c:89
#2  0x00007f9cdd3d97cd in g_assertion_message () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f9cdd3d985a in g_assertion_message_expr () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x0000561b981ec621 in nautilus_file_new_from_filename (self_owned=1, filename=0x561b9958e520 "", directory=0x561b99493ad0) at ../src/nautilus-file.c:584
#5  0x0000561b981ec621 in nautilus_file_get_internal (location=location@entry=0x7f9cb001eaf0, create=create@entry=1) at ../src/nautilus-file.c:763
#6  0x0000561b981ecf3a in nautilus_file_get (location=location@entry=0x7f9cb001eaf0) at ../src/nautilus-file.c:784
#7  0x0000561b981eab03 in nautilus_file_list_from_uri_list (uris=<optimized out>) at ../src/nautilus-file-utilities.c:884
#8  0x0000561b9826ad6b in on_clipboard_contents_received (clipboard=<optimized out>, selection_data=<optimized out>, user_data=<optimized out>)
    at ../src/nautilus-canvas-view.c:816
#9  0x00007f9cdcdfe549 in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#10 0x00007f9cdb3bbf9d in g_closure_invoke () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#11 0x00007f9cdb3cecae in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#12 0x00007f9cdb3d7485 in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#13 0x00007f9cdb3d8378 in g_signal_emit_by_name () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#14 0x00007f9cdcd18af3 in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#15 0x00007f9cdcd1cbcd in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#16 0x00007f9cdcc8bfc7 in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#17 0x00007f9cdb3bc1d6 in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#18 0x00007f9cdb3d713d in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#19 0x00007f9cdb3d7e9f in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#20 0x00007f9cdcdd6094 in  () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#21 0x00007f9cdcc8af5e in gtk_main_do_event () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#22 0x00007f9cdc799085 in  () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#23 0x00007f9cdc7ca7f2 in  () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#24 0x00007f9cdd3b2f67 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#25 0x00007f9cdd3b31a0 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#26 0x00007f9cdd3b322c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#27 0x00007f9cdb6a0bed in g_application_run () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#28 0x0000561b981b69ec in main (argc=1, argv=0x7ffded3e0638) at ../src/nautilus-main.c:102

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

We shouldn't do anything for it, IMO.

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

I repeated the same test with Thunar: Everything is OK.

Let Nautilus' devs fix that if they want to.

@palinek
Copy link
Contributor

palinek commented Nov 21, 2017

We shouldn't fix anything in it, IMO.

I think there is no problem by not assembling the trailing '\n' in libfm-qt.

Btw. the spacefm-gtk3 makes nautilus crash the very same way as libfm-qt does.

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

Btw. the spacefm-gtk3 makes nautilus crash the very same way as libfm-qt

Yes!

I think there is no problem by not assembling the trailing '\n' in libfm-qt.

We can't be sure about probable consequences completely. As I said before, in my opinion, Nautilus's problem is Nautilus's -- no joke!

@damianatorrpm
Copy link
Contributor Author

sorry about this path then (btw. the title was meant more as a joke).
I was sure this is some libfm-qt only implementation detail as I haven't been able to use cut/paste successfully using the library yet (without crashing). I will try the clipboard-fix branch-later

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

I also think this bug is introduced in Nautilus recently -- otherwise, something like this would be reported a long time ago.

@tsujan
Copy link
Member

tsujan commented Nov 21, 2017

BTW, cut/copy/paste between Nautilus and Dolphin is fun ;)

@agaida
Copy link
Member

agaida commented Nov 21, 2017

/me facepalm :P

@tsujan
Copy link
Member

tsujan commented Jan 18, 2018

Closing because this isn't our bug.

@tsujan tsujan closed this as completed Jan 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants