GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana saya bisa tahu di Linux proses mana yang mengirim sinyal ke proses saya

Saya juga perlu mengidentifikasi pengirim sinyal dalam suatu program, jadi saya mengambil jawaban grawity, dan menggunakannya dalam program saya, itu berfungsi dengan baik.

Berikut contoh kodenya:

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

Kompilasi:

gcc -pthread -Wall send_signal_raise.c

Jalankan:

./a.out

Apa fungsinya:

Program mengirimkan SIGINT ke dirinya sendiri 10 kali, sebelum mengirim SIGQUIT untuk mengakhiri sendiri.

Juga, selama eksekusi, tekan CTRL +C untuk mengirim SIGINT , atau CTRL +\ untuk mengirim SIGQUIT yang akan mengakhiri program dengan tangan.

Program berhasil mengidentifikasi siapa yang mengirim sinyal.


BCC menyertakan killsnoop kegunaan. Ini membutuhkan kernel dengan dukungan BPF.

Kutipan dari halaman manual 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.

Dua metode khusus Linux adalah SA_SIGINFO dan signalfd() , yang memungkinkan program menerima sangat informasi mendetail tentang sinyal yang dikirim, termasuk PID pengirim.

  • Panggil sigaction() dan berikan struct sigaction padanya yang memiliki penangan sinyal yang diinginkan di sa_sigaction dan SA_SIGINFO tandai di sa_flags mengatur. Dengan bendera ini, penangan sinyal Anda akan menerima tiga argumen, salah satunya adalah siginfo_t struktur yang berisi PID dan UID pengirim.

  • Hubungi signalfd() dan baca signalfd_siginfo struktur dari itu (biasanya dalam beberapa jenis loop pilih/jajak pendapat). Isinya akan mirip dengan siginfo_t .

Yang mana yang akan digunakan bergantung pada bagaimana aplikasi Anda ditulis; mereka mungkin tidak akan bekerja dengan baik di luar C biasa, dan saya tidak memiliki harapan untuk membuatnya bekerja di Jawa. Mereka juga tidak portabel di luar Linux. Mereka juga kemungkinan besar adalah Cara yang Sangat Salah dalam melakukan apa yang ingin Anda capai.


Linux
  1. Bagaimana menemukan Proses Yang Membunuh mysqld Dengan SIGKILL atau SIGTERM di Linux

  2. Cara Menentukan Proses Yang Menulis ke Disk di Linux

  3. Bagaimana saya bisa menghubungkan file di Linux?

  1. Bagaimana cara mengetahui proses mana yang menggunakan file di Linux?

  2. Bagaimana saya bisa tahu proses mana yang menggunakan swap?

  3. Bagaimana saya bisa menentukan proses apa yang membuka file di Linux?

  1. Bagaimana saya bisa mencatat semua peluncuran proses di Linux?

  2. Bagaimana Saya Dapat Membuat File Dump dari Proses yang Berjalan di Linux?

  3. Bagaimana saya bisa mengatur afinitas prosesor dari suatu proses di Linux?