casaroli opened a new pull request, #21440: URL: https://github.com/apache/nuttx/pull/21440
## Summary The default action of a signal that ends a process (SIGTERM, SIGINT, SIGSEGV, SIGKILL and the others of `CONFIG_SIG_SIGKILL_ACTION`) calls `group_kill_children()`. When `CONFIG_GROUP_KILL_CHILDREN_TIMEOUT_MS` is not 0 (the default is -1), `group_kill_children()` first sends SIGTERM to each other thread and waits until these threads exit. A thread that blocks SIGTERM does not exit. So the process does not end: with -1 it stays until that thread exits by itself, and with a timeout it ends only after the timeout. POSIX says that the default action terminates the whole process. - **sched/signal: Cancel the other threads at once in a default action.** The thread that does the default action sets `TCB_FLAG_FORCED_CANCEL` before it calls `group_kill_children()`, as the exception handlers of arm64, armv7-a, risc-v and x86_64 do before they call `_exit()`. `group_kill_children()` then does not send SIGTERM and cancels the other threads at once (`pthread_cancel()` / `nxtask_delete()` with the forced flag; `nxtask_terminate()` removes a thread that runs on another CPU). The Kconfig help of `CONFIG_GROUP_KILL_CHILDREN_TIMEOUT_MS` says that the default action does not use it. - **Documentation: The default action ends all threads of a task group.** One line in `Documentation/reference/user/07_signals.rst`. depends-on: apache/nuttx/pull/21436 ## Impact Only builds with `CONFIG_SIG_DEFAULT` and pthreads. A fatal signal with the default action now ends a process at once, also when another thread blocks or catches SIGTERM. The other threads no longer get a SIGTERM before they end: before, a SIGTERM handler of the process ran in the other threads when, for example, SIGINT ended the process. All build modes and architectures (common code); no change to an interface or a structure. `exit()`, `_exit()` and the task restart do not change: they still send SIGTERM first and wait as `CONFIG_GROUP_KILL_CHILDREN_TIMEOUT_MS` says. With the default -1, `exit()` in a process with a thread that blocks SIGTERM still waits until that thread exits (the test below shows it as INFO). ## Testing Test program `twothrterm`: the parent starts itself as a child for each case and measures how long the child lives. The main thread of the child blocks SIGTERM, sends it to the process and unblocks it. A second thread blocks all signals and either sleeps 5 s (`sleep`) or runs 5 s at a lower priority (`spin`; on SMP it runs on another CPU); if it gets to the end, it prints FAIL and exits with 9. PASS: the child ends in less than 3 s and not with 9. The `exit` case does the same with `exit()` in place of the signal (INFO, not counted). QEMU with HVF, `CONFIG_SIG_DEFAULT` and `CONFIG_SCHED_CHILD_STATUS`; the flat builds also with `CONFIG_CANCELLATION_POINTS`. Time from the start of the child to its end: | Configuration | Case | master | this PR | |---|---|---|---| | qemu-armv8a:knsh (kernel) | sleep | 5006 ms: FAIL | 108 ms: PASS | | qemu-armv8a:knsh (kernel) | spin | 5015 ms: FAIL | 108 ms: PASS | | qemu-armv8a:knsh (kernel) | exit (INFO) | 5011 ms | 5004 ms | | qemu-armv8a:nsh (flat) | sleep | 5002 ms: FAIL | 101 ms: PASS | | qemu-armv8a:nsh (flat) | spin | 5001 ms: FAIL | 101 ms: PASS | | qemu-armv8a:nsh (flat) | exit (INFO) | 5001 ms | 5001 ms | | qemu-armv8a:nsh_smp (flat, SMP, 2 CPUs) | sleep | 5003 ms: FAIL | 101 ms: PASS | | qemu-armv8a:nsh_smp (flat, SMP, 2 CPUs) | spin | 5001 ms: FAIL | 101 ms: PASS | | qemu-armv8a:nsh_smp (flat, SMP, 2 CPUs) | exit (INFO) | 5003 ms | 5003 ms | ostest: qemu-armv8a:knsh 0, qemu-armv8a:nsh 0 and qemu-armv8a:nsh_smp 0, on master and with this PR. Build with `EXTRAFLAGS="-Wno-cpp -Werror"` as CI, each OK: qemu-armv8a:nsh (flat; also with `CONFIG_SIG_DEFAULT` and `CONFIG_CANCELLATION_POINTS`), qemu-armv8a:knsh (kernel), rv-virt:citest (flat, rv32), rv-virt:ksmp64 (kernel, SMP, rv64) and mps2-an500:knsh (protected, Cortex-M7), all with `CONFIG_SIG_DEFAULT`. With `CONFIG_DISABLE_PTHREAD` the kernel compiles and the link fails in apps (ostest and getprime use pthreads; not changed here). `tools/checkpatch.sh -c -u -m -g` passes. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
