gtkglsink: invalid read when window survives the sink
To reproduce:
- Run example below in valgrind
- Resize the GTK window
- Valgrind should raise invalid read errors
Looks like the widget tries to access the destroyed sink so we probably needs to turn some pointers to weak or strong refs.
==14255== Invalid read of size 4
==14255== at 0x552DCE9: g_mutex_lock (in /usr/lib64/libglib-2.0.so.0.6000.5)
==14255== by 0x6C0278B: _size_changed_cb (gstgtkglsink.c:127)
==14255== by 0x5449741: g_closure_invoke (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x545D4F3: ??? (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x546634D: g_signal_emit_valist (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x5466972: g_signal_emit (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x4C406DE: gtk_widget_size_allocate_with_baseline (in /usr/lib64/libgtk-3.so.0.2404.6)
==14255== by 0x4C56B5A: ??? (in /usr/lib64/libgtk-3.so.0.2404.6)
==14255== by 0x5449741: g_closure_invoke (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x545D638: ??? (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x546634D: g_signal_emit_valist (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x5466972: g_signal_emit (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x4C406DE: gtk_widget_size_allocate_with_baseline (in /usr/lib64/libgtk-3.so.0.2404.6)
==14255== by 0x4C574BE: ??? (in /usr/lib64/libgtk-3.so.0.2404.6)
==14255== by 0x5449995: ??? (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x54661C7: g_signal_emit_valist (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x5466972: g_signal_emit (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x4A20769: ??? (in /usr/lib64/libgtk-3.so.0.2404.6)
==14255== by 0x5449995: ??? (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x54661C7: g_signal_emit_valist (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== Address 0x74e8358 is 552 bytes inside a block of size 1,528 free'd
==14255== at 0x484BA0C: free (vg_replace_malloc.c:540)
==14255== by 0x54E7D8C: g_free (in /usr/lib64/libglib-2.0.so.0.6000.5)
==14255== by 0x55006C3: g_slice_free1 (in /usr/lib64/libglib-2.0.so.0.6000.5)
==14255== by 0x546D345: g_type_free_instance (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x1102C204: gst_gl_sink_bin_finalize (gstglsinkbin.c:275)
==14255== by 0x544ECEF: g_object_unref (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x55FBCB5: gst_bin_remove_func (gstbin.c:1809)
==14255== by 0x55FAD67: gst_bin_remove (gstbin.c:1871)
==14255== by 0x55FAFF2: gst_bin_dispose (gstbin.c:527)
==14255== by 0x544EC67: g_object_unref (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x11B99E: <glib::object::MemoryManager as glib::shared::SharedMemoryManager<gobject_sys::GObject>>::unref (object.rs:385)
==14255== by 0x11A495: <glib::shared::Shared<T,MM> as core::ops::drop::Drop>::drop (shared.rs:296)
==14255== by 0x11204E: core::ptr::real_drop_in_place (mod.rs:197)
==14255== by 0x1122ED: core::ptr::real_drop_in_place (mod.rs:197)
==14255== by 0x1123DD: core::ptr::real_drop_in_place (mod.rs:197)
==14255== by 0x113401: bug::main (bug.rs:29)
==14255== by 0x11259F: std::rt::lang_start::{{closure}} (rt.rs:64)
==14255== by 0x125082: {{closure}} (rt.rs:49)
==14255== by 0x125082: std::panicking::try::do_call (panicking.rs:294)
==14255== by 0x126B19: __rust_maybe_catch_panic (lib.rs:82)
==14255== by 0x125B3C: try<i32,closure> (panicking.rs:273)
==14255== by 0x125B3C: catch_unwind<closure,i32> (panic.rs:388)
==14255== by 0x125B3C: std::rt::lang_start_internal (rt.rs:48)
==14255== Block was alloc'd at
==14255== at 0x484A80B: malloc (vg_replace_malloc.c:309)
==14255== by 0x54E7C98: g_malloc (in /usr/lib64/libglib-2.0.so.0.6000.5)
==14255== by 0x54FFFB5: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.6000.5)
==14255== by 0x55005DD: g_slice_alloc0 (in /usr/lib64/libglib-2.0.so.0.6000.5)
==14255== by 0x546CF79: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x544F42C: ??? (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x5450B14: g_object_new_with_properties (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x54516C0: g_object_new (in /usr/lib64/libgobject-2.0.so.0.6000.5)
==14255== by 0x562092A: gst_element_factory_create (gstelementfactory.c:372)
==14255== by 0x5620A9D: gst_element_factory_make (gstelementfactory.c:445)
==14255== by 0x1171C7: gstreamer::auto::element_factory::ElementFactory::make (element_factory.rs:179)
==14255== by 0x113031: bug::main (bug.rs:13)
==14255== by 0x11259F: std::rt::lang_start::{{closure}} (rt.rs:64)
==14255== by 0x125082: {{closure}} (rt.rs:49)
==14255== by 0x125082: std::panicking::try::do_call (panicking.rs:294)
==14255== by 0x126B19: __rust_maybe_catch_panic (lib.rs:82)
==14255== by 0x125B3C: try<i32,closure> (panicking.rs:273)
==14255== by 0x125B3C: catch_unwind<closure,i32> (panic.rs:388)
==14255== by 0x125B3C: std::rt::lang_start_internal (rt.rs:48)
==14255== by 0x112578: std::rt::lang_start (rt.rs:64)
==14255== by 0x1134D9: main (in /home/cassidy/dev/rust/karapulse/target/debug/bug)
use gstreamer as gst;
use gst::prelude::*;
use gtk::prelude::*;
fn main() {
gst::init().unwrap();
gtk::init().unwrap();
{
let pipeline = gst::Pipeline::new(None);
let src = gst::ElementFactory::make("videotestsrc", None).unwrap();
let gtkglsink = gst::ElementFactory::make("gtkglsink", None).unwrap();
let glsinkbin = gst::ElementFactory::make("glsinkbin", None).unwrap();
glsinkbin.set_property("sink", >kglsink).unwrap();
let window = gtk::Window::new(gtk::WindowType::Toplevel);
let widget = gtkglsink.get_property("widget").unwrap();
let widget = widget.get::<gtk::Widget>().unwrap();
window.add(&widget);
window.set_size_request(800, 600);
window.show_all();
pipeline.add_many(&[&src, &glsinkbin]).unwrap();
src.link(&glsinkbin).unwrap();
pipeline.set_state(gst::State::Playing).unwrap();
pipeline.set_state(gst::State::Null).unwrap();
}
gtk::main();
}
Edited by Guillaume Desmottes