user2365346
user2365346

Reputation: 497

How to check the signal handler in Linux

I have read this discussion which discuss about how to check the signal actions of each process: How can I check what signals a process is listening to?

However, I want to use C/C++, Python or other ways to get the userspace of the signal handler name of each process. Just like the psig in Solaris: What is the meaning of every column when executing psig command?

Would it be possible to do that in Linux?

Upvotes: 0

Views: 1786

Answers (1)

Nominal Animal
Nominal Animal

Reputation: 39316

Because the Linux kernel does not expose the signal handlers (other than using the sigaction() (or signal()) syscall in the process itself), you need to inject executable code to the target process to obtain this information.

(Or, alternatively, create a Linux kernel module that exposes this information.)

So, this is definitely a question.

Note that it is not possible to always obtain the name of a function, because the handler can be declared static void without any particular name in the binary.


The easiest approach would be to create a dynamic library to interpose signal() and sigaction(), with an ELF constructor function (not related to C++; Linux ELF binaries just support marking functions "constructor", in which case they are automatically executed prior to main()) that opens a suitable log file in write-only append mode, say /var/log/sighandlers/PID.log, and dumps the contents of /proc/self/maps to record the addresses the binaries are loaded in. The interposed functions will then simply write the addresses of newly assigned handlers to the log file.

It is important to note that both sigaction() and signal() are async-signal safe functions, so the interposed versions should be, too. (Fortunately, you only need write(), which is async-signal safe. I recommend using dlsym() to look up the original function pointers in the ELF constructor function.)

When examining the log file, the function addresses should be calculated relative to the beginning of the binary mapping, then objdump -tT binary or objdump -d binary to find the symbol the address belongs to.

I would personally not bother with any other approaches, even if this requires one to execute each binary using a special command (setting LD_LIBRARY_PATH) to find them out; it is either that, or a kernel module.

Upvotes: 1

Related Questions