Monitor::connect() returns false with shared_data still null on every one of
its failure paths: the mmap file cannot be opened (wrong ownership, e.g.
after a package upgrade), fstat fails, ftruncate cannot grow it (/dev/shm out
of space -- a container with the default 64MB tmpfs hits this quickly, since
one 720x480 monitor with 10 buffers already asks for ~20MB and a 1080x720 one
asks for ~62MB), or mmap itself fails.
zmc's startup loop reacts by retrying:
while (!monitor->connect() and !zm_terminate) {
Warning("Couldn't connect to monitor %d", monitor->Id());
monitor->SetHeartbeatTime(std::chrono::system_clock::now());
sleep(1);
}
so the first thing it does after a failed connect is write through the null
pointer. zmc dies with SIGSEGV at address 0x80 instead of retrying, which
presents as a monitor that will not start and a capture daemon that keeps
crashing. The accessors on either side of these already guard with
`if (shared_data && shared_data->valid)`.
Reverting the guard fails the new test with SIGSEGV at zm_monitor_shm.cpp:66,
and restoring it passes. Same fix as release-1.38's a550545e4.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBHBB95RBX7D9p8ge2WDZb