Samuel,
On 21/01/2026 17:11, Samuel Thibault wrote:
Michael Kelly, le mer. 21 janv. 2026 13:15:12 +0000, a ecrit:
Has this issue with signal handling been resolved?
No, and I don't know if it's really related to signal handling actually,
it could also be user/user or user/kernel context switch management in
mach.
I couldn't yet offer any certainty as to the cause of the problem that I
see but it certainly seems to be triggered by multiple signals. I've
attached the C code that I use for a test case. I had narrowed down the
stress-ng bit error reports to a seeming failure of memset to zero a
range of memory as requested. The code I then wrote repeatedly calls
memset and tests that the entire memory range is in fact zeroed whilst
simultaneously being bombarded with very frequent SIGALRMs. I find that
the only instance of failure in memset is during a period when two or
more SIGALRM handlers are called whilst the call to memset is taking place.
Running one instance of the test code is not sufficient. I find that if
I run around 8 instances concurrently then I see output like:
6269: 2 SIGALRMs in memset
6267(19893): Non zero at index: 19472
6267: 2 SIGALRMs in memset
6267(24924): Non zero at index: 63456
6267: 2 SIGALRMs in memset
Is my test case (and stress-ng) doing something very silly?
I've seen some fixes in glibc (eg. hurd/x86_64/htl/pt-machdep.c)
Which fix are you thinking about? The only related fix is
e539a269990dac3ff4d2432c0eb6966a5ee4f274
("hurd: Fix sigreturn clobbering some xmm registers")
which should help, but does not completely fix the issue.
I did include the above and also the following which might not be
relevant anyway:
commit 0bbeb1fd13ba4d30cd7ec977e1ab6c22d7bf8b7f
Date: Sat Jan 17 15:15:33 2026 +0100
hurd: make __thread_set_pcsptp align stack
Regards,
Mike.
#include <errno.h>
#include <error.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static volatile sig_atomic_t inmemset = 0;
static volatile sig_atomic_t nalrms_inmemset = 0;
static void
alarm_handler(int signum)
{
if (inmemset)
nalrms_inmemset++;
}
static void*
sigraise_func(void*)
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGALRM);
int err = pthread_sigmask(SIG_BLOCK, &set, NULL);
if (err)
error(1, err, "pthread_sigmask");
while (1)
{
usleep(100);
kill(getpid(), SIGALRM);
}
return NULL;
}
static const size_t SZ = 0x1000 * 16;
int
main()
{
struct sigaction action;
action.sa_handler = alarm_handler;
if (sigemptyset(&action.sa_mask))
error(1, errno, "sigemptyset");
action.sa_flags = 0;
if (sigaction(SIGALRM, &action, NULL))
error(1, errno, "sigaction");
pthread_t sigraise_thread;
int err = pthread_create(&sigraise_thread, NULL, sigraise_func, NULL);
if (err)
error(1, err, "pthread_create");
unsigned long iterations = 0;
uint8_t buf[SZ];
while (1)
{
nalrms_inmemset = 0;
inmemset = 1;
(void)memset(buf, 0x00, SZ);
inmemset = 0;
size_t n = 0;
while (n < SZ)
{
if (buf[n] != 0)
{
fprintf(stderr, "%d(%ld): Non zero at index: %zu\n",
getpid(), iterations, n);
n = SZ;
}
else
n++;
}
if (nalrms_inmemset > 1)
fprintf(stderr, "%d: %d SIGALRMs in memset\n", getpid(), nalrms_inmemset);
iterations++;
}
return 0;
}