开发者

how to intercept linux signals ? (in C)

开发者 https://www.devze.com 2022-12-14 06:54 出处:网络
I need to intercept and trace sign开发者_如何学Goals from any binaries, like strace does it under linux.

I need to intercept and trace sign开发者_如何学Goals 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().

0

精彩评论

暂无评论...
验证码 换一张
取 消