[fpc-devel] fpsignal broken on linux-x86_64 (+patch)
Nikolay Nikolov
nickysn at users.sourceforge.net
Sat Sep 5 15:36:53 CEST 2009
Hi
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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: testfpsignal.pas
Type: text/x-pascal
Size: 395 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20090905/bfd3d5fa/attachment.pas>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linux-x86_64-fpsignal-fix.patch
Type: text/x-patch
Size: 753 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20090905/bfd3d5fa/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: testsignal.c
Type: text/x-csrc
Size: 340 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20090905/bfd3d5fa/attachment.c>
More information about the fpc-devel
mailing list