Consider this program: #include <signal.h> #include <string.h> #include <setjmp.h> #include <unistd.h> #undef WRITE #define WRITE(str) write(STDOUT_FILENO, (str), strlen((str))) static sigjmp_buf escape; static void handler(int sig) { WRITE("CALLED\n"); #ifdef JUMP siglongjmp(escape, 1); #endif } volatile int v; int main(void) { struct sigaction sa; sigfillset(&sa.sa_mask); sa.sa_handler = handler; sa.sa_flags = 0; sigaction(SIGFPE, &sa, NULL); #ifdef JUMP if (sigsetjmp(escape, 1) == 0) #endif v = 44/v; return 0; } Division by zero causes SIGFPE signal. When run natively, there is no difference as to whether the signal handler returns via siglongjmp or not. The handler is called once, the program exits. Under valgrind the program runs into an infinite loop when the handler returns without siglongjmp. The handler is called again and again. That's not what I would expect. I would expect the behaviour to be identical. Or am I missing something?
(In reply to Florian Krohm from comment #0) > Division by zero causes SIGFPE signal. > When run natively, there is no difference as to whether the signal handler > returns via siglongjmp or not. > The handler is called once, the program exits. > > Under valgrind the program runs into an infinite loop when the handler > returns without siglongjmp. The handler is called again and again. > > That's not what I would expect. I would expect the behaviour to be identical. > Or am I missing something? This might be s390x specific. On x86_64 the native and valgrind behavior are identical. Without the siglongjmp the program goes into an infinite "loop" because the signal handler just returns to the divide by zero instuction over and over again and again. With the siglongjump the signal handler is called once and the handler returns to the if(sigsetjmp) and bypasses the divide by zero instruction and just returns from main.
(In reply to Mark Wielaard from comment #1) > > This might be s390x specific. Not sure - see below. However there are some fixs390 comments in the neighbourhood.... > On x86_64 the native and valgrind behavior are identical. That is not what I see. Run natively, the "with sigsetmp" version runs as expected, the "without sigsetmp" version runs in an infinite loop. Under valgrind (current git) both call the handler once and exit (none and memcheck). This is with a 5.15.0-141 kernel and glibc 2.35 and gcc 11.4.0 on Intel i7-8550U. Unfortunately, I don't know how signal delivery works in general and for s390 in particular.. When we did the s390 port the kernel related stuff was done by Christian Bornträger..