I want to know when does a linux process handles the signal.
Assuming that the process has installed the signal handler for a signal, I wanted to know when would the process's normal execution flow be interrupted and signal handler called.
According to http://www.tldp.org/LDP/tlk/ipc/ipc.html, the process would handle the signal when it exits from a system call. This would mean that a normal instruction like a = b+c (or its equivalent machine code) would not be interrupted because of signal.
Also, there are system calls which would get interrupted (and fail with EINTR or get restarted) upon receiving a signal. This means that signal is processed even before the system call completes. This behaviour seems to b conflicting with what I have mentioned in the previous paragraph.
So, I am not clear as to when is the signal processed and in which process states would it be handled by the process. Can it be interrupted
Anytime it enters from kernel space to user space, or
Anytime it is in user space, or
Anytime the process is scheduled for execution by the scheduler
Thanks!
According to http://www.tldp.org/LDP/tlk/ipc/ipc.html, the process would handle the signal when it exits from a system call. This would mean that a normal instruction like a = b+c (or its equivalent machine code) would not be interrupted because of signal.
Well, if that were the case, a CPU-intensive process would not obey the process scheduler. The scheduler, in fact, can interrupt a process at any point of time when its time quantum has elapsed. Unless it is a FIFO real-time process.
A more correct definition: One point when a signal is delivered to the process is when the control flow leaves the kernel mode to resume executing user-mode code. That doesn't necessarily involve a system call.
A lot of the semantics of signal handling are documented (for Linux, anyway - other OSes probably have similar, but not necessarily in the same spot) in the section 7 signal manual page, which, if installed on your system, can be accessed like this:
man 7 signal
If manual pages are not installed, online copies are pretty easy to find.
Related
I'm a beginner in Linux and Process signal handling.
Let's say we have a process A and it execute pause() function, we know that puts the current process to sleep until a signal is received by the process.
But when we type ctrl-c, kernel also sends a SIGINT to process A and when A receives the signal, it execute the SIGINT's default handler which is terminating the current process. So my question is:
Does the process A resume first or handler get executed first?
For simplicity, let's assume process A has only a single thread, which is blocking in a pause() call, and exactly one signal gets sent to the process.
Does the process A resume first or handler get executed first?
The signal handler gets executed first, then the pause() call returns.
What if there are multiple signals?
Standard signals are not queued, so if you send say two INT signals to the process very quickly in succession, only one of them is delivered.
If there are multiple signals, the order is unspecified.
What about POSIX realtime signals? (SIGRTMIN+0 to SIGRTMAX-0)
They are just like standard named signals, except they are queued (to a limit), and if more than one of them is pending, they get delivered in increasing numerical order.
If there are both standard and realtime signals pending, it is unspecified which ones get delivered first; although in practice, in Linux and many other systems, the standard signals get delivered first, then the realtime ones.
What if there are multiple threads in the process?
The kernel will pick one thread among those that do not have the signal masked (via sigprocmask() or pthread_sigmask()), and use that thread to deliver the signal to the signal handler.
If there are more than one thread blocking in a pause() call, one of them gets woken up. If there are more than one pending signal, it is unspecified whether the one woken thread handles them all, or if more than one thread is woken up.
In general, I warmly recommend reading the man 7 signal, man 7 signal-safety, man 2 sigaction, man 2 sigqueue, and man 2 sigwaitinfo man pages. (While the links go to the Linux man pages project, each of the pages includes a Conforming To section naming the related standards, and Linux-specific behaviour is clearly marked.)
Reading about interrupts in linux, I understand that their handlers will run till completion (lets not consider the bottom halves here). So, assume that my code has SIGINT handler registered (using the signal()/sigaction() call) with a while(1)-loop in it (i.e the handler never returns).
If I quit my program abruptly while running, then shouldn't this scenario freeze my machine entirely? Won't my machine with only one CPU core go into an infinite loop?
What I mean is; since my interrupt handler is not returning, won't the CPU be stuck in executing the while(1) code only? (i.e no other process will get the chance of running, because there won't be any context-switch/preemption inside the handler or can the interrupt handler get preempted in between running the while(1) loop?)
You definitely mix signal handlers and interrupt handlers, despite they have similar handling. Unlike you are writing kernel code you won't meet interrupt handlers directly.
But, game rules for signal handlers are very similar. You should either exit from a signal handler or finish the program (and, the latter is analog for stopping the whole system, for the kernel land). This includes exotic ways for exiting signal handlers as longjmp().
From kernel POV, a process in forever loop in an interrupt handler doesn't differ from a process with the same loop in a usual code piece like main(). Entering a signal handler modifies signal mask but doesn't change things radically. Such process can be stopped, traced, killed in the same manner as outside of signal.
(All this doesn't concern some special process classes with advanced credentials. E.g. X Window server can be special because it disables some kernel activity during its video adapter handling. But you likely should know the needed safety rules when writing such software.)
I am not new to the use of signals in programming. I mostly work in C/C++ and Python.
But I am interested in knowing how signals are actually implemented in Linux (or Windows).
Does the OS check after each CPU instruction in a signal descriptor table if there are any registered signals left to process? Or is the process manager/scheduler responsible for this?
As signal are asynchronous, is it true that a CPU instruction interrupts before it complete?
The OS definitely does not process each and every instruction. No way. Too slow.
When the CPU encounters a problem (like division by 0, access to a restricted resource or a memory location that's not backed up by physical memory), it generates a special kind of interrupt, called an exception (not to be confused with C++/Java/etc high level language exception abstract).
The OS handles these exceptions. If it's so desired and if it's possible, it can reflect an exception back into the process from which it originated. The so-called Structured Exception Handling (SEH) in Windows is this kind of reflection. C signals should be implemented using the same mechanism.
On the systems I'm familiar with (although I can't see why it should be much different elsewhere), signal delivery is done when the process returns from the kernel to user mode.
Let's consider the one cpu case first. There are three sources of signals:
the process sends a signal to itself
another process sends the signal
an interrupt handler (network, disk, usb, etc) causes a signal to be sent
In all those cases the target process is not running in userland, but in kernel mode. Either through a system call, or through a context switch (since the other process couldn't send a signal unless our target process isn't running), or through an interrupt handler. So signal delivery is a simple matter of checking if there are any signals to be delivered just before returning to userland from kernel mode.
In the multi cpu case if the target process is running on another cpu it's just a matter of sending an interrupt to the cpu it's running on. The interrupt does nothing other than force the other cpu to go into kernel mode and back so that signal processing can be done on the way back.
A process can send signal to another process. process can register its own signal handler to handle the signal. SIGKILL and SIGSTOP are two signals which can not be captured.
When process executes signal handler, it blocks the same signal, That means, when signal handler is in execution, if another same signal arrives, it will not invoke the signal handler [ called blocking the signal], but it makes the note that the signal has arrived [ ie: pending signal]. once the already running signal handler is executed, then the pending signal is handled. If you do not want to run the pending signal, then you can IGNORE the signal.
The problem in the above concept is:
Assume the following:
process A has registered signal handler for SIGUSR1.
1) process A gets signal SIGUSR1, and executes signalhandler()
2) process A gets SIGUSR1,
3) process A gets SIGUSR1,
4) process A gets SIGUSR1,
When step (2) occurs, is it made as 'pending signal'. Ie; it needs to be served.
And when the step (3) occors, it is just ignored as, there is only one bit
available to indicate the pending signal for each available signals.
To avoid such problem, ie: if we dont want to loose the signals, then we can use
real time signals.
2) Signals are executed synchronously,
Eg.,
1) process is executing in the middle of signal handler for SIGUSR1,
2) Now, it gets another signal SIGUSR2,
3) It stops the SIGUSR1, and continues with SIGUSR2,
and once it is done with SIGUSR2, then it continues with SIGUSR1.
3) IMHO, what i remember about checking if there are any signal has arrived to the process is:
1) When context switch happens.
Hope this helps to some extend.
I have two questions:
1) Kernel-space process: When a process is executing in kernel mode, it does not receive any signals.
Instead a process puts itself in a wait-queue when it expects to receive completion of any event. Such as completion of an I/O event. The process does not do anything at this stage. Once the event is triggered, (the kernel sets a trap ? Correct if wrong) and finally the process is waked up and resumes execution.
Above is the case for expected events or (synchronous).
But i wish to understand, how the process executing in kernel mode comes to know the occurrence of asynchronous events?
2) User-space process: Does the kernel always sets a trap to intimate a process executing in user-space to intimate that the signal has received? (Once the pending-signals-mask is set?)
Please answer this question with respect to the implementation in Linux (or it's flavors).
Please correct me if i am wrong. Here is my understanding about signals:
As far as i know, signal generation
and signal delivery are 2 different
things. In order to generate a signal,
the OS simply sets a bit in a bitarray
maintained in the Process Control
Block(PCB) of the process. Each bit
corresponds to a particular signal,
and when a bit is set, it means the
signal corresponding to the bit is
pending.
Delivery: Before transferring control
back to a process in user mode, the
Kernel always checks the pending
signals for this process. This check
must happen in Kernel space because
some signals can never be ignored by a
process – namely SIGSTOP and SIGKILL.
So does this mean that signals can only be delivered to a process when the kernel is scheduling that process i.e allocating it CPU ? Can a process get a signal when it is actually executing on the CPU ? If so, how is it possible i.e how the process comes to know that a signal is pending for it (since it is executing in User mode and cannot access the PCB)
Say there is multi processor machine and so there is real parallelism i.e multiple processes are executing at the same time. Process P1 is executing on cpu 1 and process P2 is executing on cpu2 and now process P2(having sufficient privileges) sends a signal to process P1. Will this signal be delivered to P1 right now or will it be delivered after P1 relinquishes the CPU for some reason and is again rescheduled at some later time by the Kernel and then this signal is delivered to process P1.
Please don't say this question is implementation dependent. If you find that the right answer is implementation defined then i am looking for answers in Linux, FreeBSD or any *nix platform for which you have knowledge of.
Thanks a lot for your help and patience :)
Regards
lali
The answer is implementation dependent :). On Mac OS X (and FreeBSD), signals are handled asynchronously - the kernel finds a thread which is not blocking the signal, and sets an Asynchronous System Trap flag on that thread. The next time the kernel schedules that thread, it handles the trap (quitting the process, ignoring the trap, or invoking the signal-handler in user space as appropriate) rather than arranging the usual continuation of the thread in user-space.
On Solaris, the implementation is somewhat similar, although it also offers synchronous signals based on hardware traps - synchronous signals are delivered to the thread that raised the trap, while asynchronous signals work in the way described above.
Linux does something similar to Solaris (I'm not sure how the conclusion in that reference follows from the discussion, but it's the discussion that is useful).
Posix.4 also defines real-time signals, but I haven't worked with those.
The short answer is - yes, process get knowledge of a signal only on the next scheduled CPU timeslice.
How to know the process has received a signal - it may call sigprocmask(2).
Process P1 is executing on cpu 1 and process P2 is executing on cpu2 and now process P2(having sufficient privileges) sends a signal to process P1. Will this signal be delivered to P1 right now or will it be delivered after P1 relinquishes the CPU for some reason and is again rescheduled at some later time by the Kernel and then this signal is delivered to process P1.
As far as i know on last linux kernels execution of P1 may be paused when P2 emit signal and signal will be delivered immediately. May be this true only for real-time signals
If I remember correctly, the interrupt arrival bit is checked during the last T state of an 8085 instruction. So there has to be a way to either generate a real interrupt on signal arrival, or there has to be a (constant?)code slice before the signal bit is checked.
Unfortunately, it appears that the only way to answer some kernel behaviour related questions is to go through the source code, because they are so "implementation dependent". Programming the computer really is nothing short of harassment - what a profession to choose!
Just try to be perfect, and hope this website helps.