Comment trouver la source d'un signal POSIX

13

Existe-t-il un moyen de découvrir l'origine d'un signal envoyé dans Red Hat Enterprise Linux 5 (SIGTERM, etc.)? Je piège régulièrement un TERM dans une application et je n'ai aucune idée d'où il vient.

user27451
la source

Réponses:

14

La page de manuel pour sigaction(2)suggère que le PID de l'expéditeur du signal est disponible dans la structure siginfo_t transmise à votre gestionnaire de signal. Cela nécessite évidemment d'utiliser sigaction ().

Depuis la page de manuel:

La structure de sigaction est définie comme quelque chose comme:

   struct sigaction {
       void     (*sa_handler)(int);
       void     (*sa_sigaction)(int, siginfo_t *, void *);
       sigset_t   sa_mask;
       int        sa_flags;
       void     (*sa_restorer)(void);
   };

Et la siginfo_tstructure ressemble à ceci:

   siginfo_t {
       int      si_signo;    /* Signal number */
       int      si_errno;    /* An errno value */
       int      si_code;     /* Signal code */
       int      si_trapno;   /* Trap number that caused
                                hardware-generated signal
                                (unused on most architectures) */
       pid_t    si_pid;      /* Sending process ID */
       uid_t    si_uid;      /* Real user ID of sending process */
       int      si_status;   /* Exit value or signal */
       clock_t  si_utime;    /* User time consumed */
       clock_t  si_stime;    /* System time consumed */
       sigval_t si_value;    /* Signal value */
       int      si_int;      /* POSIX.1b signal */
       void    *si_ptr;      /* POSIX.1b signal */
       int      si_overrun;  /* Timer overrun count; POSIX.1b timers */
       int      si_timerid;  /* Timer ID; POSIX.1b timers */
       void    *si_addr;     /* Memory location which caused fault */
       int      si_band;     /* Band event */
       int      si_fd;       /* File descriptor */
   }
larsks
la source
Merci pour la réponse, ne m'attendais pas à autant de détails. J'utilise l'encapsuleur de service Java, et lorsqu'il est défini sur "déboguer", il affichera quelque chose comme ceci: Signal piégé. Détails: numéro de signal = 15 (SIGTERM), source = "kill, sigsend or raise" signal généré par PID: 2194 (Session PID: 2164), UID: 1002 (en plein air) que j'ai découvert après avoir recherché "si_pid" et trouvé le wrapper source unix c. :-)
user27451
1

Sur les plates-formes avec DTrace (OS X, Solaris,… autres?), Vous pouvez l'utiliser avec une sonde comme celle-ci pour enregistrer les informations que vous recherchez:

sudo dtrace -n 'proc:::signal-send { printf("Process %d (%s by UID %d) sending signal %d to pid=%d\n",pid,execname,uid,args[2],args[1]->pr_pid); }'

J'ai basé cela sur un script trouvé au bas de http://www.brendangregg.com/DTrace/dtrace_oneliners.txt ainsi que quelques conseils supplémentaires sur les "noms de variable pertinents" sur /programming//a/10465606/179583 , et semble fonctionner sous certains tests de base. Maintenant, si seulement mon processus mourait de façon inattendue! ;-)

natevw
la source
1
Pour d'autres plates-formes, il y a stracece qui sert le même but si je ne me trompe pas. J'ai pu retracer les signaux reçus par un processus en suivant cet article .
Aaron
-2

Non, vous ne pouvez pas savoir qui envoie un signal.

sntg
la source
2
Ce n'est pas nécessairement le cas.
larsks