Skip to content

Commit 3f7a291

Browse files
fix: delete FifoSources before RemoveSession on reconnect failure
When monitor->ShmValid() returns false and the reconnect attempt fails, the cleanup path erased the video_source/audio_source entries from their maps without deleting the FifoSource objects, then called RemoveSession on the MediaSession. Two problems: 1. ZoneMinderFifoSource is only stopped/joined in its destructor. erase() on a raw pointer leaks the object and leaves its read_thread_ and write_thread_ running. 2. The xop::H264Source / H265Source / AV1Source is owned by the MediaSession and gets destroyed inside RemoveSession. The orphaned FifoSource still holds a raw m_h264Source pointer set via setH264Source(); the next SPS NAL parsed by the still-running ReadRun thread calls H264Source::SetSPS on freed memory and crashes in std::vector::assign. Stack of the observed crash: H264Source::SetSPS H264Source.h:34 H264_ZoneMinderFifoSource::splitFrames zm_rtsp_server_fifo_h264_source.cpp:53 ZoneMinderFifoSource::getNextFrame zm_rtsp_server_fifo_source.cpp:265 ZoneMinderFifoSource::ReadRun zm_rtsp_server_fifo_source.cpp:59 Mirror the correct order already used by the "monitor went away" path above (lines 188-197) and by the shutdown path (lines 362-375): delete the FifoSources first so their dtors set stop_ and join the threads, then RemoveSession can safely destroy the H264Source. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent e8e39d2 commit 3f7a291

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

src/zm_rtsp_server.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,17 @@ int main(int argc, char *argv[]) {
207207
if (!monitor->connect()) {
208208
Warning("Couldn't connect to monitor %d", monitor->Id());
209209
if (sessions.find(monitor->Id()) != sessions.end()) {
210+
// Delete (not just erase) the FifoSources first: their dtors stop
211+
// and join the read/write threads. RemoveSession then destroys
212+
// the MediaSession which owns the xop H264/H265/AV1Source; any
213+
// still-running ReadRun thread holds a raw m_h264Source pointer
214+
// and will crash in SetSPS on the next SPS NAL.
210215
if (video_sources.find(monitor->Id()) != video_sources.end()) {
216+
delete video_sources[monitor->Id()];
211217
video_sources.erase(monitor->Id());
212218
}
213219
if (audio_sources.find(monitor->Id()) != audio_sources.end()) {
220+
delete audio_sources[monitor->Id()];
214221
audio_sources.erase(monitor->Id());
215222
}
216223
rtspServer->RemoveSession(sessions[monitor->Id()]->GetMediaSessionId());

0 commit comments

Comments
 (0)