GNOME Bugzilla – Bug 163583
Sound Preferences hangs with keynav when gnopernicus is running.
Last modified: 2005-04-28 14:12:18 UTC
Using gnopernicus 0.9.17 and gnome-2.6 - Start gnopernicus (nothing needs to be enabled). - From the Launch menu, go to Preferences->Desktop Preferences->Sound - The Sound Preferences window will appear. - Make sure that the two checkboxes on the 'General' tab are checked - Navigate to the 'Sound Events' tab. - With focus on the tab label, press and hold the <down> arrow. - Notice that focus changes to the Sounds table and that the focus is moving through the table lines. At this point in time the Sound Preferences window hangs, focus is lost and nothing on the Sound Preferences window can be used. Sometimes instead, the window just disappears completely. This does not happen when gnopernicus is not running.
Does this happen if braille and brlmonitor are not used?
Yes.
Here's a sample backtrace: Starting program: /usr/bin/gnome-sound-properties [Thread debugging using libthread_db enabled] [New Thread 1088775680 (LWP 5801)] GTK Accessibility Module initialized Bonobo accessibility support initialized Program received signal SIGSEGV, Segmentation fault.
+ Trace 54370
Thread 1088775680 (LWP 5801)
reducing AP priority as this only occurs under stress. I'm not denying that it's a serious problem, but it can be reduced in frequency if key repeat is turned off. Problem seems to be refcount issue in gailtreeview (or possibly gtktreemodel).
The problem seems to be that we are referencing a cell_info object when traversing a list, in traverse_cells, while a g_object_unref notification is incoming. On receipt of the object-destroy message on a GailCell AtkObject, we call cell_destroyed. This may happen while we are traversing our internal cell cache, in which case we may call API on an object after it's been freed; while we remove the stale cell_info from our list inside cell_destroyed, we don't remove it from the list being traversed. From a lifecycle point of view, the problem seems to be that we don't, ourselves, increment the refcount of GailCell objects when we return them in gail_tree_view_ref_child. The reason for this is unclear, though a source code comment indicates that it is intentional. However I don't think it's right, since it results in the disposal of GailCells which we're holding in our cache, which we then must re-create on request. In any case something is going wrong with the lifecycle management of these objects. I attach a patch which increments the GailCell object ref count before returning from gail_tree_view_ref_child, and which decrements the object ref count inside clean_cell_info. It does stop the bug, and I don't see a resulting leak, although it does mean that once a GailCell has been requested by a client, we keep it in our cache as long as the corresponding GtkTreeview cell exists. This is admittedly an inefficiency for large tables; I'm not sure what the best solution is.
Created attachment 45557 [details] [review] patch which causes cells to persist once referenced, while alive
Created attachment 45642 [details] [review] improved patch which retains weak-ref lifecycle, but is reentrancy-safe
Created attachment 45780 [details] [review] improved patch which solves more (all?) of the problem more guards and checks for in_use flag were needed to make this method work, the previous patch could still segv in some circumstances.
Created attachment 45786 [details] [review] patch as committed, stopgap measure finally a patch that works - but it's become obvious that this can only be a stopgap measure until the gailtreeviewcell/gailcelll implementation is refactored. The current approach of not holding refs to the atkobjects in our cache doesn't work very well, since we need to call a fair bit of potentially-reenterant api inside our destroy handler using the current approach. The above patch fixes the immediate symptoms but it lacks elegance and generality.