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 <>
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
 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 
     745      1 php      RET   __sysctl 0
     745      1 php      CALL 
     745      1 php      RET   __sysctl 0
     745      1 php      CALL 
     745      1 php      RET   __sigaction_sigtramp 0
     745      1 php      CALL 
     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
 (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 
 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              }
 42              retval = sigaction(signo, &act, &oact);
 (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