GNU/Linux >> Linux の 問題 >  >> Linux

どのプロセスが自分のプロセスにシグナルを送信したかをLinuxで確認するにはどうすればよいですか

また、プログラムでシグナル送信者を特定する必要があったため、grawity の回答を使用して、プログラムで使用しました。

サンプル コードは次のとおりです。

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

コンパイル:

gcc -pthread -Wall send_signal_raise.c

実行:

./a.out

機能:

プログラムは SIGINT を送信します SIGQUIT を送信する前に、自分自身に 10 回

また、実行中に CTRL を押します +C SIGINT を送信する 、または CTRL +\ SIGQUIT を送信する これにより、プログラムが手動で終了します。

プログラムは、シグナルの送信者を特定できました。


BCC には killsnoop が含まれます 効用。 BPF をサポートするカーネルが必要です。

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.

2 つの Linux 固有の方法は SA_SIGINFO です と signalfd() 、これにより、プログラムは very を受け取ることができます 送信者の PID を含む、送信されたシグナルに関する詳細情報。

  • sigaction() に電話する それに struct sigaction を渡します sa_sigaction に目的のシグナル ハンドラがある そして SA_SIGINFO sa_flags のフラグ 設定。このフラグを使用すると、シグナル ハンドラは 3 を受け取ります 引数、そのうちの 1 つは siginfo_t です 送信者の PID と UID を含む構造。

  • signalfd() に電話する signalfd_siginfo を読み取ります それからの構造 (通常、ある種の選択/ポーリング ループ内)。内容は siginfo_t のようになります .

どちらを使用するかは、アプリケーションの作成方法によって異なります。それらはおそらく普通の C 以外ではうまく動作しないでしょうし、Java で動作させる望みも私にはありません。また、Linux 以外では移植できません。それらは、あなたが達成しようとしていることの非常に間違った方法である可能性もあります.


Linux
  1. Linux で SIGKILL または SIGTERM を使用して mysqld を強制終了しているプロセスを見つける方法

  2. Linuxでファイルを使用しているプロセスを見つける方法は?

  3. スワップを使用しているプロセスを知るにはどうすればよいですか?

  1. Linux でプロセスのプロセッサ アフィニティを設定するにはどうすればよいですか?

  2. 使用している Linux のバージョンを確認するにはどうすればよいですか?

  3. プロセスが開いているファイルを確認するにはどうすればよいですか?

  1. Linux でディスクに書き込みを行っているプロセスを特定する方法

  2. Linuxでファイルをシンボリックリンクするにはどうすればよいですか?

  3. 自分が画面にいるかどうかを確認するにはどうすればよいですか?