FileChooserNative memory management issue
YaLTeR opened this issue · comments
Causes crashes on Flatpak and nothing happening on the host.
I believe it's dropped prematurely, see e.g. the demo code, the object is not unreffed after show()
.
use gio::prelude::*;
use gtk::prelude::*;
use std::env::args;
fn build_ui(application: >k::Application) {
let window = gtk::ApplicationWindow::new(application);
window.set_title("First GTK+ Program");
window.set_border_width(10);
window.set_position(gtk::WindowPosition::Center);
window.set_default_size(350, 70);
let button = gtk::Button::with_label("Click me!");
button.connect_clicked(|_| {
let file_chooser = gtk::FileChooserNativeBuilder::new()
.action(gtk::FileChooserAction::Open)
.title("Open something")
.build();
file_chooser.connect_response(move |file_chooser, response| {
eprintln!("{:?}", response);
file_chooser.destroy();
});
file_chooser.show();
// Uncomment to make it behave properly.
// use glib::translate::*;
// let _ = file_chooser.as_object_ref().to_glib_full();
});
window.add(&button);
window.show_all();
}
fn main() {
let application =
gtk::Application::new(Some("com.github.gtk-rs.examples.basic"), Default::default())
.expect("Initialization failed...");
application.connect_activate(|app| {
build_ui(app);
});
application.run(&args().collect::<Vec<_>>());
}
Causes crashes on Flatpak
Can you provide a backtrace of the crash (with debug symbols)? This really shouldn't crash and doesn't here, also doesn't give any valgrind warnings.
I believe it's dropped prematurely
Yes in your code above the file_chooser
is dropped right at the end of the clicked
signal handler. You probably want to keep it alive a bit longer until the user closes it in one way or another.
Why this behaves differently than other dialogs is not clear to me though. Other dialogs have their window owned by GTK and stay alive until they're explicitly destroyed.
Can you provide a backtrace of the crash (with debug symbols)?
I could if it didn't also crash gdb
itself when trying to do a backtrace... 😄 (I reported that here)
Here's as far as I can go before the gdb
crash:
#0 0x00007f8482f86615 in gtk_widget_get_display (widget=0x3500353500353537) at gtkwidget.c:11005
11005 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
#1 0x00007f8482fa8843 in gtk_window_unexport_handle (window=0x3500353500353537) at gtkwindow.c:13000
13000 if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
#2 0x00007f8482dcc24f in filechooser_portal_data_free (data=data@entry=0x55da0bcd5050) at gtkfilechoosernativeportal.c:83
83 gtk_window_unexport_handle (data->exported_window);
#3 0x00007f8482dcc9d4 in response_cb (connection=<optimized out>, sender_name=<optimized out>, object_path=<optimized out>, interface_name=<optimized out>, signal_name=<optimized out>, parameters=<optimized out>, user_data=0x55da0b966820) at gtkfilechoosernativeportal.c:175
175 filechooser_portal_data_free (data);
#4 0x00007f848285a88f in emit_signal_instance_in_idle_cb (data=0x7f8474019950) at ../gio/gdbusconnection.c:3777
3777 signal_instance->subscriber->callback (signal_instance->connection,
#5 0x00007f8482614c0e in g_main_dispatch (context=0x55da0b9108c0) at ../glib/gmain.c:3309
3309 need_destroy = !(* dispatch) (source, callback, user_data);
#6 g_main_context_dispatch (context=context@entry=0x55da0b9108c0) at ../glib/gmain.c:3974
3974 g_main_dispatch (context);
#7 0x00007f8482614fc0 in g_main_context_iterate (context=context@entry=0x55da0b9108c0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4047
4047 g_main_context_dispatch (context);
#8 0x00007f8482615063 in g_main_context_iteration (context=context@entry=0x55da0b9108c0, may_block=may_block@entry=1) at ../glib/gmain.c:4108
4108 retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF);
As discussed on IRC, the crash looks like a bug in the native file chooser implementation. It accesses an already freed pointer if the dialog is freed too fast, like here.
The issue that the dialog disappears immediately looks like an API ugliness in GTK and should be reported there to find out what the best way would be to keep the dialog alive long enough.