After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 539581 - GEdit segfaults when using the FileBrowser plugin
GEdit segfaults when using the FileBrowser plugin
Status: RESOLVED FIXED
Product: gedit-plugins
Classification: Other
Component: General
git master
Other Linux
: Normal critical
: ---
Assigned To: Gedit maintainers
Gedit maintainers
Depends on:
Blocks:
 
 
Reported: 2008-06-22 12:05 UTC by Cosimo Cecchi
Modified: 2019-03-23 20:33 UTC
See Also:
GNOME target: ---
GNOME version: 2.23/2.24


Attachments
Explicit checking cancelled state in callbacks (4.08 KB, patch)
2008-07-31 12:09 UTC, jessevdk@gmail.com
committed Details | Review

Description Cosimo Cecchi 2008-06-22 12:05:27 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
  • #0 IA__g_object_ref
    at /build/buildd/glib2.0-2.17.2/gobject/gobject.c line 1718
  • #1 IA__g_io_scheduler_push_job
    at /build/buildd/glib2.0-2.17.2/gio/gioscheduler.c line 242
  • #2 IA__g_simple_async_result_run_in_thread
    at /build/buildd/glib2.0-2.17.2/gio/gsimpleasyncresult.c line 647
  • #3 g_file_enumerator_real_next_files_async
    at /build/buildd/glib2.0-2.17.2/gio/gfileenumerator.c line 609
  • #4 IA__g_file_enumerator_next_files_async
    at /build/buildd/glib2.0-2.17.2/gio/gfileenumerator.c line 326
  • #5 model_iterate_children_cb
    at gedit-file-browser-store.c line 2119
  • #6 IA__g_simple_async_result_complete
    at /build/buildd/glib2.0-2.17.2/gio/gsimpleasyncresult.c line 553
  • #7 complete_in_idle_cb
    at /build/buildd/glib2.0-2.17.2/gio/gsimpleasyncresult.c line 563
  • #8 g_idle_dispatch
    at /build/buildd/glib2.0-2.17.2/glib/gmain.c line 4168
  • #9 IA__g_main_context_dispatch
    at /build/buildd/glib2.0-2.17.2/glib/gmain.c line 2063
  • #10 g_main_context_iterate
    at /build/buildd/glib2.0-2.17.2/glib/gmain.c line 2696
  • #11 IA__g_main_loop_run
    at /build/buildd/glib2.0-2.17.2/glib/gmain.c line 2919
  • #12 gtk_main
    from /usr/lib/libgtk-x11-2.0.so.0
  • #13 main
    at gedit.c line 585

Comment 1 Sebastien Bacher 2008-07-24 16:29:00 UTC
there is a similar stacktrace on https://bugs.launchpad.net/gedit/+bug/251384
Comment 2 Paolo Borelli 2008-07-24 23:59:54 UTC
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...
Comment 3 jessevdk@gmail.com 2008-07-31 12:07:15 UTC
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.
Comment 4 jessevdk@gmail.com 2008-07-31 12:09:38 UTC
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.