GNOME Bugzilla – Bug 350776
Crash closing gedit with something on the clipboard
Last modified: 2007-07-26 23:36:35 UTC
What were you doing when the application crashed? Closed gedit after viewing a text file Distribution: Gentoo Base System version 1.6.14 Gnome Release: 2.15.91 2006-08-09 (JHBuild) BugBuddy Version: 2.15.90 Memory status: size: 104738816 vsize: 0 resident: 104738816 share: 0 rss: 20811776 rss_rlim: 0 CPU usage: start_time: 1155228448 rtime: 0 utime: 664 stime: 0 cutime:638 cstime: 0 timeout: 26 it_real_value: 0 frequency: 0 Backtrace was generated from '/usr/bin/gedit' Using host libthread_db library "/lib/tls/libthread_db.so.1". `system-supplied DSO at 0xffffe000' has disappeared; keeping its symbols. [Thread debugging using libthread_db enabled] [New Thread 1865635504 (LWP 7631)] 0xffffe410 in __kernel_vsyscall ()
+ Trace 70204
Thread 1 (Thread 1865635504 (LWP 7631))
Bug 165992 has a very similar stack trace. Cause of the crash were too many unrefs. Good trace, confirming
*** Bug 351160 has been marked as a duplicate of this bug. ***
an applicatin bug like Bug 165992 ?
*** Bug 351243 has been marked as a duplicate of this bug. ***
*** Bug 351094 has been marked as a duplicate of this bug. ***
This only happens when you close gedit with something on the clipboard (sorry if i'm stating the obvious). I get this same stack trace path in Gedit 2.15.6
Can you guys explain us how to reproduce this crash step by step?
Created attachment 71169 [details] Full backtrace of hello, copy and exit Paolo, This works everytime for me: 1) open Gedit (default untitled document appears) 2) type "hello" 3) select "hello" and copy it to the clipboard (ctrl a, ctrl c) 4) close Gedit (close without saving, if you choose save the crash happens after the file is successfully saved before the crash occurs) If I don't copy anything to the clipboard (miss out step 3) everything is fine. The surrounding events seem to be arbitrary, if anything has been copied to the clipboard before Gedit is closed this crash occurs. I've attached my own backtraces (of the exact above steps) for good measure, until the original submitter can confirm this method.
I tried with both gedit 2.14.x from Dapper and gedit CVS HEAD, but I cannot reproduce the crash using the step you reported.
This didn't occur with gedit 2.14.x from Gentoo portage, it only starting occuring upon upgrade of Gnome to 2.15.x. I just checked gedit out of CVS and this occurs with CVS HEAD. I will emerge gedit 2.14.x from portage again and that should settle whether it's gedit or something else?
I just compiled gedit 2.14.4 from portage (which compiled fine against all the updated dependencies). gdb confirms it exits normally when I follow the exact same steps. Seems to be a glitch introduced in gedit 2.15.x. What else can I try?
can you try gedit from cvs HEAD, I think I fixed this a couple of days ago: the crash seems related to having G_FATAL_CRITICAL set and an assertion is triggered due to the fact that the window was not disposed correctly. Another useful piece of info is which plugins you have active. If you disable all plugins the crash goes away?
Got it! Systematically disabling and re-enabling the plugins revealed the culprit. This only occurs when the Snippets plugin is enabled. I'm guessing since the snippets plugin is written in python it opens up a whole new bunch of questions...
actually it confirms my point: python plugins cause some 'interesting' reference count issues :) It should be fixed in cvs head.
I'm not very familiar with CVS, I only get by with a few cvs commands... Does "cvs -z3 -d:pserver:anonymous@anoncvs.gnome.org:/cvs/gnome co gedit" checkout the HEAD tag?
yes, looks correct [1] once you have it checked out, you'll need to run ./autogen --prefix=/blah/blah instead of ./configure --prefix=/blah/blah [1]: as long as the pserver is still active, since I have an account I use ssh access so I am not sure of which is the pserver status... IIRC with pserver you also need cvs -z3 -d:pserver:anonymous@anoncvs.gnome.org:/cvs/gnome login before the checkout, if asked for a password just press enter.
I'm sorry to say it still happens in HEAD :| Could it be one of the python dependencies or glib/gtk python bindings?
I managed to reproduce. It's a refcounting issue: by setting a breakpoint in gedit_window_dispose() you may see that window->priv->manager still has a refcount even when the GeditWindow releases its references. This causes the UIManager to survive the finalization of the window and since finalizing the window instead deatroys the menus and the toolbar, when the survived uimanager tries to update its proxy widgets you get the assertion Gtk-CRITICAL **: gtk_container_foreach: assertion `GTK_IS_CONTAINER (container)' failed I still have no idea who is holding a ref to the UIManager and why this triggers only when there is something in the clipboard...
If this happens only when the snippets plugin is enables, probably the ref is held by the snippets plugin itself... just guessing!
*** Bug 352486 has been marked as a duplicate of this bug. ***
Jesse: could you please try to understand what is happening in the snippet plugin? It would be really nice to fix this for 2.16.
Well, I tried to reproduce it but I couldn't. I haven't been able to built gedit with gtk+-2.10 so my guess is that maybe this bug has been introduced by gtkrecent. The fact that it only happens with snippets enabled is then again very weird. I couldn't find anything at first glance in the snippets plugin that might trigger this (as far as I know all the references are dropped). Not being able to reproduce the bug isn't very handy in trying to solve this one. I'll try get my build environment fixed after the weekend.
I've poked at the issue a bit in the following way: in gdb break on window_init and look at the address of priv->manager, let's say it is 0x80eaaa0. You can then see who refs/unrefs the ui manager with b g_object_ref if _object==0x80eaaa0 b g_object_unref if _object==0x80eaaa0 With the above I could see that the issue is not caused by someone grabbing an extra ref, the ui manager has a ref of 2 both when putting something in the clipboard (crashing case) and when not using the clipboard. The two refs are owned by the window itself and the python plugin. The difference in the two cases is the timing at which the refs are released: in the crashing case:
+ Trace 71032
So I have no idea why this is triggered by the snippets+clipboard combination, but the python gc is run too late.
OK, some more analysis and a patch. The warning/crash has nothing to do with the clipboard nor with snippets specifically: as said above it happens because the python GC runs after the window has been destroyed. This happens when there is something in the clipboard because the clipboard does some magic and keeps the main loop alive, thus the GC is actually run from the queued idle, which however happens after the window has been destroyed. In the normal case (without stuff on the clipboard) this doesn't happen because gedit_python_shutdown() forces the GC to run immediately: as a proof with snippets plugin enabled just open two windows and close one and you'll see the same warning because also in this case we are not shutting python down. As for not being specific to snippets, it's actually External Tools (the other py plugin that we have which adds menus) that is doing something special preventing the warning: it is calling explicitely manager.ensure_update(), consuming the problematic ui_manager idle. A first way to solve this specific issue is to call gtk_ui_manager_ensure_update() explicitely in window::dispose() before we drop our ref to the manager, so that we consume all pending updates. However I prefer a more generic solution, for which I am attaching a patch: I modified gedit_python_garbage_collect() so that it *both* runs the GC immediately and schedules a collection in the idle, then I force the collection in window::dispose() *before* we drop our own refs. This way the GC forces python to drop its ref to the uimanager (and possibly other objects) before we drop our own.
Created attachment 71651 [details] [review] patch Here is the patch I am committing. Note that there is another important thing I didn't mention above: we need to run the GC both at the start of dispose() and at the end, after we dropped our own references.
It seems black magic to me... I wonder why we need all this workaround to make the Python GC to work. How is epiphany dealing with this problems? Are we sure we don't have broken code with regards to the management of windows life cycle?
I don't think it's black magic... well at least not too much: we recently added window::dispose because it's the right place to make sure refcont loops are broken. To do so we first make sure that there are no 'lingering' objectsm then we drop our own references and then we collect again to reap the objects that may have died after our unrefs. > Are we sure we don't have broken code with regards to the management of windows > life cycle? Well I am pretty sure we haven't regressed in this regard: we just run the GC more than once, but the run scheduked in the idle is still there. However this doesn't mean things are perfect: unfortunately sometimes the window is still not finalized, but this was the case also before the patch. I have investigated it quite a bit but couldn't come to a solution yet. It seems that it's once again a ref loop issue: if you watch the dispose function with py plugins disabled you'll see that it's run twice, while with python only just once, so there is something that keeps the window alive preventing its finalization.
*** Bug 441678 has been marked as a duplicate of this bug. ***