GNU/Linux >> Znalost Linux >  >> Linux

Jak mohu v Linuxu zjistit, který proces poslal mému procesu signál

Potřeboval jsem také identifikovat odesílatele signálu v programu, takže jsem vzal Grawityho odpověď a použil jsem ji ve svém programu, funguje to dobře.

Zde je ukázkový kód:

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

Zkompilujte:

gcc -pthread -Wall send_signal_raise.c

Provést:

./a.out

Co to dělá:

Program odešle SIGINT 10krát sobě, před odesláním SIGQUIT aby se sám ukončil.

Během jeho provádění také stiskněte CTRL +C odeslat SIGINT nebo CTRL +\ odeslat SIGQUIT která by program ukončila ručně.

Program mohl úspěšně identifikovat, kdo vyslal signál(y).


BCC obsahuje killsnoop utility. Vyžaduje jádro s podporou BPF.

Výňatek z manuálové stránky 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.

Dvě metody specifické pro Linux jsou SA_SIGINFO a signalfd() , která umožňuje programům přijímat velmi podrobné informace o odeslaných signálech, včetně PID odesílatele.

  • Zavolejte na číslo sigaction() a předejte mu struct sigaction který má požadovaný ovladač signálu v sa_sigaction a SA_SIGINFO příznak v sa_flags soubor. S tímto příznakem obdrží váš operátor signálu tři argumenty, z nichž jeden je siginfo_t struktura obsahující PID a UID odesílatele.

  • Zavolejte na číslo signalfd() a přečtěte si signalfd_siginfo struktur z něj (obvykle v nějakém druhu výběrové/poll smyčky). Obsah bude podobný siginfo_t .

Který z nich použít, závisí na tom, jak je vaše aplikace napsána; pravděpodobně nebudou dobře fungovat mimo prosté C a neměl bych žádnou naději, že je zprovozním v Javě. Jsou také nepřenosné mimo Linux. Jsou také pravděpodobně velmi špatným způsobem, jak dělat to, čeho se snažíte dosáhnout.


Linux
  1. Jak zjistit, který proces zabíjí mysqld pomocí SIGKILL nebo SIGTERM na Linuxu

  2. Jak zjistit, který proces zapisuje na disk v Linuxu

  3. Jak poznám, že jsem na obrazovce?

  1. Jak zjistit, který proces používá soubor v Linuxu?

  2. Jak mohu zaznamenat všechna spuštění procesů v Linuxu?

  3. Jak mohu vytvořit soubor výpisu běžícího procesu v Linuxu?

  1. Jak zjistím, na jaký uživatelský limit narážím?

  2. Jak zjistím, jaké soubory má proces otevřené?

  3. Jak mohu zjistit, který proces vytváří UDP provoz v Linuxu?