2009-12-20 6 views
3

J'ai besoin d'intercepter et de tracer les signaux de n'importe quel binaire, comme strace le fait sous linux. Je n'ai pas besoin d'une sortie aussi verbeuse comme la vraie une strace. Je veux juste savoir comment cela fonctionne, comment puis-je intercepter le signal et comment puis-je les tracer. Merci d'avance :)comment intercepter les signaux Linux? (en C)

Répondre

3

strace utilise l'appel système ptrace() pour le traçage, qui vous permet également d'intercepter (et éventuellement de manipuler) les signaux envoyés au processus.

Voici un petit exemple:

#include <sys/ptrace.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
    /* simple example, child is traced, uses alarm which causes a signal to be 
    * set up */ 
    pid_t child; 

    child = fork(); 
    if (child == 0) 
    { 
     ptrace(PTRACE_TRACEME, 0, NULL, NULL); 
     alarm(3); 
     while(1) 
     { 
     } 
     exit(0); 
    } 

    /* parent */ 
    while(1) 
    { 
     int wstatus; 
     int signum; 

     wait(&wstatus); 
     if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus)) 
      break; 

     signum = WSTOPSIG(wstatus); 
     printf("child stopped with signal %d\n", signum); 
     /* resume execution */ 
     ptrace(PTRACE_CONT, child, NULL, signum); 
    } 

    return 0; 
} 
1

C'est la mise en œuvre plus simple!

Mettez quelque part dans votre int main() plusieurs appels à signal(), un pour chaque signal que vous voulez attraper. Le premier argument est le nom du signal; la seconde est la fonction de gestionnaire de signal (plus de détails ci-dessous):

signal(SIGFPE, SignalHandler); 
    signal(SIGILL, SignalHandler); 
    signal(SIGINT, SignalHandler); 
    signal(SIGSEGV, SignalHandler); 
    signal(SIGTERM, SignalHandler); 
#ifndef WIN32 
    signal(SIGHUP, SignalHandler); 
    signal(SIGQUIT, SignalHandler); 
    signal(SIGKILL, SignalHandler); 
    signal(SIGPIPE, SignalHandler); 
    signal(SIGCHLD, SignalHandler); 
#endif 

Maintenant, écrivez une fonction de signal. Elle doit retourner vide et accepter un int: void SignalHandler(int signal_number):

void SignalHandler(int signal_number) 
{ 
    printf("Received signal: %s\n", strsignal(signal_number); 
    // Do something 
} 

Ca y est! Vous pouvez également le tester en vous envoyant un signal avec la fonction raise(SIGNAL_NAME); par exemple, essayez raise(SIGTERM);!

0

L'interception de signaux vers d'autres processus est quelque chose que vous ne devriez pas faire pour d'autres raisons que de les déboguer. C'est ce pour quoi strace est destiné. Les processus doivent être capables de gérer leurs propres signaux.

Inutile de dire que si vous écrivez un débogueur, comprenez ptrace().

Questions connexes