gtk-rs / gtk

DEPRECATED, use https://github.com/gtk-rs/gtk3-rs repository instead!
https://gtk-rs.org/
MIT License
1.24k stars 82 forks source link

set_sort_func for TreeModelSort panics #960

Closed cdepillabout closed 4 years ago

cdepillabout commented 4 years ago

I'm trying to use gtk::TreeSortableExtManual::set_sort_func on a TreeModelSort, but the callback appears to always panic at runtime.

I don't have a minimally reproducible error, but I do have a small change to my own code base that triggers this error:

https://github.com/cdepillabout/nix-query-tree-viewer/commit/fa5b6ed7557bd9b4c20dd9fafac8207a0f6b678b#diff-781f3944d3debcae5a68e2d54ca2f098R192

In my actual code base, I've worked around this by just coding up my own wrapper to gtk_sys::gtk_tree_sortable_set_sort_func based on the code for gtk::ListBoxExt::set_sort_func (which I had assumed was working correctly, because it is automatically generated):

https://github.com/cdepillabout/nix-query-tree-viewer/blob/d93a85929704b03deebb96c25dd3926aa50c0ccd/src/ui/stack/tree.rs#L40

Here is where I call it from:

https://github.com/cdepillabout/nix-query-tree-viewer/blob/d93a85929704b03deebb96c25dd3926aa50c0ccd/src/ui/stack/tree.rs#L188


Here's the backtrace when this error happens:

$ RUST_BACKTRACE=1 cargo run -- /nix/store/jymg0kanmlgbcv35wxd8d660rw0fawhv-hello-2.10.drv
...
thread 'main' panicked at 'assertion failed: self.is::<T>()', /home/illabout/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.9.1/src/object.rs:358:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1028
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1412
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:188
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:205
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:464
  11: std::panicking::begin_panic
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/panicking.rs:400
  12: glib::object::Cast::unsafe_cast
             at ./<::std::macros::panic macros>:3
  13: <O as gtk::tree_sortable::TreeSortableExtManual>::set_sort_func::trampoline
             at /home/illabout/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.8.0/src/tree_sortable.rs:180
  14: gtk_tree_model_sort_compare_func
  15: node_find_closest
  16: node_insert_sorted
  17: g_sequence_sort_iter
  18: g_sequence_sort
  19: gtk_tree_model_sort_sort_level
  20: gtk_tree_model_sort_sort_level
  21: <O as gtk::tree_sortable::TreeSortableExtManual>::set_sort_column_id
             at /home/illabout/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.8.0/src/tree_sortable.rs:147
  22: nix_query_tree_viewer::ui::stack::tree::change_sort_order
             at src/ui/stack/tree.rs:118
  23: nix_query_tree_viewer::ui::stack::change_sort_order
             at src/ui/stack.rs:22
  24: nix_query_tree_viewer::ui::set_sort_order
             at src/ui.rs:70
  25: nix_query_tree_viewer::ui::toolbar::handle_select_sort_order
             at src/ui/toolbar.rs:20
  26: nix_query_tree_viewer::ui::toolbar::connect_signals::{{closure}}
             at src/ui/toolbar.rs:49
  27: <O as gtk::auto::combo_box::ComboBoxExt>::connect_changed::changed_trampoline
             at /home/illabout/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.8.0/src/auto/combo_box.rs:1003
  28: _g_closure_invoke_va
  29: g_signal_emit_valist
  30: g_signal_emit
  31: gtk_combo_box_set_active_internal
  32: gtk_combo_box_set_active_iter
  33: gtk_combo_box_menu_activate
  34: g_cclosure_marshal_VOID__STRINGv
  35: _g_closure_invoke_va
  36: g_signal_emit_valist
  37: g_signal_emit
  38: item_activated_cb
  39: g_closure_invoke
  40: signal_emit_unlocked_R
  41: g_signal_emit_valist
  42: g_signal_emit
  43: gtk_widget_activate
  44: gtk_menu_shell_activate_item
  45: gtk_menu_shell_button_release
  46: _gtk_marshal_BOOLEAN__BOXEDv
  47: _g_closure_invoke_va
  48: g_signal_emit_valist
  49: g_signal_emit
  50: gtk_widget_event_internal
  51: propagate_event
  52: gtk_main_do_event
  53: _gdk_event_emit
  54: gdk_event_source_dispatch
  55: g_main_context_dispatch
  56: g_main_context_iterate.isra.26
  57: g_main_context_iteration
  58: g_application_run
  59: <O as gio::application::ApplicationExtManual>::run
             at /home/illabout/.cargo/registry/src/github.com-1ecc6299db9ec823/gio-0.8.0/src/application.rs:23
  60: nix_query_tree_viewer::ui::run
             at src/ui.rs:153
  61: nix_query_tree_viewer::default_main
             at src/lib.rs:8
  62: nix_query_tree_viewer::main
             at src/bin/nix-query-tree-viewer.rs:4
  63: std::rt::lang_start::{{closure}}
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
  64: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:48
  65: std::panicking::try::do_call
             at src/libstd/panicking.rs:287
  66: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
  67: std::panicking::try
             at src/libstd/panicking.rs:265
  68: std::panic::catch_unwind
             at src/libstd/panic.rs:396
  69: std::rt::lang_start_internal
             at src/libstd/rt.rs:47
  70: std::rt::lang_start
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
  71: main
  72: __libc_start_main
  73: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Let me know if you need a backtrace in gdb or anything else.

The line that is actually causing the problem is the following:

https://github.com/gtk-rs/gtk/blob/54e0a9bc2593e6d83515602ff4625d154a733107/src/tree_sortable.rs#L180

I'm not sure what could be going on here. It seems reasonable to get a gtk::TreeModelSort from a gtk::TreeModel.

sdroege commented 4 years ago

Curious, every tree sortable must be a tree model so that should work.

Any chance you can try to produce a testcase for this so we can reproduce it and analyze it in more detail? What is the type of this in the line that explodes?

BenjaminRi commented 4 years ago

I have the exact same problem. I wanted to implement a case-insensitive string sort for my column. It happens for the sortable TreeView of my log viewer tool https://github.com/BenjaminRi/Sherlog (note, the current sort function contains other problems because I've been messing with it), and even if I remove pretty much all the code from the comparison closure and add a println! in the beginning, it crashes before that println! is shown. I just stumbled across this issue and it's late now, but I may be able to construct a minimal reproducing case in the coming days.

GuillaumeGomez commented 4 years ago

@BenjaminRi That'd be super useful! :)

BenjaminRi commented 4 years ago

You can find the minimal repro in the following repository: https://github.com/BenjaminRi/sort_func_panic The panic happens as soon as you click the column header to trigger the sort operation. I hope it's the same problem, the stack trace looks pretty much the same.

sdroege commented 4 years ago

I can confirm the crash here

sdroege commented 4 years ago

And I have a fix

sdroege commented 4 years ago

@BenjaminRi In your code you write

    // https://github.com/gtk-rs/gtk/issues/701
    // Must insert at least one entry, or else it crashes on startup (different bug)

Commenting that code so that the model stays empty does not result in a crash here. Can you provide some more details for that separate bug?

BenjaminRi commented 4 years ago

@sdroege The information is all in the issue that I linked in the comment. It looks like it's caused by an underlying bug in the C implementation of GTK:

https://github.com/gtk-rs/gtk/issues/701

And if we follow down that line into the GTK bug tracker, we see that it's a Cairo bug:

https://gitlab.gnome.org/GNOME/gtk/issues/1333

and if we go into that bugtracker, we see that the issue is still open

https://gitlab.freedesktop.org/cairo/cairo/issues/338

sdroege commented 4 years ago

Ah, so it's Windows-specific. Makes sense that it doesn't happen for me then. Thanks :)

BenjaminRi commented 4 years ago

@sdroege Thank you for your good work. I did not expect such a fast reaction and fix.

sdroege commented 4 years ago

If there's a minimal testcase then these problems are usually easy to fix when you know where to look :)