Home > Linux > ulimit -t 引起的kill血案

ulimit -t 引起的kill血案

September 28th, 2012

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: ulimit -t 引起的kill血案

今天在内核群里印风同学问了个问题:

某台机器的ulimit -t 不知道为啥是300, 这是不是意味着程序占用CPU 300秒后会收到SIGKILL ?
我用gdb跑mysqld 跑了一会,收到SIGKILL信号,没有配置cgroup,也没啥后台脚本,看了下,就ulimit -t 比较诡异,其他机器都是unlimited。

简单的man ulimit下手册说:

-t The maximum amount of cpu time in seconds

貌似限制的是CPU最大执行时间,以秒为单位。
为了验证上面的说法,我特地设计了以下的场景:我们首先运行一个死循环程序消耗CPU时间,同时把进程的最大CPU消耗时间设定在180秒,期待在这个时间点进程会被杀掉。
以下是验证过程:

$ uname -r
2.6.32-131.21.1.tb477.el6.x86_64
$ ulimit -t 180
$ ulimit -t
180
$ cat busy.c
int main(int argc, char *argv[]) {
  for(;;);
  return 0;
}
$ gcc busy.c 
$ time ./a.out 
Killed

real	3m0.029s
user	2m59.966s
sys	0m0.007s

从现象来看,3分钟后我们的busy进程确实被杀了,dmesg也没说什么原因被杀。

不过不怕我早有准备,提早在运行的同时在另外一个终端开了个stap脚本来确定到底谁杀死了我们的进程:

$ cat sigkill.stp
probe signal.send{
  if(sig_name == "SIGKILL")
    printf("%s was sent to %s (pid:%d) by %s uid :%d\n", sig_name, pid_name , sig_pid, execname(), uid())
}

$ sudo stap sigkill.stp
SIGKILL was sent to a.out (pid:23700) by a.out uid :50920

我们可以看的很清楚是./a.out给自己发的kill信号,属于自杀非他杀,行为有点意思吧!

木名同学找了下内核代码确认了以上行为:
./kernel/posix-cpu-timers.c:1139

           if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) {
                        /*                                                                                                                                               
                         * At the hard limit, we just die.                                                                                                               
                         * No need to calculate anything else now.                                                                                                       
                         */
                        __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
                        return;
                }
                if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
                        /*                                                                                                                                               
                         * At the soft limit, send a SIGXCPU every second.                                                                                               
                         */
                        __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
                        if (sig->rlim[RLIMIT_CPU].rlim_cur
                            < sig->rlim[RLIMIT_CPU].rlim_max) {
                                sig->rlim[RLIMIT_CPU].rlim_cur++;
			}
                }

内核的代码解释的很清楚,超过硬CPU限制就简单粗暴的让进程被自杀了。之前我还说内核不大可能这么狠,没想到。。。
小结:多看代码,少猜测。
祝大家玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Linux Tags: , ,
  1. September 28th, 2012 at 23:35 | #1

    分析犀利,行云流水

    Yu Feng Reply:

    多谢夸奖。

  2. Han He
    September 29th, 2012 at 00:25 | #2

    感谢分享。看完文章,感觉分析问题思路要清晰,方法要适当,值得学习。systemtap是个好工具!!

  3. September 29th, 2012 at 11:30 | #3

    online judge 控制资源也都是这么干的……

  4. tanyangxf
    September 29th, 2012 at 14:10 | #4

    如果程序跑一阵机器自动重启,日志中没什么信息可以看,有没有办法监控?

  5. September 29th, 2012 at 14:59 | #5

    不错,值得学习!

  6. Raymond
    November 18th, 2012 at 17:56 | #6

    什么时候会需要设置-t呢?这会让问题调查变得很诡异

    Yu Feng Reply:

    ulimit这些限制很过时了,不建议去配置。

Comments are closed.