Hello, The patch below fixes a corner case of signals: when longjumping from a signal handler, the code currently restores the reply port used by the main code. But since we possibly longjmp over a pending RPC, we should rather just kill that reply port, which will thus get recreated on next RPC. Otherwise, the next RPC will try to use it and probably receive a message that was for the interrupted RPC, and thus produce a -301 error (EMIG_REPLY_MISMATCH)... For instance, the testcase below always show that mach_port_destroy returns a -301 error: it actually gets the reply message of the raise call itself...
Roland, do you agree on this? Samuel #include <mach.h> #include <signal.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <setjmp.h> jmp_buf jb; void handle(int sig) { fprintf(stderr, "got it\n"); siglongjmp(jb, sig); } int main(void) { int res; int i; int err = 0; signal(SIGBUS, handle); if (!(res = sigsetjmp(jb, 1))) { res = raise(SIGBUS); if (res) perror("raise"); } else { res = mach_port_destroy(__mach_task_self(), MACH_PORT_NULL); if (res) fprintf(stderr,"%d\n", res); } return 0; } diff --git a/hurd/sigunwind.c b/hurd/sigunwind.c index 3a62fb5..e535c4a 100644 --- a/hurd/sigunwind.c +++ b/hurd/sigunwind.c @@ -50,7 +50,8 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val) *reply_port = MACH_PORT_DEAD; __mach_port_destroy (__mach_task_self (), port); } - *reply_port = scp->sc_reply_port; + if (scp->sc_reply_port) + __mach_port_destroy (__mach_task_self (), scp->sc_reply_port); } __spin_lock (&ss->lock);