Как я могу сказать в Linux, какой процесс послал мой процесс сигнал - PullRequest
26 голосов
/ 04 декабря 2011

У меня есть Java-приложение, получившее SIG TERM. Я хочу знать pid процесса, который отправил этот сигнал.
Это возможно?

Ответы [ 3 ]

30 голосов
/ 05 декабря 2011

Два специфичных для Linux метода: SA_SIGINFO и signalfd(), что позволяет программам получать очень подробную информацию об отправленных сигналах, включая отправителяPID.

  • Вызовите sigaction() и передайте ему struct sigaction, который имеет нужный обработчик сигнала в sa_sigaction и флаг SA_SIGINFO в sa_flags установлено.С этим флагом ваш обработчик сигнала будет получать три аргумента, один из которых является siginfo_t структурой, содержащей PID и UID отправителя.

  • Call signalfd() и чтение signalfd_siginfo структур из него (обычно в каком-то цикле выбора / опроса).Содержание будет похоже на siginfo_t.

Какой из них использовать, зависит от того, как написано ваше приложение;они, вероятно, не будут хорошо работать вне простого C, и у меня не было бы никакой надежды заставить их работать на Java.Они также непереносимы вне Linux.Они также, вероятно, являются Очень Неправильным Способом делать то, чего вы пытаетесь достичь.

9 голосов
/ 25 июля 2015

Мне также нужно было идентифицировать отправителя сигнала в программе, поэтому я взял ответ от 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 себе 10перед отправкой SIGQUIT для завершения.

Кроме того, во время его выполнения нажмите CTRL + C для отправки SIGINT или CTRL + \ для отправки SIGQUIT, что приведет к завершению программы вручную.

Программа может успешно определить, кто отправил сигнал (ы).

1 голос
/ 05 декабря 2011

Нет, сигналы не предназначены для межпроцессного взаимодействия.Насколько я знаю, PID не передается.Отправляющий PID не имеет значения для всех применений, которые я видел для сигналов.Вы можете быть относительно уверены, что процессы, отправляющие сигнал, либо имеют привилегии root, либо принадлежат к тому же UID, что и ваш процесс.

Возможно, что процесс, который отправил сигнал, больше не существует.Если команда kill использовалась вместо встроенной оболочки, то почти наверняка процесс больше не существует.

Со стороны Java это еще сложнее.Процесс выполняется на виртуальной машине Java, которая абстрагируется от операционной системы.Не все концепции операционной системы существуют на этом компьютере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...