fpsignal broken on linux-x86_64
Original Reporter info from Mantis: nickysn @nickysn
-
Reporter name: Nikolay Nikolov
Original Reporter info from Mantis: nickysn @nickysn
- Reporter name: Nikolay Nikolov
Description:
On linux-x86_64, programs have odd behaviour after a signal handler, installed with fpsignal is invoked. The handler executes fine and after it finishes, the program either crashes or terminates. Attached program demonstrates this, when run on linux-x86_64. After some debugging, I found out the cause - the fpsignal function in rtl/unix/bunxovl.inc sets sa.sa_flags to (SA_SIGINFO or SA_RESTORER); (SA_RESTORER is $4000000). Then fpsigaction (in rtl/linux/ossysc.inc) is called, which checks whether both SA_RESTORER and SA_ONSTACK flags are 0. If they are, on certain architectures (ifdef NEED_USER_TRAMPOLINE) fpsigaction sets the SA_RESTORER flag to 1 and sets new_action^.sa_restorer to a "restorer" trampoline procedure which calls sigreturn or rt_sigreturn (depending on arch and SA_RESTORER flag). However, on x86_64, SA_RESTORER is already set by the caller (fpsignal), which causes the check inside fpsigaction (whether both SA_RESTORER and SA_ONSTACK bits are zero) to return false and the trampoline isn't installed. Still the SA_RESTORER flag is passed to the kernel, but the new_action^.sa_restorer address is not initialized, leading to crashes or odd behaviour. My patch removes all the ifdefs in fpsignal, since they're IMHO meaningless now. I'm not 100% sure what are they trying to achieve, but I guess it was written before fpsigaction was changed to install its own "restorer" trampolines. SA_SIGINFO is IMHO also not needed, since it doesn't change the trampoline used (on x86_64 and i386; on i386 it does, but then the caller fpsignal doesn't set SA_SIGINFO; on x86_64, the trampoline is only one and is not affected by SA_SIGINFO; on arm - I'm not 100% sure; on sparc - no trampolines). To summarize, here's the impact of the patch:
it only affects the fpsignal function and not fpsigaction
linux-i386 - no change and works - tested on Fedora 11 (2.6.29.6-217.2.16.fc11.i686.PAE) and Debian 5.0.2 (2.6.26-2-xen-amd64 - 32-bit binary, under a 64-bit kernel)
linux-x86_64 - was previously broken, now fixed; tested on Fedora 11 (2.6.29.6-217.2.16.fc11.x86_64) and Debian 5.0.2 (2.6.26-2-xen-amd64)
linux-ppc - no change (in theory)
linux-ppc64 - no change (in theory)
linux-arm - needs testing; might break something
linux-sparc - needs testing; might break something
other unices - i386, ppc, ppc64 - no change (in theory)
other unices - x86_64, arm, sparc (are there any?) - also need testing
I've also attached a C program, that does the same thing as the pascal test program, so both can be run with strace and the syscalls called from glibc and fpc's rtl can be compared.
Mantis conversion info:
- Mantis ID: 14514
- OS: linux-x86_64
- Version: 2.2.4
- Fixed in version: 2.4.0
- Fixed in revision: 13717 (#0698121f)