diff --git a/src/main.c b/src/main.c index 6c027acf..fb90b590 100644 --- a/src/main.c +++ b/src/main.c @@ -23,7 +23,10 @@ void handle_error(int signo) { sprintf(msg, "Error occured (%d)! Quitting...\n", signo); write(STDERR_FILENO, msg, strlen(msg)); keepRunning = 0; - exit(EXIT_FAILURE); + /* _exit(), not exit(): from a signal handler only async-signal-safe + calls are allowed, and skipping the atexit handlers leaves the + watchdog armed so a crash still ends in a reset */ + _exit(EXIT_FAILURE); } void handle_exit(int signo) { diff --git a/src/watchdog.c b/src/watchdog.c index 1db88774..2143edb9 100644 --- a/src/watchdog.c +++ b/src/watchdog.c @@ -21,6 +21,12 @@ int watchdog_start(int timeout) { ioctl(fd, WDIOC_SETTIMEOUT, &timeout); + /* Disarm on any normal exit from here on, including the error returns + out of main(), so a startup failure does not end in a reset. A fatal + signal leaves through _exit() in handle_error() and keeps it armed. + watchdog_stop() is safe to call twice. */ + atexit(watchdog_stop); + HAL_INFO("watchdog", "Watchdog started!\n"); return EXIT_SUCCESS; }