srtsrc: segfault in fill()
I've come across an occasional SIGSEGV in srtsrc, occurring after minutes to hours of runtime. Source element is in caller mode. Difficult to reproduce reliably.
Reproduced in both 1.16.2 and master ( 4d585c64 ). libsrt version 1.4.1
Crashing pipeline:
srtsrc name=src uri=srt://10.128.1.7:9104 latency=200 ! tsparse set-timestamps=true ! queue ! tsdemux name=demux
queue name=vq ! decodebin ! queue ! xvimagesink
queue name=aq ! aacparse ! avdec_aac ! audioconvert ! queue ! pulsesink
demux. ! vq. demux. ! aq.
A more minimal testcase also breaks but seems to take much longer:
gst-launch-1.0 srtsrc name=src uri=srt://10.128.1.7:9104 ! queue ! tsparse set-timestamps=true ! queue ! fakesink sync=true
Source pipeline:
udpsrc (...) ! queue ! srtsink mode=2 localaddress=0.0.0.0 localport=9104
Source is a hardware mpegts encoder, the video is HEVC - no issues with a similar demux/decoding/presentation pipeline without srt. I can provide a dump of that stream on request if it would be helpful but I am assuming not for now.
Maxed loglevel produces uninteresting output, business as usual before the segfault and an unsurprising buffer overrun after:
(...)
0:14:22.175191609 26589 0x7fa760002920 LOG srtsrc gstsrtsrc.c:178:gst_srt_src_fill:<src> filled buffer from _get of size 1316, ts 99:99:99.999999999, dur 99:99:99.999999999, offset -1, offset_end -1
0:14:22.184894847 26589 0x7fa760002920 LOG srtsrc gstsrtsrc.c:178:gst_srt_src_fill:<src> filled buffer from _get of size 1316, ts 99:99:99.999999999, dur 99:99:99.999999999, offset -1, offset_end -1
Caught SIGSEGV
Spinning. Please run 'gdb gst-launch-1.0 26589' to continue debugging, Ctrl-C to quit, or Ctrl-\ to dump core.
15:17:01.346330/SRT:RcvQ:worker*E:SRT.c: %13603548:No room to store incoming packet: offset=0 avail=0 ack.seq=1171179725 pkt.seq=1171179725 rcv-remain=8191
15:17:01.346741/SRT:RcvQ:worker*E:SRT.c: %13603548:No room to store incoming packet: offset=1 avail=0 ack.seq=1171179725 pkt.seq=1171179726 rcv-remain=8191
Haven't had much luck reproducing it with gdb attached to a debug build due to performance issues, but do have a stacktrace:
(gdb) bt
#0 0x00007ffff7fc2053 in gst_srt_src_fill (src=0x55555585e3a0 [GstPushSrc|src], outbuf=0x7fff4b6bcea0) at ../gst-plugins-bad/ext/srt/gstsrtsrc.c:144
#1 0x00007ffff6f0d079 in gst_base_src_default_create (src=0x55555585e3a0 [GstBaseSrc|src], offset=<optimized out>, size=<optimized out>, buffer=0x7fffd4ff8d08)
at ../gstreamer/libs/gst/base/gstbasesrc.c:1539
#2 0x00007ffff6f0e4df in gst_base_src_get_range (src=src@entry=0x55555585e3a0 [GstBaseSrc|src], offset=offset@entry=18446744073709551615, length=<optimized out>, buf=buf@entry=0x7fffd4ff8de0)
at ../gstreamer/libs/gst/base/gstbasesrc.c:2530
#3 0x00007ffff6f13254 in gst_base_src_loop (pad=0x555555860080 [GstPad|src]) at ../gstreamer/libs/gst/base/gstbasesrc.c:2854
#4 0x00007ffff7ca15d9 in gst_task_func (task=0x555555899dd0 [GstTask|src:src]) at ../gstreamer/gst/gsttask.c:328
(...)
(gdb) info locals
(...)
err = 0x0
recv_len = <optimized out>
So err being null and recv_len negative seems like a classic edge outside the 'happy case' but I am having trouble determining which path through gst_srt_object_read is being taken to produce this result with no other log output. The typical failure cases of packet loss, jitter, disconnection, killing the other pipeline, etc don't seem to trigger this particular path.