This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 22c06473dc9 sched/signal: Release a pending signal before its action
runs.
22c06473dc9 is described below
commit 22c06473dc96df985a22c2a4adef61b1453c2bab
Author: Marco Casaroli <[email protected]>
AuthorDate: Wed Oct 21 04:14:29 2026 +0200
sched/signal: Release a pending signal before its action runs.
When a thread unblocks a pending signal, nxsig_unmask_pendingsignal()
takes the entry of the signal off the pending list, dispatches the
signal, and then releases the entry. When the action of the signal
ends the process (the default action of SIGTERM, SIGINT or SIGKILL),
nxsig_tcbdispatch() does not return, and the entry is never released:
one entry, from the pool or from the kernel heap, is lost each time.
A shell blocks signals around its commands, so "kill -TERM $$" in a
shell script loses one each time.
Copy the signal information and release the entry before the dispatch.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <[email protected]>
---
sched/signal/sig_unmaskpendingsignal.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/sched/signal/sig_unmaskpendingsignal.c
b/sched/signal/sig_unmaskpendingsignal.c
index 1f79ea8420b..54d4ecf2fd8 100644
--- a/sched/signal/sig_unmaskpendingsignal.c
+++ b/sched/signal/sig_unmaskpendingsignal.c
@@ -51,6 +51,8 @@ static bool nxsig_dispatch_unmasked(FAR struct tcb_s *rtcb)
{
sigset_t unmaskedset;
FAR sigpendq_t *pendingsig;
+ siginfo_t info;
+ bool group;
int signo;
/* Prohibit any context switches until we are done with this.
@@ -96,19 +98,22 @@ static bool nxsig_dispatch_unmasked(FAR struct tcb_s *rtcb)
if ((pendingsig = nxsig_remove_pendingsignal(rtcb, signo)) != NULL)
{
- /* If there is one, then process it like a normal signal.
- * Since the signal was pending, then unblocked on this
- * thread, we can skip the normal group signal dispatching
- * rules; there can be no other recipient for the signal
- * other than this thread.
+ /* Release the entry first: the action can end the process
+ * (the default action of SIGTERM, for example), and then
+ * nxsig_tcbdispatch() does not return.
*/
- nxsig_tcbdispatch(rtcb, &pendingsig->info,
- pendingsig->tcb == NULL);
+ info = pendingsig->info;
+ group = pendingsig->tcb == NULL;
+ nxsig_release_pendingsignal(pendingsig);
- /* Then remove it from the pending signal list */
+ /* Process it like a normal signal. Since the signal was
+ * pending, then unblocked on this thread, we can skip the
+ * normal group signal dispatching rules; there can be no
+ * other recipient for the signal other than this thread.
+ */
- nxsig_release_pendingsignal(pendingsig);
+ nxsig_tcbdispatch(rtcb, &info, group);
}
}
}