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 732051 - Crash can result if a child widget is destroyed while its tab is being dragged
Crash can result if a child widget is destroyed while its tab is being dragged
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkNotebook
3.10.x
Other Linux
: Normal critical
: ---
Assigned To: gtk-bugs
gtk-bugs
: 732034 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2014-06-22 16:36 UTC by Tony Houghton
Modified: 2015-01-30 17:40 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GtkNotebook: Don't crash if the child disappeared during DND (1017 bytes, patch)
2015-01-26 13:28 UTC, Debarshi Ray
committed Details | Review

Description Tony Houghton 2014-06-22 16:36:46 UTC
If a child widget is destroyed while its tab is being dragged, this causes problems for the application when it receives a signal at the end of the drag ("create-window", "page-added", "page-reordered" etc) referring to a child widget that no longer exists. It typically results in a crash. This can be demonstrated in gnome-terminal and roxterm as described at <https://sourceforge.net/p/roxterm/bugs/105/>.

I don't think there's an easy way for an application to keep track of whether a tab is being dragged and thus avoid this problem, so please could GtkNotebook automatically cancel any drag if the child widget is destroyed.
Comment 1 Christian Persch 2014-08-16 17:29:20 UTC
*** Bug 732034 has been marked as a duplicate of this bug. ***
Comment 2 Egmont Koblinger 2014-08-21 15:49:16 UTC
Bumping severity to critical, according to bugzilla's help page.

I could not think of any way to work around the issue in gnome-terminal.  There seems to be no way to programatically cancel a pending DND event, and there's no way to query if a DND is in progress (to keep the terminal tab alive for the DND's duration), so the crash is inevitable.
Comment 3 Matthias Clasen 2014-12-22 15:18:02 UTC
I don't think it is ok for you to destroy the widget after you gave it to one of the notebook tab-adding functions. The notebook takes ownership of it.
Comment 4 Tony Houghton 2014-12-22 18:09:24 UTC
I disagree, a GtkContainer should be able to handle a child widget being destroyed without it being removed first. The docs for gtk_container_remove() actually recommend destroying without explicitly removing. And anyway, do we know that it's safe to call gtk_container_remove() or gtk_notebook_remove_page() on a page that's being dragged without triggering this same bug?
Comment 5 Christian Persch 2015-01-07 18:42:28 UTC
I have to concur with comment 4. How else is one supposed to handle this (other than disabling tab DND) ?
Comment 6 Egmont Koblinger 2015-01-10 14:02:52 UTC
The title of the bug is a bit misleading.

The widget is of course first removed from the notebook with gtk_container_remove(), and then destroyed.

Just as the notebook takes ownership on gtk_container_add(), it needs to release ownership on gtk_container_remove() (aborting the DND if necessary) so from this point on the caller is safe to destroy the object.

Or it should hold an extra ref while DNDing (but that'd lead to a more complex solution).
Comment 7 Debarshi Ray 2015-01-26 13:28:45 UTC
Created attachment 295447 [details] [review]
GtkNotebook: Don't crash if the child disappeared during DND
Comment 8 Debarshi Ray 2015-01-26 13:30:20 UTC
The fix for this looks simple to me and GtkNotebook is already careful enough to handle this in a few other places.

Reopening.
Comment 9 Egmont Koblinger 2015-01-26 15:06:35 UTC
Thanks Debarshi!

Tested with gtk+-3.12.2 I confirm that the originally reported crash is gone.  However, I've just discovered that the story is more complicated.

If you try to drop the ceased notebook over a gnome-terminal's terminal area, a "(gnome-terminal-server:12345): Gtk-CRITICAL **: gtk_selection_data_set: assertion 'length <= 0' failed" is printed.

If the whole source window disappears, sometimes (about 50% of the cases) I still see a segfault.  Open two gnome-terminal windows, in one of them have two tabs.  In both of these tabs execute something like "exec sleep 10".  Start dragging one of them (it's two possible cases depending on which one will terminate first; but I saw no substantial difference between these two cases).  Hold the dragged tab over noone's land (e.g. the desktop).  Wait until both tabs and hence the complete window (along with the notebook widget itself) disappears.  Then move the mouse over the remaining gnome-terminal window's terminal area.  As soon as the mouse enters there, I often get a segfault.
Comment 10 Egmont Koblinger 2015-01-26 15:19:22 UTC
(Without knowing anything about the code) I think it'd be a cleaner design and more robust solution (even against more complicated setups that I still haven't thought of) if gtk_container_remove() first triggered to execute whatever's executed when pressing Escape (except for the UI animation), that is, cancelled the pending DND operation first and then removed it.
Comment 11 Egmont Koblinger 2015-01-30 15:18:28 UTC
Fixed? Does this mean I should open a new bugreport for comment 9's finding?
Comment 12 Debarshi Ray 2015-01-30 16:42:59 UTC
(In reply to comment #9)

> If you try to drop the ceased notebook over a gnome-terminal's terminal area, a
> "(gnome-terminal-server:12345): Gtk-CRITICAL **: gtk_selection_data_set:
> assertion 'length <= 0' failed" is printed.

I can't get it to crash like that. I see these CRITICALS:

CRITICAL **: atk_selection_ref_selection: assertion 'ATK_IS_SELECTION (obj)' failed

Gtk-CRITICAL **: gtk_accessible_get_widget: assertion 'GTK_IS_ACCESSIBLE (accessible)' failed

Do you have a back trace?

> If the whole source window disappears, sometimes (about 50% of the cases) I
> still see a segfault.  Open two gnome-terminal windows, in one of them have two
> tabs.  In both of these tabs execute something like "exec sleep 10".  Start
> dragging one of them (it's two possible cases depending on which one will
> terminate first; but I saw no substantial difference between these two cases). 
> Hold the dragged tab over noone's land (e.g. the desktop).  Wait until both
> tabs and hence the complete window (along with the notebook widget itself)
> disappears.  Then move the mouse over the remaining gnome-terminal window's
> terminal area.  As soon as the mouse enters there, I often get a segfault.

I can't reproduce this. Back trace could be useful.
Comment 13 Matthias Clasen 2015-01-30 17:40:39 UTC
(In reply to comment #11)
> Fixed? Does this mean I should open a new bugreport for comment 9's finding?

I would appreciate testing with whats in master before any more bugs are filed. Bugs are not free...