2009-12-20 34 views
3

我需要拦截和跟踪任何二进制文件的信号,比如strace在linux下执行。 我不需要像真正的strace那样输出如此冗长的输出。 我只是想知道它是如何工作的,我如何拦截信号,以及如何追踪它们。 在此先感谢:)如何截取linux信号? (在C)

回答

3

strace使用ptrace()系统调用进行跟踪,这也允许您拦截(并可能操纵)发送到进程的信号。

这里有一个小例子:

#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

这是最简单的实现!

int main()几个电话某处放至signal(),每个信号你想赶上。第一个参数是信号名称;第二个是信号处理函数(更多地在下面):

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 

现在写一个信号函数。它必须返回void并接受int:void SignalHandler(int signal_number)

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

就是这样!您也可以通过使用功能raise(SIGNAL_NAME)向您自己发送信号来测试它;例如,请尝试raise(SIGTERM);

0

截取信号到其他进程是你除了调试以外不应该做的任何事情。这是strace的意图。进程应该能够处理他们自己的信号。

不用说,如果你正在写一个调试器,了解ptrace的()。