向 init 发送不同的终止信号 - 如何记录

向 init 发送不同的终止信号 - 如何记录

我必须编写一个 C 程序来检查 init 如何响应不同的终止信号,但是我不确定如何记录它 - 例如,信号编号​​ 14 会使 ubuntu 崩溃,然后某个更高的信号会将其关闭。有没有办法正确地记录它,以便我知道系统如何响应每个信号?这是我使用的 C 代码,任何反馈也将不胜感激:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    int sigs[64] = { 0 };
    for(int i = 0; i < 64; i++) sigs[i] = i+1;
    char sigs_char[64][2];
    for(int i = 0; i < 64; i++) sprintf(sigs_char[i], "%d", sigs[i]);

    char one[2] = " 1";

    char commands[64][128];
    for(int i = 0; i < 64; i++){
        strcpy(commands[i], "sudo kill -s ");
        strncat(commands[i], sigs_char[i], 2);
        strcat(commands[i], one);
    }

    for(int i = 0; i < 64; i++){
        printf("Sending signal number %d\n", i);
        system(commands[i]);
    }
    return 0;
}

答案1

恐怕没有通用的方法来“记录”init的反应。首先,事实是kill不会向 发送任何未处理的信号initinit来自man 2 kill):

NOTES
       The only signals that can be sent to process ID 1,  the  init  process,
       are  those  for  which  init  has explicitly installed signal handlers.
       This is done to assure the system is not brought down accidentally.

因此,对于许多信号来说,根本不会有反应。现在剩下的信号是处理。使用这个Unix和Linux问题,我们可以确定那些1

$ HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/1/status)
$ for i in {0..31}; do (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); done | column
1 HUP   6 ABRT  11 SEGV 15 TERM 30 PWR
2 INT   10 USR1 14 ALRM 17 CHLD 32

这些:

  • SIGABRTSIGSEGV导致核心转储和内核崩溃。这里没有检测到任何东西。
  • SIGTERM导致它重新加载,日志消息如下/var/log/syslog

    Nov 14 00:25:13 vm kernel: [32383.384907] init: upstart-udev-bridge main process (395) terminated with status 1
    Nov 14 00:25:13 vm kernel: [32383.384916] init: upstart-udev-bridge main process ended, respawning
    Nov 14 00:25:13 vm kernel: [32383.384990] init: upstart-socket-bridge main process (649) terminated with status 1
    Nov 14 00:25:13 vm kernel: [32383.384995] init: upstart-socket-bridge main process ended, respawning
    Nov 14 00:25:13 vm kernel: [32383.385059] init: upstart-file-bridge main process (953) terminated with status 1
    Nov 14 00:25:13 vm kernel: [32383.385074] init: upstart-file-bridge main process ended, respawning
    
  • SIGINT导致它开始重新启动,并SIGPWR开始关机。两者看起来都像正常的(例如,就像你做了一样reboot)。
  • 其余均未造成任何明显影响。(不过,考虑到init的职责,我们可以猜出什么SIGCHLD造成了影响。)

所有这些都是为了 Upstart。谁知道 SysV 或 systemd 会如何反应?

所以,总而言之,你在这里使用经验方法不会有太大的运气。使用来源,卢克。


1init这段复杂的代码是为了获取愿意捕获的信号:

HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/1/status)
for i in {0..31} 
do 
    (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); 
done | column
  • HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/1/status)/proc/$PID/status包含有关该过程的大量信息,包括处理的信号集。该集合由 给出SigCgt,即以十六进制数给出的位掩码。我们使用awk提取该数字并添加0x为前缀。
  • (( (1 << i) & $HANDLED_SIGS )):检查信号号是否(i+1)被屏蔽。由于我们关心的是第i位,因此我们使用 2 (i-1)(即1 << i)。对于(( )),非零值表示成功。

相关内容