Caught signal SIGSEGV when RTMP streaming server restart
Created by: nashiracn
Overview
I use PyAV to streaming video to RTMP server, when server restart, PyAV crashed with signal SIGSEGV.
Expected behavior
do not crash
Actual behavior
Traceback:
Investigation
file av/container/output.pyx
method close_output()
called twince. one is container.close()
, another is container. __dealloc__ ()
。
On first calling, self.err_check(lib.av_write_trailer(self.ptr))
rasie an Exception, so self._done
not changed. but in libavformat av_write_trailer()
freed AVFormatContext.priv_data
。
On second calling, av_write_trailer() -> flv_write_trailer()
will access AVFormatContext.priv_data
which caught signal SIGSEGV
I mopdified av/container/output.pyx
, I looks well:
diff --git a/av/container/output.pyx b/av/container/output.pyx
index 8781958..bdc756d 100644
--- a/av/container/output.pyx
+++ b/av/container/output.pyx
@@ -19,7 +19,10 @@ cdef close_output(OutputContainer self):
cdef Stream stream
if self._started and not self._done:
- self.err_check(lib.av_write_trailer(self.ptr))
+ try:
+ self.err_check(lib.av_write_trailer(self.ptr))
+ except Exception as ex:
+ pass
for stream in self.streams:
stream.codec_context.close()
Reproduction
- streaming to a RTMP server
- restart RTMP server
- container.close() twice
Versions
- OS: Debian 10.3
- PyAV runtime:
PyAV v7.0.2.dev0
git origin: git@github.com:mikeboers/PyAV
git commit: v6.2.0-132-gd9bebbd
library configuration: --disable-doc --disable-x86asm --enable-shared --disable-stripping
library license: LGPL version 2.1 or later
libavcodec 58. 76.100
libavdevice 58. 9.103
libavfilter 7. 77.100
libavformat 58. 42.100
libavutil 56. 42.101
libswresample 3. 6.100
libswscale 5. 6.101
- PyAV build:
running config
PyAV: 7.0.2.dev0 v6.2.0-132-gd9bebbd
Python: 3.7.3 (default, Dec 20 2019, 18:57:59) \n[GCC 8.3.0]
platform: Linux-4.19.0-8-amd64-x86_64-with-debian-10.3
extension_extra:
include_dirs: [b'include', b'/usr/local/include']
libraries: [b'avformat', b'avcodec', b'avdevice', b'avutil', b'avfilter', b'swscale', b'swresample']
library_dirs: [b'/usr/local/lib']
define_macros: []
runtime_library_dirs: []
config_macros:
PYAV_COMMIT_STR="v6.2.0-132-gd9bebbd"
PYAV_VERSION=7.0.2.dev0
PYAV_VERSION_STR="7.0.2.dev0"
- FFmpeg:
ffmpeg version N-97033-gc455a28a9e Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --disable-doc --disable-x86asm --enable-shared --disable-stripping
libavutil 56. 42.101 / 56. 42.101
libavcodec 58. 76.100 / 58. 76.100
libavformat 58. 42.100 / 58. 42.100
libavdevice 58. 9.103 / 58. 9.103
libavfilter 7. 77.100 / 7. 77.100
libswscale 5. 6.101 / 5. 6.101
libswresample 3. 6.100 / 3. 6.100
Research
I have done the following:
-
Checked the PyAV documentation -
Searched on Google -
Searched on Stack Overflow -
Looked through old GitHub issues