gst-rtsp-server issueshttps://gitlab.freedesktop.org/gstreamer/gst-rtsp-server/-/issues2021-09-24T11:03:31Zhttps://gitlab.freedesktop.org/gstreamer/gst-rtsp-server/-/issues/136segfault when reusing a Bin in RTSPMediaFactory2021-09-24T11:03:31ZMinijacksonsegfault when reusing a Bin in RTSPMediaFactoryHello and thank you for this awesome library!
I think I have a reproducible segmentation fault when misusing `RTSPMediaFactory` in a subclass. I'm not very knowledgable in GStreamer, but I think the misuse comes from reusing a previousl...Hello and thank you for this awesome library!
I think I have a reproducible segmentation fault when misusing `RTSPMediaFactory` in a subclass. I'm not very knowledgable in GStreamer, but I think the misuse comes from reusing a previously "consumed" `gst::Bin` by returning it from `RTSPMediaFactoryImpl::create_element`. Here is the code to reproduce it, adapted from the RTSP with subclass example:
<details>
<summary>Rust code</summary>
```rust
use gst::glib;
use gstreamer as gst;
use gstreamer_rtsp as gst_rtsp;
use gstreamer_rtsp_server as gst_rtsp_server;
use gst::prelude::*;
use gst_rtsp_server::prelude::*;
// Create the bin before the call to `create_element`
fn precreate_bin() -> gst::Bin {
let bin = gst::Bin::new(None);
let src = gst::ElementFactory::make("videotestsrc", None).unwrap();
let enc = gst::ElementFactory::make("vp8enc", None).unwrap();
let pay = gst::ElementFactory::make("rtpvp8pay", Some("pay0")).unwrap();
src.set_property("is-live", &true).unwrap();
enc.set_property("deadline", &1i64).unwrap();
bin.add_many(&[&src, &enc, &pay]).unwrap();
gst::Element::link_many(&[&src, &enc, &pay]).unwrap();
bin
}
fn main() {
gst::init().unwrap();
let main_loop = glib::MainLoop::new(None, false);
let server = gst_rtsp_server::RTSPServer::new();
let mounts = server.get_mount_points().unwrap();
let factory = media_factory::Factory::default();
mounts.add_factory("/test", &factory);
let id = server.attach(None).unwrap();
println!(
"Stream ready at rtsp://127.0.0.1:{}/test",
server.get_bound_port()
);
main_loop.run();
glib::source_remove(id);
}
mod media_factory {
use super::*;
use gst_rtsp_server::subclass::prelude::*;
mod imp {
use super::*;
pub struct Factory {
precreated_bin: gst::Bin,
}
impl Default for Factory {
fn default() -> Self {
Factory {
// Store the Bin so it can be reused
precreated_bin: precreate_bin(),
}
}
}
#[glib::object_subclass]
impl ObjectSubclass for Factory {
const NAME: &'static str = "RsRTSPMediaFactory";
type Type = super::Factory;
type ParentType = gst_rtsp_server::RTSPMediaFactory;
}
impl ObjectImpl for Factory {}
impl RTSPMediaFactoryImpl for Factory {
fn create_element(
&self,
_factory: &Self::Type,
_url: &gst_rtsp::RTSPUrl,
) -> Option<gst::Element> {
// Provide our stored bin
// From my understanding, `clone` doesn't
// actually clone the object, but shares ownership
Some(self.precreated_bin.clone().upcast())
}
}
}
glib::wrapper! {
pub struct Factory(ObjectSubclass<imp::Factory>) @extends gst_rtsp_server::RTSPMediaFactory;
}
impl Default for Factory {
fn default() -> Factory {
glib::Object::new(&[]).expect("Failed to create factory")
}
}
}
```
</details>
To reproduce the segfault, simply open the stream `rtsp://localhost:8554/test`, close it, and open it again.
<details>
<summary>Terminal output</summary>
```
Stream ready at rtsp://127.0.0.1:8554/test
(bla:32039): GStreamer-CRITICAL **: 14:41:59.939: gst_ghost_pad_new: assertion '!gst_pad_is_linked (target)' failed
(bla:32039): GStreamer-CRITICAL **: 14:41:59.939: gst_pad_set_active: assertion 'GST_IS_PAD (pad)' failed
(bla:32039): GStreamer-CRITICAL **: 14:41:59.939: gst_element_add_pad: assertion 'GST_IS_PAD (pad)' failed
** (bla:32039): CRITICAL **: 14:41:59.939: gst_rtsp_stream_new: assertion 'GST_IS_PAD (pad)' failed
** (bla:32039): CRITICAL **: 14:41:59.939: gst_rtsp_stream_set_multicast_iface: assertion 'GST_IS_RTSP_STREAM (stream)' failed
** (bla:32039): CRITICAL **: 14:41:59.939: gst_rtsp_stream_set_max_mcast_ttl: assertion 'GST_IS_RTSP_STREAM (stream)' failed
** (bla:32039): CRITICAL **: 14:41:59.939: gst_rtsp_stream_set_bind_mcast_address: assertion 'GST_IS_RTSP_STREAM (stream)' failed
** (bla:32039): CRITICAL **: 14:41:59.939: gst_rtsp_stream_set_profiles: assertion 'GST_IS_RTSP_STREAM (stream)' failed
** (bla:32039): CRITICAL **: 14:41:59.939: gst_rtsp_stream_set_protocols: assertion 'GST_IS_RTSP_STREAM (stream)' failed
[1] 32039 segmentation fault (core dumped) cargo run
```
</details>
<details>
<summary>Backtrace</summary>
```
#0 0x00007fcb1af7353d in gst_rtsp_stream_set_retransmission_time () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#1 0x00007fcb1af5dad8 in gst_rtsp_media_create_stream () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#2 0x00007fcb1af5e215 in gst_rtsp_media_collect_streams () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#3 0x00007fcb1af64106 in default_construct () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#4 0x000055ea43028109 in <T as gstreamer_rtsp_server::subclass::rtsp_media_factory::RTSPMediaFactoryImplExt>::parent_construct::{{closure}} (
f=0x7fcb1af64090 <default_construct>)
at /home/minijackson/.cargo/git/checkouts/gstreamer-rs-79e52a2d27eb91a3/cd3d114/gstreamer-rtsp-server/src/subclass/rtsp_media_factory.rs:141
#5 0x000055ea43026367 in core::option::Option<T>::map (self=..., f=...)
at /home/minijackson/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:453
#6 0x000055ea43029a76 in <T as gstreamer_rtsp_server::subclass::rtsp_media_factory::RTSPMediaFactoryImplExt>::parent_construct (self=0x55ea438b70c0, factory=0x7fcb0ae397a8,
url=0x7fcb0ae397b8) at /home/minijackson/.cargo/git/checkouts/gstreamer-rs-79e52a2d27eb91a3/cd3d114/gstreamer-rtsp-server/src/subclass/rtsp_media_factory.rs:138
#7 0x000055ea43029648 in gstreamer_rtsp_server::subclass::rtsp_media_factory::RTSPMediaFactoryImpl::construct (self=0x55ea438b70c0, factory=0x7fcb0ae397a8, url=0x7fcb0ae397b8)
at /home/minijackson/.cargo/git/checkouts/gstreamer-rs-79e52a2d27eb91a3/cd3d114/gstreamer-rtsp-server/src/subclass/rtsp_media_factory.rs:25
#8 0x000055ea43027bd9 in gstreamer_rtsp_server::subclass::rtsp_media_factory::factory_construct (ptr=0x55ea438b7190, url=0x7fcb00009690)
at /home/minijackson/.cargo/git/checkouts/gstreamer-rs-79e52a2d27eb91a3/cd3d114/gstreamer-rtsp-server/src/subclass/rtsp_media_factory.rs:287
#9 0x00007fcb1af63afc in gst_rtsp_media_factory_construct () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#10 0x00007fcb1af5015a in find_media () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#11 0x00007fcb1af53111 in handle_request () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#12 0x00007fcb1af568bb in gst_rtsp_client_handle_message () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#13 0x00007fcb1aa878cf in gst_rtsp_source_dispatch_read () from /nix/store/...-gst-plugins-base-1.16.2/lib/libgstrtsp-1.0.so.0
#14 0x00007fcb1acb833e in g_main_context_dispatch () from /nix/store/...-glib-2.64.6/lib/libglib-2.0.so.0
#15 0x00007fcb1acb86f0 in g_main_context_iterate.isra () from /nix/store/...-glib-2.64.6/lib/libglib-2.0.so.0
#16 0x00007fcb1acb89c3 in g_main_loop_run () from /nix/store/...-glib-2.64.6/lib/libglib-2.0.so.0
#17 0x00007fcb1af799cf in do_loop () from /nix/store/...-gst-rtsp-server-1.16.2/lib/libgstrtspserver-1.0.so.0
#18 0x00007fcb1ace1c54 in g_thread_pool_thread_proxy () from /nix/store/...-glib-2.64.6/lib/libglib-2.0.so.0
#19 0x00007fcb1ace13ed in g_thread_proxy () from /nix/store/...-glib-2.64.6/lib/libglib-2.0.so.0
#20 0x00007fcb1aa3cead in start_thread () from /nix/store/...-glibc-2.31-74/lib/libpthread.so.0
#21 0x00007fcb1a825caf in clone () from /nix/store/...-glibc-2.31-74/lib/libc.so.6
```
</details>