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 729651 - Crash in GtkFileChooserButton with appears-as-list
Crash in GtkFileChooserButton with appears-as-list
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkFileChooser
3.15.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
Federico Mena Quintero
: 712582 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2014-05-06 14:18 UTC by andysem
Modified: 2017-08-27 20:11 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
ComboBox: Use iter before popdown() may invalidate (1.70 KB, patch)
2017-08-25 19:32 UTC, Daniel Boles
committed Details | Review

Description andysem 2014-05-06 14:18:52 UTC
Meld crashes on directory selection for directory comparison on Kubuntu. Steps to reproduce:

- Start meld.
- On the main screen select directory comparison mode.
- Select one of the directories to compare by choosing Other in one of the combo-boxes below.
- Meld crashes.

This problem have been reported multiple times:

Meld bug: https://bugzilla.gnome.org/show_bug.cgi?id=712582
KDE bug: https://bugs.kde.org/show_bug.cgi?id=326424

There are several backtraces and some analysis in these bugs. The problem appears at least in Kubuntu 13.10 and 14.04 x86_64.
Comment 1 Hugo Pereira Da Costa 2014-05-06 14:36:52 UTC
Note: the same crash also happens with gtk-demo, selecting "pickers" and trying to change the "folder" box to any value.
The crash happens with any widget theme, provided that GtkComboBox::appears-as-list = 1
Comment 2 Matthias Clasen 2014-05-08 00:15:41 UTC


  • #0 gtk_tree_model_get_valist
    at gtktreemodel.c line 1797
  • #1 gtk_tree_model_get
    at gtktreemodel.c line 1759
  • #2 combo_box_row_separator_func
    at gtkfilechooserbutton.c line 2344
  • #3 tree_column_row_is_sensitive
    at gtkcombobox.c line 2197
  • #4 gtk_combo_box_list_button_released
    at gtkcombobox.c line 3767
  • #5 _gtk_marshal_BOOLEAN__BOXED
    at gtkmarshalers.c line 85
  • #6 g_closure_invoke
    at gclosure.c line 768
  • #7 signal_emit_unlocked_R
    at gsignal.c line 3551
  • #8 g_signal_emit_valist
    at gsignal.c line 3317
  • #9 g_signal_emit
    at gsignal.c line 3363
  • #10 gtk_widget_event_internal
    at gtkwidget.c line 7229
  • #11 gtk_widget_event
    at gtkwidget.c line 6891
  • #12 propagate_event_up
    at gtkmain.c line 2406
  • #13 propagate_event
    at gtkmain.c line 2514
  • #14 gtk_main_do_event
    at gtkmain.c line 1735

Comment 3 Mauren 2014-05-24 18:06:37 UTC
I successfully reproduce this bug with the following test application, under Fedora 19 with KDE 4.11.5, GTK3 version 3.8.8.

However it crashes whenever I choose an item from the combo box, no matter what option I choose.

#include <gtk/gtk.h>

static void activate_main_window(GtkApplication *app, gpointer user_data) {
    GtkWidget *main_window = gtk_application_window_new(app);
    GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    GtkWidget *file_chooser = gtk_file_chooser_button_new("test",
        GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);

    gtk_container_add(GTK_CONTAINER(box),
        file_chooser);
    gtk_container_add(GTK_CONTAINER(main_window),
        box);

    gtk_widget_show_all(main_window);
}

int main(int argc, char **argv) {
    GtkApplication *app = gtk_application_new(NULL,
        G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate_main_window), NULL);

    g_application_run(G_APPLICATION(app), argc, argv);
    g_object_unref(app);

    return 0;
}
Comment 4 Mauren 2014-05-24 18:07:23 UTC
Backtrace from gdb

  • #0 gtk_tree_model_get_valist
    at gtktreemodel.c line 1765
  • #1 gtk_tree_model_get
    at gtktreemodel.c line 1727
  • #2 combo_box_row_separator_func
    at gtkfilechooserbutton.c line 2388
  • #3 tree_column_row_is_sensitive
    at gtkcombobox.c line 2188
  • #4 gtk_combo_box_list_button_released
    at gtkcombobox.c line 3753
  • #5 _gtk_marshal_BOOLEAN__BOXED
    at gtkmarshalers.c line 85
  • #6 g_closure_invoke
    at gclosure.c line 777
  • #7 signal_emit_unlocked_R
    at gsignal.c line 3584
  • #8 g_signal_emit_valist
    at gsignal.c line 3338
  • #9 g_signal_emit
    at gsignal.c line 3384
  • #10 gtk_widget_event_internal
    at gtkwidget.c line 6721
  • #11 gtk_widget_event
    at gtkwidget.c line 6378
  • #12 propagate_event_up
    at gtkmain.c line 2393
  • #13 propagate_event
    at gtkmain.c line 2501
  • #14 gtk_main_do_event
    at gtkmain.c line 1716
  • #15 gdk_event_source_dispatch
    at gdkeventsource.c line 364
  • #16 g_main_dispatch
    at gmain.c line 3054
  • #17 g_main_context_dispatch
    at gmain.c line 3630
  • #18 g_main_context_iterate
    at gmain.c line 3701
  • #19 g_main_context_iteration
    at gmain.c line 3762
  • #20 g_application_run
    at gapplication.c line 1623
  • #21 main
    at test.c line 22

Comment 5 kamil.rojewski+gnome 2015-02-11 19:51:40 UTC
For crying out loud, this bug is almost a year old and it's still 100% reproducible on Kubuntu 14.10. Don't you care your users have constant crashes?
Comment 6 Daniel Boles 2017-08-24 01:02:40 UTC
Please don't conflate the unnecessarily combative "don't care [about] your users" with the reality, which is 'have limited resources to debug the deprecated side of a baffling dual-mode widget'.

GtkComboBox would be confusing enough on its own, but the GTK+ 3 implementation where nearly every code path is conditional on the current mode does not exactly lend itself to swift diagnosis.
Comment 7 Daniel Boles 2017-08-24 01:23:41 UTC
fwiw, another for the pile


(a.out:455): Gtk-CRITICAL **: gtk_tree_model_filter_get_value: assertion 'GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp' failed

(a.out:455): GLib-GObject-WARNING **: /build/glib2.0-y6934K/glib2.0-2.42.1/./gobject/gtype.c:4221: type id '0' is invalid

(a.out:455): GLib-GObject-WARNING **: can't peek value table for type '<invalid>' which is not currently referenced

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7808477 in gtk_tree_model_get_valist (
    tree_model=tree_model@entry=0x967160, iter=iter@entry=0x7fffffffdb00, 
    var_args=var_args@entry=0x7fffffffd9b0)
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtktreemodel.c:1797
1797	/tmp/buildd/gtk+3.0-3.14.5/./gtk/gtktreemodel.c: No such file or directory.
(gdb) bt
  • #0 gtk_tree_model_get_valist
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtktreemodel.c line 1797
  • #1 gtk_tree_model_get
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtktreemodel.c line 1759
  • #2 combo_box_row_separator_func
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkfilechooserbutton.c line 2331
  • #3 tree_column_row_is_sensitive
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkcombobox.c line 2197
  • #4 gtk_combo_box_list_button_released
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkcombobox.c line 3771
  • #5 _gtk_marshal_BOOLEAN__BOXED
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkmarshalers.c line 85
  • #6 g_closure_invoke
    from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
  • #7 ??
    from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
  • #8 g_signal_emit_valist
    from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
  • #9 g_signal_emit
    from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
  • #10 gtk_widget_event_internal
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkwidget.c line 7773
  • #11 propagate_event_up
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkmain.c line 2424
  • #12 propagate_event
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkmain.c line 2526
  • #13 gtk_main_do_event
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkmain.c line 1748
  • #14 gdk_event_source_dispatch
    at /tmp/buildd/gtk+3.0-3.14.5/./gdk/x11/gdkeventsource.c line 364
  • #15 g_main_context_dispatch
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #16 ??
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #17 g_main_loop_run
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #18 gtk_main
    at /tmp/buildd/gtk+3.0-3.14.5/./gtk/gtkmain.c line 1207
  • #19 main

Comment 8 Daniel Boles 2017-08-24 01:42:12 UTC
[yes, I'm stuck on an ancient machine, but I doubt much has changed in the list-mode code since then]


$ valgrind ./a.out
==1882== Memcheck, a memory error detector
==1882== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1882== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==1882== Command: ./a.out
==1882== 

(a.out:1882): Gtk-CRITICAL **: gtk_tree_model_filter_get_value: assertion 'GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp' failed

(a.out:1882): GLib-GObject-WARNING **: /build/glib2.0-y6934K/glib2.0-2.42.1/./gobject/gtype.c:4221: type id '0' is invalid

(a.out:1882): GLib-GObject-WARNING **: can't peek value table for type '<invalid>' which is not currently referenced
==1882== Invalid read of size 8
==1882==    at 0x5119477: gtk_tree_model_get_valist (gtktreemodel.c:1797)
==1882==    by 0x5119798: gtk_tree_model_get (gtktreemodel.c:1759)
==1882==    by 0x4FB9AFD: combo_box_row_separator_func (gtkfilechooserbutton.c:2331)
==1882==    by 0x4F69744: tree_column_row_is_sensitive (gtkcombobox.c:2197)
==1882==    by 0x4F6F081: gtk_combo_box_list_button_released (gtkcombobox.c:3771)
==1882==    by 0x502234C: _gtk_marshal_BOOLEAN__BOXED (gtkmarshalers.c:85)
==1882==    by 0x6AF5244: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x6B06F6B: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x6B0F284: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x6B0F9DE: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x5152E33: gtk_widget_event_internal (gtkwidget.c:7773)
==1882==    by 0x501FD5D: propagate_event_up (gtkmain.c:2424)
==1882==    by 0x501FD5D: propagate_event (gtkmain.c:2526)
==1882==  Address 0x30 is not stack'd, malloc'd or (recently) free'd
==1882== 
==1882== 
==1882== Process terminating with default action of signal 11 (SIGSEGV)
==1882==  Access not within mapped region at address 0x30
==1882==    at 0x5119477: gtk_tree_model_get_valist (gtktreemodel.c:1797)
==1882==    by 0x5119798: gtk_tree_model_get (gtktreemodel.c:1759)
==1882==    by 0x4FB9AFD: combo_box_row_separator_func (gtkfilechooserbutton.c:2331)
==1882==    by 0x4F69744: tree_column_row_is_sensitive (gtkcombobox.c:2197)
==1882==    by 0x4F6F081: gtk_combo_box_list_button_released (gtkcombobox.c:3771)
==1882==    by 0x502234C: _gtk_marshal_BOOLEAN__BOXED (gtkmarshalers.c:85)
==1882==    by 0x6AF5244: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x6B06F6B: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x6B0F284: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x6B0F9DE: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4200.1)
==1882==    by 0x5152E33: gtk_widget_event_internal (gtkwidget.c:7773)
==1882==    by 0x501FD5D: propagate_event_up (gtkmain.c:2424)
==1882==    by 0x501FD5D: propagate_event (gtkmain.c:2526)
==1882==  If you believe this happened as a result of a stack
==1882==  overflow in your program's main thread (unlikely but
==1882==  possible), you can try to increase the size of the
==1882==  main thread stack using the --main-stacksize= flag.
==1882==  The main thread stack size used in this run was 8388608.
==1882== 
==1882== HEAP SUMMARY:
==1882==     in use at exit: 3,235,460 bytes in 38,815 blocks
==1882==   total heap usage: 312,626 allocs, 273,811 frees, 18,002,253 bytes allocated
==1882== 
==1882== LEAK SUMMARY:
==1882==    definitely lost: 21,814 bytes in 12 blocks
==1882==    indirectly lost: 28,093 bytes in 1,118 blocks
==1882==      possibly lost: 149,776 bytes in 2,130 blocks
==1882==    still reachable: 2,789,225 bytes in 34,198 blocks
==1882==         suppressed: 0 bytes in 0 blocks
==1882== Rerun with --leak-check=full to see details of leaked memory
==1882== 
==1882== For counts of detected and suppressed errors, rerun with: -v
==1882== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Killed
Comment 9 Daniel Boles 2017-08-24 02:07:11 UTC
FileChooserButton does shenanigans with its filtered model (TreeModelFilter) when ComboBox:popup-shown changes. I wonder if that makes the iterator that we get in gtk_combo_box_list_button_released() invalid - as we get it, then call popdown(), THEN try to select the iter. If so, UB means all bets are off beyond that point.


The testcase in bug 703511, which doesn't use FileChooserButton, /does/ also use a filtered model, though afaict all rows are always visible in the simple code path that still crashes, and nothing should make its filtered model be rebuilt.
Comment 10 Daniel Boles 2017-08-25 19:32:13 UTC
Created attachment 358441 [details] [review]
ComboBox: Use iter before popdown() may invalidate

Bad actors, such as our very own FileChooserButton, may connect to the
:popped-up property and alter the model as the menu becomes in/visible.

We were first getting an iter into the model while popped-up, then doing
popdown(), then using the iter, which may have just become invalidated
by the errant :popped-up handler. If so, crash city is the destination.

This is clearly bonkers, but until such patterns are removed, we have to
work around them. So, set_active() from the popped-up path while it is
known to be valid, by moving the call to set_active() before popdown().

While here, change set_active_iter(iter) to set_active_internal(path) to
avoid pointlessly going through the iter to get the path we already have

--

This seems to fix it for me - confirmation from other affected users appreciated
Comment 11 Daniel Boles 2017-08-25 19:37:39 UTC
(btw, this patch has no discernible effect on bug 703511)
Comment 12 Daniel Boles 2017-08-25 20:05:52 UTC
Comment on attachment 358441 [details] [review]
ComboBox: Use iter before popdown() may invalidate

pushed (with tweaks to commentary) to gtk-2-24 and gtk-3-22
Comment 13 Daniel Boles 2017-08-25 20:10:30 UTC
*** Bug 712582 has been marked as a duplicate of this bug. ***
Comment 14 Daniel Boles 2017-08-25 20:46:28 UTC
D'oh. Don't skip history class. I just realised this fix conflicts with the following commit (incompletely). So it may need to be reverted if that matters.

If so, consider this advance warning/apology for users on either side of this.

Anyway, re-breaking this might be a blessing in disguise in reality: Firstly, list mode has a host of other ugly bugs making it impractical for many other reasons, and it’s deprecated in GTK+ 3 and removed in 4.

Secondly, GtkFileChooserButton isn’t, so the real fix is to make it stop pulling the model out from underneath GtkComboBox while popping up/down. That is the real problem, albeit not one that lends itself to such simple 'fixes' as mine.


commit 097e3b0b1fd7d34887df3f03e2915a408a9c8f5b
Author: Matthias Clasen <mclasen@redhat.com>
Date:   Wed Mar 15 19:00:59 2006 +0000

    Popdown the list before changing the active iter, otherwise people will be
    
    2006-03-15  Matthias Clasen  <mclasen@redhat.com>
    
            * gtk/gtkcombobox.c (gtk_combo_box_list_button_released)
            (gtk_combo_box_list_key_press): Popdown the list before changing
            the active iter, otherwise people will be surprised by the
            grabs that are still in place when their ::changed handler
            runs.
Comment 15 andysem 2017-08-26 08:42:43 UTC
If the fix is reverted, please reopen the bug.
Comment 16 Daniel Boles 2017-08-27 20:11:56 UTC
Of course.

Anyway, I hope not to need to, and to push a patch that satisfies both sets of expectations simultaneously: https://bugzilla.gnome.org/show_bug.cgi?id=786835