免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 5373 | 回复: 21
打印 上一主题 下一主题

为何 apache 的 php 运行的程序无法获得 root 给的 SIGINT 信号? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-14 17:47 |只看该作者 |正序浏览
一个简单的截获 SIGINT 的程序
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <syslog.h>

void fun_ctrl_c(int signal)
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;syslog (LOG_ALERT, "Hello Ctrl-C, exit.\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (0);
}


int main(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;daemon (0, 0);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signal (SIGINT, fun_ctrl_c);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;syslog (LOG_ALERT, "signal test is running.\n");

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep (1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
}


在 root 下直接运行没有问题,killall -2 signal 也能杀掉,syslog 里也有日志记录

但是如果用 apache 的 php 去运行的话,进程中的 signal 不再接收 SIGINT 信号了,这可能是怎么造成的?
PHP 代码如下:
<?php
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shell_exec("/tmp/signal");
?>

论坛徽章:
0
22 [报告]
发表于 2009-03-19 17:05 |只看该作者
真是晕死!见鬼了!

论坛徽章:
0
21 [报告]
发表于 2009-03-18 17:44 |只看该作者
奇怪了,我试验居然可以!!!!!
  1. wys htdocs # ps -elf | grep "apache\|TIME"
  2. F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
  3. 1 S root     13688     1  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  4. 5 S apache   13690 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  5. 5 S apache   13691 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  6. 5 S apache   13692 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  7. 5 S apache   13693 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  8. 5 S apache   13694 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  9. 1 S apache   13704     1  0  80   0 -   391 429496 17:56 ?        00:00:00 ./sigint
  10. 5 S apache   13705 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  11. 0 R root     13712 13334  0  80   0 -   436 -      17:57 pts/0    00:00:00 grep --colour=auto apache\|TIME
复制代码


  1. wys htdocs # kill -2 13704
复制代码


  1. wys htdocs # ps -elf | grep "apache\|TIME"
  2. F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
  3. 1 S root     13688     1  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  4. 5 S apache   13690 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  5. 5 S apache   13691 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  6. 5 S apache   13692 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  7. 5 S apache   13693 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  8. 5 S apache   13694 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  9. 5 S apache   13705 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  10. 0 R root     13714 13334  0  80   0 -   436 -      17:57 pts/0    00:00:00 grep --colour=auto apache\|TIME
  11. wys htdocs # tail -2 /var/log/messages
  12. Mar 24 17:56:44 wys sigint: signal test is running.
  13. Mar 24 17:57:36 wys sigint: Hello Ctrl-C, exit.
  14. wys htdocs #
复制代码


另作试验如下,killall -s 方式

  1. wys htdocs # ps -elf | grep "apache\|TIME"
  2. F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
  3. 1 S root     13688     1  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  4. 5 S apache   13690 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  5. 5 S apache   13691 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  6. 5 S apache   13692 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  7. 5 S apache   13693 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  8. 5 S apache   13694 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  9. 5 S apache   13705 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  10. 1 S apache   13847     1  0  80   0 -   391 429496 18:06 ?        00:00:00 ./sigint
  11. 0 R root     13849 13334  0  80   0 -   435 -      18:06 pts/0    00:00:00 grep --colour=auto apache\|TIME
  12. wys htdocs # su - apache -c "killall -s SIGINT sigint"
  13. wys htdocs # ps -elf | grep "apache\|TIME"
  14. F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
  15. 1 S root     13688     1  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  16. 5 S apache   13690 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  17. 5 S apache   13691 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  18. 5 S apache   13692 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  19. 5 S apache   13693 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  20. 5 S apache   13694 13688  0  80   0 -  4664 429496 17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
  21. 5 S apache   13705 13688  0  80   0 -  4664 -      17:56 ?        00:00:00 /usr/sbin/apache2 -D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -d /usr/lib/apache2 -f /etc/apache2/httpd.conf -k start
复制代码

  1. killall (PSmisc) 22.5
  2. Copyright (C) 1993-2005 Werner Almesberger and Craig Small

  3. PSmisc comes with ABSOLUTELY NO WARRANTY.
  4. This is free software, and you are welcome to redistribute it under
  5. the terms of the GNU General Public License.
  6. For more information about these matters, see the files named COPYING.

  7. 2007-03-02  Karel Zak
  8.         * killall <path> does textual path comparision with value of the
  9.           /proc/<pid>/exe link when a comparision with inode number failed.
  10.           The old algorithme based on inode numbers doesn't work if since
  11.           the process was started, the file at <path> has been replaced
  12.           (e.g due prelink process).
复制代码


查看相关apache及php的signal handler文档,与此问题均无关,怀疑killall的版本问题.

[ 本帖最后由 wysilly 于 2009-3-18 20:35 编辑 ]

论坛徽章:
0
20 [报告]
发表于 2009-03-18 16:01 |只看该作者
原帖由 alphayeah 于 2009-3-18 00:31 发表
很普遍的现象,我用过valgrind作调试程序时就没有办法kill掉那个程序。

但产生问题的根源是什么呢?是不是因为调用它的父进程本身屏蔽了部分信号?

论坛徽章:
0
19 [报告]
发表于 2009-03-18 00:31 |只看该作者
很普遍的现象,我用过valgrind作调试程序时就没有办法kill掉那个程序。

论坛徽章:
0
18 [报告]
发表于 2009-03-15 13:50 |只看该作者
额外做过的实验:
1、用浏览器方式运行 php 代码,php 代码中 shell_exec 运行一个 test.sh,test.sh 中调用 signal,却仍然无法接收 SIGINT 信号
2、直接从 root 用户 su 到 apache 用户,手动运行 php test.php,生成的进程就可以接收 SIGINT

初步怀疑,是不是和运行的环境变量有关?但我没有办法在 apache 调用 php 执行时初始化成 shell 的环境变量

MMMIX 兄说的对,看有没有办法用 php 内部的信号处理方法,去查查

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
17 [报告]
发表于 2009-03-15 13:46 |只看该作者
原帖由 platinum 于 2009-3-15 13:38 发表
是不是和这个有关,我在用浏览器执行 php 程序时,同时监测 ps 表进程,发现如下信息

QUOTE:
19745 ?        S      0:00 sh -c cd '/tmp' ; /tmp/signal
19746 ?        S<     0:00 /tmp/signal

看来 PHP 是通过 sh 启动 /tmp/signal 的,但这也说不通为嘛 signal 的 ppid 会变为 1,因为看来这个 sh 会等到 signal 退出自己才退出。

另外,还有一个超级奇怪的现象!!!

这个就更诡异了。

BTW,PHP 或者 Apache 自己没有内置的处理信号的方法么?有的话最好用它们提供的,这样可以避免许多诡异问题。

论坛徽章:
0
16 [报告]
发表于 2009-03-15 13:38 |只看该作者
原帖由 MMMIX 于 2009-3-15 13:31 发表

我现在很好奇为嘛在两种方式下它的 ppid 都为 1

是不是和这个有关,我在用浏览器执行 php 程序时,同时监测 ps 表进程,发现如下信息
19745 ?        S      0:00 sh -c cd '/tmp' ; /tmp/signal
19746 ?        S<     0:00 /tmp/signal



另外,还有一个超级奇怪的现象!!!
看一下我的操作

  1. # netstat -lnp
  2. Active Internet connections (only servers)
  3. Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
  4. tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN     3891/mysqld
  5. tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     19619/apache2
  6. tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     3965/sshd
  7. tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN     19619/apache2
  8. Active UNIX domain sockets (only servers)
  9. Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
  10. unix  2      [ ACC ]     STREAM     LISTENING     4259     3891/mysqld         /var/run/mysqld/mysqld.sock
  11. unix  2      [ ACC ]     STREAM     LISTENING     243917   19621/apache2       /var/run/cgisock.19619
  12. unix  2      [ ACC ]     STREAM     LISTENING     4083     3819/syslog-ng      /dev/log

  13. # killall -s SIGINT apache2

  14. # netstat -lnp
  15. Active Internet connections (only servers)
  16. Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
  17. tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN     3891/mysqld
  18. tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     3965/sshd
  19. tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN     19833/signal
  20. Active UNIX domain sockets (only servers)
  21. Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
  22. unix  2      [ ACC ]     STREAM     LISTENING     4259     3891/mysqld         /var/run/mysqld/mysqld.sock
  23. unix  2      [ ACC ]     STREAM     LISTENING     4083     3819/syslog-ng      /dev/log

  24. #
复制代码

原先的 apache 监听 TCP/80 和 TCP/443 端口
1、通过 SIGINT 杀掉 apache 进程后 signal 进程竟然开始监听 TCP/443
2、监听的只有 TCP/443,但 TCP/80 却没有

这是什么个逻辑啊……

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
15 [报告]
发表于 2009-03-15 13:31 |只看该作者
原帖由 platinum 于 2009-3-15 13:27 发表

BTW: killall 和 kill 我都试过,应该不会是我的这个低级错误,真奇怪了……

我现在很好奇为嘛在两种方式下它的 ppid 都为 1

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
14 [报告]
发表于 2009-03-15 13:30 |只看该作者
原帖由 platinum 于 2009-3-15 13:27 发表

MMMIX 兄,不知道是不是我们看的 man 文档不一样,我用的是 gentoo,man killall 的提示是

难道不同版本的 killall 还会不同?

是不同,我这是 Mac OS X,BSD 系列的。。。
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP