Sending different kill signals to init - how to log

I have to write a C program to check how init reacts to different kill signals, however I am not sure how to log it - for example signal number 14 crashes the ubuntu, then some higher one turns it off. Is there any way to log it properly so that I know how does system react to each signal? Here is the C code I use, any feedback on that would be also appreciated:

#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;
}
3

1 Answer

I'm afraid there's no general way to "log" init's reaction. First, there's the fact that kill won't deliver any signals to init that init isn't handling (from 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.

So, for many signals, there won't be a reaction at all. Now that leaves the signals that are handled. Using this Unix & Linux question, we can determine those1:

$ 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

Of these:

  • SIGABRT and SIGSEGV caused core dumps and kernel panics. Nothing to be detected here.
  • SIGTERM caused it to reload, with log messages in /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 caused it to start a reboot, and SIGPWR started a shutdown. Both looked like normal ones (say, like if you did a reboot, for example).
  • None of the others caused any visible effects. (Though, considering init's duties, we can guess what SIGCHLD does.)

And all this is for Upstart. Who knows how SysV or systemd will react?

So, all in all, you're not going to have much luck with empirical methods here. Use the Source, Luke.


1That convoluted bit of code is for getting the signals that init is willing to catch:

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 contains a wealth of information about the process, including the set of handled signals. This set is given by SigCgt, a bitmask given as a hexadecimal number. We use awk to extract that number and add 0x as a prefix.
  • (( (1 << i) & $HANDLED_SIGS )): check if signal no. (i+1) is masked. Since we're concerned about the ith bit, we use 2(i-1) (which is 1 << i). With (( )), a non-zero value indicates success.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like