2009-12-20 94 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的()。