免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 5367 | 回复: 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");
?>

论坛徽章:
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
2 [报告]
发表于 2009-03-14 18:47 |只看该作者
是不是 Apache 自己把 SIGINT 捕捉/屏蔽了?

BTW,在用 Apache 的 PHP 的时候,你是怎么发信号的?

论坛徽章:
0
3 [报告]
发表于 2009-03-14 22:14 |只看该作者
不知道是不是 apache 把 SIGINT 捕捉或屏蔽了
用 apache 中的 php 调用程序的时候,仅仅是执行了一个可以捕获信号的 signal 程序
发信号的时候是在 console 命令行下用 root 权限写 "killall -s SIGINT signal" 来发送信号的

论坛徽章:
0
4 [报告]
发表于 2009-03-14 23:59 |只看该作者
很正常,应该是apache屏蔽掉了该信号,或者根本就不存在signal进程名,你可以ps一下,把signal的pid找出来,然后再kill掉它。

论坛徽章:
0
5 [报告]
发表于 2009-03-15 00:40 |只看该作者
原帖由 alphayeah 于 2009-3-14 23:59 发表
很正常,应该是apache屏蔽掉了该信号,或者根本就不存在signal进程名,你可以ps一下,把signal的pid找出来,然后再kill掉它。

signal 的进程名是存在的,用 killall 杀进程名,或者用 kill 杀 pid 都试过,没有效果的,但是如果用 killall -9 或者 kill -9 就可以杀掉
所以,不存在进程名或者 pid 错误的低级错误

我应如何证明是 apache 屏蔽掉了该信号呢?又有什么方法可以阻止其这么做吗?

论坛徽章:
0
6 [报告]
发表于 2009-03-15 09:26 |只看该作者
记得/proc/$pid/status下有信号屏蔽掩码之类的,看父子进程是不是有继承关系呢。

论坛徽章:
0
7 [报告]
发表于 2009-03-15 10:37 |只看该作者
以下是用 php test.php 和在浏览器里写 http://IP/test.php 执行后的结果

  1. php test.php
  2. # cat /proc/16481/status
  3. Name:   signal
  4. State:  S (sleeping)
  5. Tgid:   16481
  6. Pid:    16481
  7. PPid:   1
  8. TracerPid:      0
  9. Uid:    0       0       0       0
  10. Gid:    0       0       0       0
  11. FDSize: 32
  12. Groups: 0 1 2 3 4 6 10 11 20 26 27
  13. VmPeak:     5100 kB
  14. VmSize:     5076 kB
  15. VmLck:         0 kB
  16. VmHWM:      1196 kB
  17. VmRSS:      1196 kB
  18. VmData:      340 kB
  19. VmStk:        84 kB
  20. VmExe:         8 kB
  21. VmLib:      4196 kB
  22. VmPTE:        16 kB
  23. Threads:        1
  24. SigQ:   0/2048
  25. SigPnd: 0000000000000000
  26. ShdPnd: 0000000000000000
  27. SigBlk: 0000000000000000
  28. SigIgn: 0000000000001000
  29. SigCgt: 0000000000000002
  30. CapInh: 0000000000000000
  31. CapPrm: 00000000fffffeff
  32. CapEff: 00000000fffffeff
  33. voluntary_ctxt_switches:        2
  34. nonvoluntary_ctxt_switches:     7
复制代码

  1. 浏览器执行
  2. Name:   signal
  3. State:  S (sleeping)
  4. Tgid:   16488
  5. Pid:    16488
  6. PPid:   1
  7. TracerPid:      0
  8. Uid:    0       0       0       0
  9. Gid:    0       0       0       0
  10. FDSize: 32
  11. Groups: 0 1 2 3 4 6 10 11 20 26 27
  12. VmPeak:     5100 kB
  13. VmSize:     5076 kB
  14. VmLck:         0 kB
  15. VmHWM:      1200 kB
  16. VmRSS:      1200 kB
  17. VmData:      340 kB
  18. VmStk:        84 kB
  19. VmExe:         8 kB
  20. VmLib:      4196 kB
  21. VmPTE:        16 kB
  22. Threads:        1
  23. SigQ:   0/2048
  24. SigPnd: 0000000000000000
  25. ShdPnd: 0000000000000000
  26. SigBlk: fffffffe3bfae007
  27. SigIgn: 0000000000001000
  28. SigCgt: 0000000000000002
  29. CapInh: 0000000000000000
  30. CapPrm: 00000000fffffeff
  31. CapEff: 00000000fffffeff
  32. voluntary_ctxt_switches:        5
  33. nonvoluntary_ctxt_switches:     1
复制代码

发现只有 voluntary_ctxt_switches 和 nonvoluntary_ctxt_switches 不一样
请问 OneThird 兄,能从这个分析出什么吗?
BTW:你的头像好可爱~!

论坛徽章:
0
8 [报告]
发表于 2009-03-15 11:13 |只看该作者
SigCgt: 0000000000000002 这个应该是捕获的信号位图,是不是说编号为2的信号SIGINT,但是没有执行默认的动作,是不是继承apache的信号处理函数,你看看apache的代码呢,或者可能的话,kill -s SIGINT pid_of_apache看看反应呢。我也不是很了解,关注中。

论坛徽章:
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
9 [报告]
发表于 2009-03-15 13:17 |只看该作者
原帖由 platinum 于 2009-3-14 22:14 发表
发信号的时候是在 console 命令行下用 root 权限写 "killall -s SIGINT signal" 来发送信号的

这个是我查 killall 手册的结果
           -s          Show only what would be done, but do not send any signal.


当然,kill 的 -s 是发信号的。

论坛徽章:
0
10 [报告]
发表于 2009-03-15 13:24 |只看该作者
原帖由 OneThird 于 2009-3-15 11:13 发表
SigCgt: 0000000000000002 这个应该是捕获的信号位图,是不是说编号为2的信号SIGINT,但是没有执行默认的动作,是不是继承apache的信号处理函数,你看看apache的代码呢,或者可能的话,kill -s SIGINT pid_of_a ...

谢谢 OneThird 兄的关注,我回头去看一下 apache 的关于信号处理部分的代码
另外,两个不同方法执行的 signal 的 PPID 都是 1,而其中一个并非 apache,我认为 kill -s SIGINT pid_of_apache 对 signal 程序无效

恩,确实无效,apache 进程已经消失了,但 signal 进程还在……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP