NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: lib/41085: sigaction returns EINVAL instead of -1
The following reply was made to PR lib/41085; it has been noted by GNATS.
From: Matteo Beccati <matteo%beccati.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: lib/41085: sigaction returns EINVAL instead of -1
Date: Sat, 28 Mar 2009 08:21:23 +0100
David Holland wrote:
> Is maybe PHP doing some kind of macro wrapper around sigaction? This
> is PHP we're talking about after all... and while it's possible that
> ktrace could just miss the sigaction call entirely, that doesn't seem
> very likely. (And in fact, the code in libc is such that if you try to
> sigaction on signal -1, it ought to call __sigaction_sigtramp
> *twice*.)
From what I can see the PHP code calls sigaction() just like any other
libc sig* function.
> I've looked over the kernel and libc code involved and I don't see any
> plausible way for it to mix the return value and error code, unless
> something Xen-specific is causing the carry flag (which distinguishes
> error returns from real return values) to get cleared in the low-level
> code on the way back from the system call. But for that one would need
> to explain why ktrace isn't seeing anything. Plus, if it's there and
> it's repeatable, one would expect it to affect a lot more than just
> sigaction.
>
> Can you easily check if the problem occurs only under Xen?
Same happens with a GENERIC kernel. If you want I can provide ssh access
to the machine.
Anyway, here's a trimmed down version of the script. I've added a
nanosleep call just to make it obvious to identify the call in the
ktrace output:
root@epia:~/compile/php-HEAD# cat pcntl_signal.php
<?php
usleep(1);
var_dump(pcntl_signal(-1, function(){}));
ktrace of sig related calls, plus the sigaction call above:
...
745 1 php CALL __sigprocmask14(0,0,0xbfa00074)
745 1 php RET __sigprocmask14 0
745 1 php CALL __sigprocmask14(0,0,0xbaee3be0)
745 1 php RET __sigprocmask14 0
745 1 php CALL
__sysctl(0xbfbfe7dc,2,0xbfbfe7e4,0xbfbfe7e8,0,0)
745 1 php RET __sysctl 0
745 1 php CALL
__sysctl(0xbfbfe81c,2,0xbafc3240,0xbfbfe824,0,0)
745 1 php RET __sysctl 0
745 1 php CALL
__sigaction_sigtramp(SIGPIPE,0xbfbfe688,0xbfbfe670,0xbaf58e6c,2)
745 1 php RET __sigaction_sigtramp 0
...
745 1 php CALL
__sigaction_sigtramp(SIGPROF,0xbfbfe5c8,0xbfbfe5b0,0xbaf58e6c,2)
745 1 php RET __sigaction_sigtramp 0
745 1 php CALL __sigprocmask14(3,0xbaee3be0,0)
745 1 php RET __sigprocmask14 0
...
745 1 php CALL nanosleep(0xbfbfcffc,0)
745 1 php RET nanosleep 0
745 1 php CALL write(1,0x83b2600,0xb)
745 1 php GIO fd 1 wrote 11 bytes
"bool(true)
"
...
gdb:
(gdb) break php_signal
Breakpoint 1 at 0x82d0296: file
/root/compile/php-HEAD/ext/pcntl/php_signal.c, line 29.
(gdb) run pcntl_signal.php
Starting program: /root/compile/php-HEAD/sapi/cli/php pcntl_signal.php
Breakpoint 1, php_signal (signo=-1, func=0x82d00de
<pcntl_signal_handler>, restart=1) at
/root/compile/php-HEAD/ext/pcntl/php_signal.c:29
29 act.sa_handler = func;
(gdb) list
24 * in the Unix Environment by W. Richard Stevens p 298. */
25 Sigfunc *php_signal(int signo, Sigfunc *func, int restart)
26 {
27 int retval;
28 struct sigaction act,oact;
29 act.sa_handler = func;
30 sigemptyset(&act.sa_mask);
31 act.sa_flags = 0;
32 if (signo == SIGALRM || (! restart)) {
33 #ifdef SA_INTERRUPT
(gdb) list
34 act.sa_flags |= SA_INTERRUPT; /* SunOS */
35 #endif
36 } else {
37 #ifdef SA_RESTART
38 act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
39 #endif
40 }
41
42 retval = sigaction(signo, &act, &oact);
43
(gdb) disassemble
Dump of assembler code for function php_signal:
0x082d0290 <php_signal+0>: push %ebp
0x082d0291 <php_signal+1>: mov %esp,%ebp
0x082d0293 <php_signal+3>: sub $0x48,%esp
0x082d0296 <php_signal+6>: mov 0xc(%ebp),%eax
0x082d0299 <php_signal+9>: mov %eax,0xffffffe4(%ebp)
0x082d029c <php_signal+12>: sub $0xc,%esp
0x082d029f <php_signal+15>: lea 0xffffffe4(%ebp),%eax
0x082d02a2 <php_signal+18>: add $0x4,%eax
0x082d02a5 <php_signal+21>: push %eax
0x082d02a6 <php_signal+22>: call 0x805d0a0 <__sigemptyset14@plt>
0x082d02ab <php_signal+27>: add $0x10,%esp
0x082d02ae <php_signal+30>: movl $0x0,0xfffffff8(%ebp)
0x082d02b5 <php_signal+37>: cmpl $0xe,0x8(%ebp)
0x082d02b9 <php_signal+41>: je 0x82d02ca <php_signal+58>
0x082d02bb <php_signal+43>: cmpl $0x0,0x10(%ebp)
0x082d02bf <php_signal+47>: je 0x82d02ca <php_signal+58>
0x082d02c1 <php_signal+49>: mov 0xfffffff8(%ebp),%eax
0x082d02c4 <php_signal+52>: or $0x2,%eax
0x082d02c7 <php_signal+55>: mov %eax,0xfffffff8(%ebp)
0x082d02ca <php_signal+58>: sub $0x4,%esp
0x082d02cd <php_signal+61>: lea 0xffffffcc(%ebp),%eax
0x082d02d0 <php_signal+64>: push %eax
0x082d02d1 <php_signal+65>: lea 0xffffffe4(%ebp),%eax
0x082d02d4 <php_signal+68>: push %eax
0x082d02d5 <php_signal+69>: pushl 0x8(%ebp)
0x082d02d8 <php_signal+72>: call 0x805d360 <__sigaction14@plt>
0x082d02dd <php_signal+77>: add $0x10,%esp
0x082d02e0 <php_signal+80>: mov %eax,0xfffffffc(%ebp)
0x082d02e3 <php_signal+83>: cmpl $0x0,0xfffffffc(%ebp)
0x082d02e7 <php_signal+87>: jns 0x82d02f2 <php_signal+98>
0x082d02e9 <php_signal+89>: movl $0xffffffff,0xffffffbc(%ebp)
0x082d02f0 <php_signal+96>: jmp 0x82d02f8 <php_signal+104>
0x082d02f2 <php_signal+98>: mov 0xffffffcc(%ebp),%eax
0x082d02f5 <php_signal+101>: mov %eax,0xffffffbc(%ebp)
0x082d02f8 <php_signal+104>: mov 0xffffffbc(%ebp),%eax
0x082d02fb <php_signal+107>: leave
0x082d02fc <php_signal+108>: ret
End of assembler dump.
(gdb) advance 44
php_signal (signo=-1, func=0x82d00de <pcntl_signal_handler>, restart=1)
at /root/compile/php-HEAD/ext/pcntl/php_signal.c:44
44 if (retval < 0)
(gdb) print retval
$1 = 22
(gdb) print act
$2 = {_sa_u = {_sa_handler = 0x82d00de <pcntl_signal_handler>,
_sa_sigaction = 0x82d00de <pcntl_signal_handler>}, sa_mask = {__bits =
{0, 0, 0, 0}}, sa_flags = 2}
(gdb) print oact
$3 = {_sa_u = {_sa_handler = 0x8537098, _sa_sigaction = 0x8537098},
sa_mask = {__bits = {138093920, 136402289, 138092292, 6}}, sa_flags = 15}
Home |
Main Index |
Thread Index |
Old Index