GNOME Bugzilla – Bug 539581
GEdit segfaults when using the FileBrowser plugin
Last modified: 2019-03-23 20:33:29 UTC
1. activate the file browser plugin 2. open a file in a directory with gedit 3. it will segfault 4. open the same file again or another file in the same directory 5. it will open correctly Then you can also 6. browse to another directory 7. goto 2 i.e. it will segfault regularly the first time you open a file in a directory. This does not happen if I disable the File Browser plugin and did not happen before the transition to GIO. I don't have much time to debug this, but from a quick debugging I found out it seemed to be a problem with the GCancellable used in the _enumerate_children () funcs in gedit-file-browser-store.c. Stacktrace: (gdb) bt full
+ Trace 201073
there is a similar stacktrace on https://bugs.launchpad.net/gedit/+bug/251384
I think the memory corruption comes from the fact that on startup and in other cases where filling the model for the first time is not fast enough to be already completed when the root of the tree changes, it happens that the async callback model_iterate_next_files_cb runs on nodes that have already been freed when emptying and refilling the model. In fact if you stick a g_assert (NODE_IS_DIR (parent)) at the start of that function it triggers. My theory is that the memory corruption could be due to the semantic of g_cancellable_cancel which are different from the old gnome-vfs cancel: the pending operation is not cancelled synchronously but just put in a "cancelled" state. Eventually the callback is called even if the operation has been cancelled, it just gets the "cancelled" gerror. Even if my theory is correct (which I am not sure) I have no idea which is the best way to adress this...
I think I understand now where the problem comes from. What happens is: 1. Async cancellable operation is started 2. Async operation runs in a thread and finishes 3. The async job schedules an idle func to run the callback for the operation in the main loop 4. Node gets freed, and cancellation is set on the GCancellable object 5. Callback gets run in the main loop, but cancellation is not noticed because the actual operation is already finished The solution to this is to double check the cancellation state in the callback functions by manually invoking g_cancellable_is_cancelled on the cancellable object.
Created attachment 115617 [details] [review] Explicit checking cancelled state in callbacks Attached patch fixes the problem of cancellation. Although I think this is actually a bug in gio. Checking the cancellation object manually should not be necessary in my opinion. The finish functions should return an error in this case.