简体   繁体   中英

Linux: how to check which handler is handling the signals

The /proc/PID/status show that which signal is caught by the process. However, I wonder how to check which handler is handling the signal(s). For example:

void  handler1(int sigNum)      
{
    if(sigNum == SIGINT)
        printf("handler1 is handling SIGINT\n");
} 

void  handler2(int sigNum)      
{
    if(sigNum == SIGINT)
        printf("handler2 is handling SIGINT\n");
} 

void main()
{
    signal(SIGINT, handler1);
    signal(SIGINT, handler2);
    while(1);
}

The main function has registered two signal handlers to handle the SIGINT. how to know handler1 or handler2 has been registered to handle SIGINT and is handling SIGINT? I want to do the same thing just like psig under the Solaris. What is the meaning of every column when executing psig command?

I've experimented with a monitoring program that executes a target process with signal() , sigaction() , and fork() interposed, using a dynamic helper library. The monitoring program listens for incoming Unix domain connections.

The dynamic library is very simple. At startup (using the GCC constructor attribute supported in Linux ELF binaries), it connects to the monitoring program. (After a successful fork() , the new process will close its copy of the descriptor, and open a new connection.) At each signal() or sigaction() invocation, it reports the signal name to the monitoring program using

struct change {
    uint64_t      addr;
    char          name[15];
    unsigned char info;       /* SA_RESETHAND; SIG_DFL/SIG_IGN */
};

The library maps signal numbers to names (like SIGINT to "INT" , or SIGRTMIN+3 to "RTMIN+3" ) or plain decimal number strings for unrecognized signal numbers. This allows a single 64-bit monitoring program to monitor a mix of 64-bit and 32-bit processes.

The info field is used for reporting SA_RESETHAND ( SA_ONESHOT ) signal handlers, which get reset to default disposition when the signal is delivered to the handler. It is also used to indicate SIG_DFL and SIG_IGN handlers, plus possibly other special events.

When a new connection is made, the monitoring program uses readelf -W --syms --dyn-syms or objdump -tT or objdump -d on /proc/PID/exe , remembering the address (or address range) for each known function in the binary. It logs each struct change for each connection, along with a timestamp.

(When a connection is made, the interposing library must "pause" until the monitoring program has examined the binary. Otherwise, short-running binaries may have exited (or executed another binary) before the monitoring program has had time to examine the correct binary.)

On my system, bash installs a SIGCHLD handler for address 447ad0, which does not have a symbol associated. If the known symbols are sorted in ascending order, and handlers are specified relative to the nearest symbol, then that handler could be reported as reap_dead_jobs+40 <447ad0> , for example. (Note that reap_dead_jobs resides at [447a90, 447ac1), so finding the symbol that covers the address will not suffice.)

Consider this a description of the approach that should work, based on my experiments. My own code needs a full rewrite to be useful; that is why I did not include it here. I'd expect the completed project to be around 600 - 900 lines of code.

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