GNU/Linux >> Tutoriels Linux >  >> Linux

Comment puis-je savoir sous Linux quel processus a envoyé un signal à mon processus

J'avais aussi besoin d'identifier l'expéditeur du signal dans un programme, alors j'ai pris la réponse de Grawity et je l'ai utilisée dans mon programme, ça marche bien.

Voici l'exemple de code :

send_signal_raise.c

// send signal to self test - raise()

#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static int int_count = 0, max_int = 5;
static struct sigaction siga;

static void multi_handler(int sig, siginfo_t *siginfo, void *context) {
    // get pid of sender,
    pid_t sender_pid = siginfo->si_pid;

    if(sig == SIGINT) {
        int_count++;
        printf("INT(%d), from [%d]\n", int_count, (int)sender_pid);
        return;
    } else if(sig == SIGQUIT) {
        printf("Quit, bye, from [%d]\n", (int)sender_pid);
        exit(0);
    }

    return;
}

int raise_test() {
    // print pid
    printf("process [%d] started.\n", (int)getpid());

    // prepare sigaction
    siga.sa_sigaction = *multi_handler;
    siga.sa_flags |= SA_SIGINFO; // get detail info

    // change signal action,
    if(sigaction(SIGINT, &siga, NULL) != 0) {
        printf("error sigaction()");
        return errno;
    }
    if(sigaction(SIGQUIT, &siga, NULL) != 0) {
        printf("error sigaction()");
        return errno;
    }

    // use "ctrl + c" to send SIGINT, and "ctrl + \" to send SIGQUIT,
    int sig;
    while(1) {
        if(int_count < max_int) {
            sig = SIGINT;
        } else {
            sig  = SIGQUIT;
        }
        raise(sig); // send signal to itself,

        sleep(1); // sleep a while, note that: SIGINT will interrupt this, and make program wake up,
    }

    return 0;
}

int main(int argc, char *argv[]) {
    raise_test();
    return 0;
}

Compiler :

gcc -pthread -Wall send_signal_raise.c

Exécuter :

./a.out

Ce qu'il fait :

Le programme envoie SIGINT à lui-même 10 fois, avant d'envoyer SIGQUIT se terminer.

Aussi, lors de son exécution, appuyez sur CTRL +C pour envoyer SIGINT , ou CTRL +\ pour envoyer SIGQUIT qui terminerait le programme à la main.

Le programme a pu identifier avec succès qui a envoyé le(s) signal(s).


BCC inclut le killsnoop utilitaire. Il nécessite un noyau prenant en charge BPF.

Extrait de la page de manuel killsnoop (8) :

       killsnoop  traces  the  kill()  syscall, to show signals sent via this method. This may be
       useful to troubleshoot  failing  applications,  where  an  unknown  mechanism  is  sending
       signals.

       This  works by tracing the kernel sys_kill() function using dynamic tracing, and will need
       updating to match any changes to this function.

       This makes use of a Linux 4.5 feature (bpf_perf_event_output()); for  kernels  older  than
       4.5, see the version under tools/old, which uses an older mechanism.

       Since this uses BPF, only the root user can use this tool.

Deux méthodes spécifiques à Linux sont SA_SIGINFO et signalfd() , qui permet aux programmes de recevoir très des informations détaillées sur les signaux envoyés, y compris le PID de l'expéditeur.

  • Appelez le sigaction() et lui passer un struct sigaction qui a le gestionnaire de signal souhaité dans sa_sigaction et le SA_SIGINFO indicateur en sa_flags Positionner. Avec ce drapeau, votre gestionnaire de signal recevra trois arguments, dont l'un est un siginfo_t structure contenant le PID et l'UID de l'expéditeur.

  • Appelez le signalfd() et lire signalfd_siginfo structures à partir de celui-ci (généralement dans une sorte de boucle de sélection/interrogation). Le contenu sera similaire à siginfo_t .

Lequel utiliser dépend de la façon dont votre application est écrite ; ils ne fonctionneront probablement pas bien en dehors du C ordinaire, et je n'aurais aucun espoir de les faire fonctionner en Java. Ils sont également non portables en dehors de Linux. Ils sont également probablement la très mauvaise façon de faire ce que vous essayez d'accomplir.


Linux
  1. Comment installer vtop sur Linux

  2. Comment trouver quel processus tue mysqld avec SIGKILL ou SIGTERM sous Linux

  3. Comment puis-je lier symboliquement un fichier sous Linux?

  4. Comment puis-je savoir si je suis dans un écran ?

  5. Comment savoir quel processus utilise un fichier sous Linux ?

Comment tuer un processus zombie sous Linux

Comment tuer un processus sous Linux

Comment tuer un processus sous Linux

Comment puis-je enregistrer tous les lancements de processus sous Linux ?

Qu'est-ce qu'un processus arrêté sous Linux ?

Comment puis-je savoir quelle limite d'utilisateurs je rencontre ?