Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the code for default signal handler in ELF binary?

I know that when we hit Ctrl+C, a SIGINT signal will be raised and the default action of terminating the process will be done by kernel. But where is the code for this termination coming from? Is it in the ELF binary or the kernel does it for us? I presume it is in the kernel and that is why we need custom handlers in our source code to override the signal behavior.

Any pointers will be much appreciated.

like image 980
bawejakunal Avatar asked Sep 17 '15 08:09

bawejakunal


People also ask

What is a Default signal handler?

A Default signal handler is associated with every signal that the kernel runs when handling that signal. The action that a script or program performs when it receives a signal is called the default actions. A default signal handler handles these types of different default actions.

Does signal () call the signal handler?

The signal() system call just installs the handler: "signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer-defined function (a "signal handler")." There you go.

What's a signal and how is it handled by the kernel?

A signal is a notification to a process that an event has occurred, and can be sent by the kernel, another process, or by itself. The delivery of a signal is asynchronous. You can send a signal to a process using the kill system call.

What happens when a process receives a signal?

When a process receives a signal, a default action happens, unless the process has arranged to handle the signal. For the list of signals and the corresponding default actions, see signal(7).


1 Answers

It is something kernel is doing for us. You can find all the information by reading signal.c file in kernel sources.

The point where kernel is trying to find a registered signal handler starts here: http://lxr.free-electrons.com/source/kernel/signal.c#L2257

2257                 ka = &sighand->action[signr-1];
2258 
2259                 /* Trace actually delivered signals. */
2260                 trace_signal_deliver(signr, &ksig->info, ka);
2261 
2262                 if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
2263                         continue;
2264                 if (ka->sa.sa_handler != SIG_DFL) {
2265                         /* Run the handler.  */
2266                         ksig->ka = *ka;
2267 
2268                         if (ka->sa.sa_flags & SA_ONESHOT)
2269                                 ka->sa.sa_handler = SIG_DFL;
2270 
2271                         break; /* will return non-zero "signr" value */
2272                 }

So, if there's a signal handler and if it is not "ignore signal" (SIG_IGN) and if it is not "default" handler (SIG_DEF), kernel will simply mark it for being run (and depending if it's one-shot it will move handler to default handler again).

However, if there's no signal handler registered, or if it is SIG_DEF, kernel checks if maybe it needs to pause the process, and finally kernel states the following:

2330                 /*
2331                  * Anything else is fatal, maybe with a core dump.
2332                  */

http://lxr.free-electrons.com/source/kernel/signal.c#L2330

like image 87
Nemanja Boric Avatar answered Nov 15 '22 22:11

Nemanja Boric