GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo puedo saber en Linux qué proceso envió una señal a mi proceso?

También necesitaba identificar el remitente de la señal en un programa, así que tomé la respuesta de grawity y la usé en mi programa, funciona bien.

Aquí está el código de muestra:

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

Compilar:

gcc -pthread -Wall send_signal_raise.c

Ejecutar:

./a.out

Qué hace:

El programa envía SIGINT a sí mismo 10 veces, antes de enviar SIGQUIT terminarse a sí mismo.

Además, durante su ejecución, presione CTRL +C enviar SIGINT o CTRL +\ enviar SIGQUIT que terminaría el programa a mano.

El programa pudo identificar con éxito quién envió la(s) señal(es).


BCC incluye el killsnoop utilidad. Requiere un kernel con soporte BPF.

Extracto de la página del manual de 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.

Dos métodos específicos de Linux son SA_SIGINFO y signalfd() , que permite que los programas reciban muy información detallada sobre las señales enviadas, incluido el PID del remitente.

  • Llama al sigaction() y pasarle un struct sigaction que tiene el controlador de señal deseado en sa_sigaction y el SA_SIGINFO bandera en sa_flags establecer. Con esta bandera, su controlador de señal recibirá tres argumentos, uno de los cuales es un siginfo_t estructura que contiene el PID y el UID del remitente.

  • Llama al signalfd() y lee signalfd_siginfo estructuras a partir de él (normalmente en algún tipo de bucle de selección/sondeo). El contenido será similar a siginfo_t .

Cuál usar depende de cómo esté escrita su aplicación; probablemente no funcionarán bien fuera de C simple, y no tendría ninguna esperanza de que funcionen en Java. Tampoco son portátiles fuera de Linux. También es probable que sean la forma muy incorrecta de hacer lo que está tratando de lograr.


Linux
  1. Cómo instalar vtop en Linux

  2. ¿Cómo puedo saber si estoy en una pantalla?

  3. ¿Cómo puedo determinar qué proceso tiene un archivo abierto en Linux?

  4. ¿Cómo puedo saber qué versión de Linux estoy usando?

  5. ¿Cómo puedo saber con qué límite de usuarios me estoy encontrando?

Cómo matar un proceso en Linux

Cómo MATAR un proceso en Linux

¿Qué es un proceso detenido en Linux?

¿Cómo puedo crear un archivo de volcado de un proceso en ejecución en Linux?

¿Cómo puedo configurar la afinidad del procesador de un proceso en Linux?

¿Cómo puedo saber qué archivos tiene abiertos un proceso?