Package: libc0.3 Version: 2.9-27 When using a sigaltstack, under some circumstances returning from a signal handler causes the process to block on a spinlock indefinitely. This problem is specific to Hurd. I've attached a small demonstration program. This is either a kernel or libc bug.
The expected output is: terps...@orange:~$ ./sigbug Starting with stack bfd789c0 Alarm in 5 seconds Waiting for signal. Got sigint with stack b7dead24 On hurd we now enter an indefinite spin_lock (hang) Clean exit On hurd the output is: terps...@strauss:~$ ./sigbug Starting with stack 1024ddc Alarm in 5 seconds Waiting for signal. Got sigint with stack 1411efc On hurd we now enter an indefinite spin_lock (hang) ... then it hangs consuming CPU resources: terps...@strauss:~$ ps -xM PID STAT TIME COMMAND 24645 R 0:02.62 ./sigbug terps...@strauss:~$ ps -xM PID STAT TIME COMMAND 24645 R 0:03.12 ./sigbug A stack trace of the program: (gdb) bt #0 0x0105690c in swtch_pri () at /build/buildd/eglibc-2.9/build-tree/hurd-i386-libc/mach/swtch_pri.S:2 #1 0x01058204 in __spin_lock_solid (lock=0x120880c) at spin-solid.c:27 #2 0x010961b8 in __spin_lock (how=2, set=0x1411edc, oset=0x0) at ../mach/lock-intern.h:55 #3 __sigprocmask (how=2, set=0x1411edc, oset=0x0) at ../sysdeps/mach/hurd/sigprocmask.c:43 #4 0x01099eae in abort () at abort.c:65 #5 0x0109795b in __sigreturn (scp=0x1411f20) at ../sysdeps/mach/hurd/i386/sigreturn.c:74 #6 0x01071cf6 in trampoline () from /lib/libc.so.0.3 #7 0x01411f20 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) Compile the test program as: terps...@strauss:~$ gcc -Wall -O0 -g sigbug.c -o sigbug Here is the test program: terps...@strauss:~$ cat sigbug.c #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> void f(int s) { int x; printf("Got sigint with stack %lx\n", (long)&x); printf("On hurd we now enter an indefinite spin_lock (hang)\n"); } int main() { struct sigaction sa; stack_t altstack; sigset_t mask; printf("Starting with stack %lx\n", (long)&sa); memset(&altstack, 0, sizeof(altstack)); altstack.ss_size = 1024*1024; altstack.ss_sp = malloc(2*altstack.ss_size); altstack.ss_sp += altstack.ss_size; sigaltstack(&altstack, 0); memset(&sa, 0, sizeof(sa)); sigfillset(&sa.sa_mask); sa.sa_handler = f; sa.sa_flags = SA_ONSTACK; sigaction(SIGALRM, &sa, 0); printf("Alarm in 5 seconds\n"); alarm(5); printf("Waiting for signal.\n"); sigemptyset(&mask); sigsuspend(&mask); printf("Clean exit\n"); return 0; }