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;
}

Reply via email to