简体   繁体   中英

how to intercept linux signals ? (in C)

I need to intercept and trace signals from any binaries, like strace does it under linux. I don't need a so verbose output like the real one strace. I just want to know how it works, how can I intercept signal and how can I trace them. Thanks in advance :)

strace uses the ptrace() system call for tracing, which also allows you to intercept (and possibly manipulate) signals sent to the process.

Here's a tiny example:

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

This is a simple implementation:

Put somewhere in your int main() several calls to signal() , one for each signal you want to catch. The first argument is the signal name; the second is the signal handler function (more on that below):

    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

Now, write a signal function. It must return void and accept an int: void SignalHandler(int signal_number) :

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

That's it! You can also test it by sending a signal to yourself with the function raise(SIGNAL_NAME) ; for example, try raise(SIGTERM); !

Intercepting signals to other processes is something you should not do for any reason other than debugging them. This is what strace is intended for. Processes should be capable of handling their own signals.

Needless to say, if you are writing a debugger, understand ptrace().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM