In Linux 2.6, I would like my process to catch both SIGHUP and SIGTERM in order to exit orderly.
When the node shuts down, logs show that it will handle either SIGHUP (the parent process receives SIGTERM) or SIGTERM first.
My question is: is there a possibility that the handlers for these signals are called concurrently? or the kernel triggers one after the other?
Depending on your code architecture you could enforce synchronous reading of signals preventing any concurrency issues. You could use signalfd and then read from that fd whenever you want to check on any outstanding signals. If you need them to behave in their asynchronous default with a signal handler I think you have to be prepared for your signal handler to be potentially interrupted.
man signalfd
In Asynchronous signals to a process, the Linux kernel send signals with a system call to target process structure and when context of the process is switched to RUN state, signals are handled by root thread and block signals on all other threads. Since the stack space is different for each thread each signal can be handled at a time(Correct if am wrong).
Related
Platform is Linux/POSIX.
The signal is sent to a whole process, not a specific thread.
No signal is set to blocked, all default.
The process is multi-thread process.
From what I've googled, a signal may be handled by a random thread.
And when that signal's handler is executing, it's temporarily blocked until handler returns.
QUESTION: Multiple signals of different types reached simultaneously. Do their handler execute simultaneously on multiple thread or all of them go to one randomly picked thread (SUB-QUESTION: in this case a handler could interrupt another handler's execution started previously, so there could be a interrupt stack?) ? Or mixed? For instance there are 3 type of signals received but only 2 thread free (this is actually the first case).
EXAMPLE: SIGHUP, SIGINT, SIGTERM reached almost simultaneously. The program has two available thread to dispatch signal handler execution.
SIDE-QUESTION: If signal handlers run in parallel, I'll have to use mutex to synchronize them properly. Otherwise 'volatile sig_atomic_t' would be enough, right?
Expected: all signals go to one thread (randomly picked) despite of their different signal types, I haven't seen an example of using mutexes and atoms to synchronize signal handlers.
Your understanding is correct - unless a signal was directed
to a specific thread, there's no guarantee which thread will handle a signal.
See POSIX's Signal Generation and Delivery and pthreads(7):
POSIX.1 distinguishes the notions of signals that are directed
to the process as a whole and signals that are directed to
individual threads. According to POSIX.1, a process-directed
signal (sent using kill(2), for example) should be handled by
a single, arbitrarily selected thread within the process.
So it may be delivered & handled by the same thread that's currently handling another signal (in that case, the previous handler may be interrupted by the new signal). Or may be delivered to another signal.
You can block other signals while one is being handled using sa_mask field
of sigaction to avoid a signal handler being interrupted.
SIDE-QUESTION: If signal handlers run in parallel, I'll have to use mutex to synchronize them properly. Otherwise 'volatile sig_atomic_t' would be enough, right?
You almost certainly don't want to use mutex in a signal handler. There are only few functions that can be safely called from a signal handler (you can only call the functions that are async-signal-safe).
See signal-safty for more information.
If you can use volatile sig_atomic_t for whatever the purpose (do you need to co-ordinate execution of different signal handlers?), it should be preferred.
Expected: all signals go to one thread (randomly picked) despite of their different signal types, I haven't seen an example of using mutexes and atoms to synchronize signal handlers.
This is commonly done by blocking signals that you're interested in from main and fetching/handling them in a specific thread. See pthread_sigmask which also has an example on how to implement this.
I'm currently learning how signals really works in POSIX-systems. Signals such as SIGTERM can be caught and handled with custom handlers, this means that the kernel propagates the signal to the process itself. On the other hand SIGKILL is not catchable and cannot be handled firstly because it is its main purpose - kill the process. But I'm wondering does this means that the SIGKILL is not even propagated to the process ? I mean if the users will send kill -9 to some process using terminal the kernel will immediately purge that process without even forwarding the signal to it, or the signal will still be forwarded to the process but with the exception that we cannot add a custom handler to it? Sorry, if you consider this question dummy! I'm just starting with POSIX systems
some signals can catch and we name those catchable signals and some are uncatchable. The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
You can see a complete list of signals and appropriate action here.
I am programming a tree of processes in Linux and I wonder if there is any signal that can be used just to send from A process to B process without affecting B process.
For example, assume B_pid is the process B's ID, if process A calls kill(B_pid, SIGSTOP); then A will pause B. What I am looking for is a signal, let's say SIGNOTHING, that when A calls kill(B_pid, SIGNOTHING), then it just simply sends a message to B rather than doing something to both B and the system.
SIGUSR1 and SIGUSR2 are designed for that purpose.
If you invoke the following command on your shell:
kill -l
you get a full list of signals available for your system.
Most of the signals can be used to simply "receive" them on the target side. BUT: Most signals are also used by the system itself to tell the application that something special happened, like SIGSEGV. So it makes no sense to use signals, which have a fixed meaning as they are used to communicate from kernel/OS to the application.
For user signals, you have two signals reserved, which can be used for everything you like: SIGUSR1 and SIGUSR2.
Not all Unix systems have these signals! So first take a look which signals can be used on your current system!
Additional hint:
Check you signal handlers and the context on which they are running. On some implementations it is not allowed to call non-reentrant functions from the context of the handler. So it is maybe more useful to communicate via a pipe or any other IPC method.
There are signals that are meant for use for user programs. From man signal:
The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
SIGSTOP will always stop the program and SIGKILL will always terminate the program.
There are two user-defined signals commonly used for signal communication between processes:
SIGUSR1 ... User-defined signal 1
SIGUSR2 ... User-defined signal 2
And there is also a whole range of real-time signals for use as user-defined signals between SIGRTMIN and SIGRTMAX, that have to be at least 8 signals (ie. SIGRTMAX - SIGRTMIN >= 8) and linux supports 33 signals. These are all for use for user-application to do anything it desires.
Basically each signal in Linux has a action associated with it.
Man page of signal:
Signal dispositions
Each signal has a current disposition, which determines how the
process behaves when it is delivered the signal.
The entries in the "Action" column of the table below specify the
default disposition for each signal, as follows:
Term Default action is to terminate the process.
Ign Default action is to ignore the signal.
Core Default action is to terminate the process and dump core (see
core(5)).
Stop Default action is to stop the process.
Cont Default action is to continue the process if it is currently
stopped.
SIGSTOP
SIGSTOP P1990 Stop Stop process
A process can change the disposition of a signal using sigaction(2)
or signal(2). (The latter is less portable when establishing a
signal handler; see signal(2) for details.) Using these system
calls, a process can elect one of the following behaviors to occur on
delivery of the signal: perform the default action; ignore the
signal; or catch the signal with a signal handler, a programmer-
defined function that is automatically invoked when the signal is
delivered.
You can define your own signal handler and define the behavior of your process.
Note: SIGKILL and SIGSTOP cannot be caught
1-Sending unix signals is only possible to a processes, or it is also possible to send signals to threads?
2-Is it possible to send the tid of a thread to a kernel module? How?
3-In what way the kernel module can find the tid of a thread, to send a signal?
4-the thread will have a handler that will run on each signal. If each handler corresponds to a signal, are there any race conditions?
Can communicate a signal to all threads? What happens if all access the handler at a time?
Ad.1 From where do you want to send a signal? You can use kill() to send signal to process and pthread_kill() to send it to thread (but only from process which created thread).
Ad.3. While handling one signal, other pending signals will be queued, so there will be no race conditions. But you need to set non local variables used in handler to atomic (so when interrupt comes setting this variable will not be interrupted) and check which functions are handler safe.
About signals and threads - signal usually comes directly to process (only with pthread_kill you can send signal to thread from user space). If you have multithreaded process and none of thread has this signal blocked, then signal will come to random thread (the one which is running exactly when signal comes). If you block all threads but one, then signal will come to only this one thread.
Can someone explain why we should not call non async functions from signal handlers ? Like the exact sequence of steps that corrupt the programs while calling with such functions.
And, does signals always run on separate stack ? if so is it a separate context or it runs on the context of the signaled thread ?
Finally, in case of a multi-threaded system what happens when signal handler is executed and some other thread is signaled and calls the same signal handler ?
(I am trying to develop deep understanding of signals and its applications)
When a process receives a signal, it is handled in the context of the process. You should only use aync-safe functions or re-entrant functions from inside a signal handler. For instance, you cannot call a malloc() or a printf() within a signal handler. The reason being:
*) Lets assume your process was executing in malloc when you received the signal. So the global heap data structures are in an inconsistent state. Now if you acquire the heap lock from inside your signal handler and make changes you will further render the heap inconsistent.
*) Another possibility is if the heap lock has been acquired by your process when it received the signal, and then you call malloc() from your signal handler, it sees that lock is held and it waits infinitely to acquire the lock (infinitely because the thread that can release the lock will not run till the signal is completely handled).
2) Signals run in the context of the process. As for the signal stack you can look at this SO answer -> Do signal handers have a separate stack?
3) As for getting multiple instances of the same signal you can look at this link -> Signal Handling in UNIX where Rumple Stiltskin answers it well.
I know some Solaris. So I'm using that for details. LWP==Solaris for "thread" as in pthreads.
trap signals like SIGILL, are delivered to the thread that caused the trap. Asynchronous signals are delivered to the first active thread (LWP), or process that is not blocking that signal. A kernel module called aslwp() traverses the process-header table (has associated LWP's) looking for the first likely candidate to receive the asynch signal.
A signal stack lives in the kernel. I'm not sure what/how to answer your signal stack question.
One process may have several pending signals. Is that what you mean?
Each signal destined for a process is held there until the process switches context (or is forced) into the active state. This in part because you generally cannot incur a trap when the process context has been swapped out and the process does nothing cpu-wise. You certainly can incur asynch signals. But the process cannot "do anything" with any signal if it cannot run. So, at this point the kernel swaps the context back to active, and the signal is delivered via aslwp().
Realtime signals behave differently, and I'm letting it stay with that.
Try reading this:
developers.sun.com/solaris/articles/signalprimer.html