I added some PX4_INFO and PX4_DEBUG lines and found why mavlink fails to stop.,
INFO [cdcacm_autostart] VBUS present → absent (state=2 protocol=1)
INFO [cdcacm_autostart] connected: VBUS lost, requesting MAVLink stop
INFO [cdcacm_autostart] MAVLink stop: exec command on /dev/ttyACM0 (state_connected VBUS-lost) ERROR 139083441 MAVLink stop: dispatch failed (pid=-1 errno=128 Transport endpoint is not connected)
DEBUG 139583615 state_disconnecting
INFO [cdcacm_autostart] USB disconnect: serdis_main() start
serdis: Disconnected
INFO [cdcacm_autostart] USB disconnect: serdis_main() done
errno=128 (ENOTCONN) proves the USB transport is already physically gone before cdcacm even tries to dispatch. exec_builtin can’t spawn the task because the endpoint is dead.
But Mavlink receiver already has ENOTCONN handling.
In mavlink_receiver.cpp line 3174
if (nread == -1 && errno == ENOTCONN) { // Not connected (can happen for USB)
usleep(100000); // just sleeps and retries forever!
}
Mavlink receiver detects ENOTCONN but never stops — it just sleeps 100ms and loops back. This creates a zombie mavlink instance on a dead fd.
Here is the complete picture.
USB unplugged → CDC/ACM marks ENOTCONN immediately
Can you send me the full hardfault from SD card as well as the px4 file and elf file that you’re using? That will help me debug this. The elf file needs to be the exact one that you used to reproduce.
From the git hash I also can’t tell exactly what you’re trying, so we really need to be really exact here.