GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso sapere in Linux quale processo ha inviato un segnale al mio processo

Avevo anche bisogno di identificare il mittente del segnale in un programma, quindi ho preso la risposta di grawity e l'ho usata nel mio programma, funziona bene.

Ecco il codice di esempio:

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

Compila:

gcc -pthread -Wall send_signal_raise.c

Esegui:

./a.out

Cosa fa:

Il programma invia SIGINT a se stesso 10 volte, prima di inviare SIGQUIT per terminare se stesso.

Inoltre, durante la sua esecuzione, premi CTRL +C per inviare SIGINT o CTRL +\ per inviare SIGQUIT che terminerebbe il programma a mano.

Il programma potrebbe identificare con successo chi ha inviato i segnali.


BCC include il killsnoop utilità. Richiede un kernel con supporto BPF.

Estratto dalla pagina man di 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.

Due metodi specifici di Linux sono SA_SIGINFO e signalfd() , che consente ai programmi di ricevere molto informazioni dettagliate sui segnali inviati, incluso il PID del mittente.

  • Chiama sigaction() e passagli un struct sigaction che ha il gestore di segnale desiderato in sa_sigaction e il SA_SIGINFO flag in sa_flags impostare. Con questo flag, il tuo gestore di segnale riceverà tre argomenti, uno dei quali è un siginfo_t struttura contenente PID e UID del mittente.

  • Chiama signalfd() e leggi signalfd_siginfo strutture da esso (di solito in una sorta di ciclo select/poll). I contenuti saranno simili a siginfo_t .

Quale usare dipende da come è scritta la tua applicazione; probabilmente non funzioneranno bene al di fuori del semplice C e non avrei alcuna speranza di farli funzionare in Java. Sono anche non portabili al di fuori di Linux. Probabilmente sono anche il modo molto sbagliato di fare ciò che stai cercando di ottenere.


Linux
  1. Come uccidere un processo zombie su Linux

  2. Come installare vtop su Linux

  3. Come determinare quale processo sta scrivendo su disco in Linux

  4. Come posso sapere se mi trovo su uno schermo?

  5. Come posso sapere quali file ha aperto un processo?

Come uccidere un processo in Linux

Come KILL un processo su Linux

Cos'è un processo interrotto in Linux?

Come posso sapere quale versione di Linux sto usando?

Come posso sapere in quale limite di utenti mi sto imbattendo?

Come posso identificare quale processo sta creando traffico UDP su Linux?