GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann ich unter Linux feststellen, welcher Prozess meinem Prozess ein Signal gesendet hat?

Ich musste auch den Signalsender in einem Programm identifizieren, also habe ich die Antwort von grawity genommen und in meinem Programm verwendet, es funktioniert gut.

Hier ist der Beispielcode:

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

Kompilieren:

gcc -pthread -Wall send_signal_raise.c

Ausführen:

./a.out

Funktion:

Das Programm sendet SIGINT 10 mal an sich selbst, bevor SIGQUIT gesendet wird um sich selbst zu beenden.

Drücken Sie außerdem während der Ausführung CTRL +C um SIGINT zu senden , oder CTRL +\ um SIGQUIT zu senden was das Programm von Hand beenden würde.

Das Programm konnte erfolgreich identifizieren, wer das/die Signal(e) gesendet hat.


BCC enthält den killsnoop Dienstprogramm. Es erfordert einen Kernel mit BPF-Unterstützung.

Auszug aus der man-page von 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.

Zwei Linux-spezifische Methoden sind SA_SIGINFO und signalfd() , wodurch Programme sehr empfangen können detaillierte Informationen über gesendete Signale, einschließlich der PID des Absenders.

  • Rufen Sie sigaction() an und übergebe ihm einen struct sigaction die den gewünschten Signalhandler in sa_sigaction hat und die SA_SIGINFO Flag in sa_flags einstellen. Mit diesem Flag erhält Ihr Signalhandler drei Argumente, von denen eines ein siginfo_t ist Struktur, die die PID und UID des Absenders enthält.

  • Rufen Sie signalfd() an und lesen Sie signalfd_siginfo Strukturen daraus (normalerweise in einer Art Select/Poll-Schleife). Der Inhalt ähnelt siginfo_t .

Welche Sie verwenden sollten, hängt davon ab, wie Ihre Anwendung geschrieben ist. Sie werden wahrscheinlich nicht gut außerhalb von C funktionieren, und ich hätte keine Hoffnung, sie in Java zum Laufen zu bringen. Sie sind auch außerhalb von Linux nicht portierbar. Sie sind wahrscheinlich auch der völlig falsche Weg, um das zu erreichen, was Sie erreichen möchten.


Linux
  1. So beenden Sie einen Zombie-Prozess unter Linux

  2. So installieren Sie vtop unter Linux

  3. So bestimmen Sie, welcher Prozess in Linux auf die Festplatte schreibt

  4. Wie kann ich eine Datei unter Linux symbolisch verknüpfen?

  5. Wie kann ich feststellen, ob ich mich in einem Bildschirm befinde?

So beenden Sie einen Prozess in Linux

Wie man einen Prozess unter Linux beendet

Wie kann ich feststellen, welcher Prozess eine Datei in Linux geöffnet hat?

Was ist ein gestoppter Prozess unter Linux?

Wie kann ich feststellen, welche Version von Linux ich verwende?

Wie kann ich feststellen, auf welches Benutzerlimit ich stoße?