Signal Handling Output Display Issue - c

I am creating a relatively simple multiple process program to learn about signals and signal handling in Linux using C. I have several processes handling signals (I use sigaction to assign handlers) that are sent to all processes in the process group and one tracking process that displays some information after a certain number of signals are detected.
My question is this. How do I reliably display console output from the tracking process? This process needs to display the current number of signals detected and I know printf() isn't good to call from a signal handler. I know I can use write(), but I am not sure I can put variable values into this to display, and I think this system call can be interrupted by signals.
Could you give me a simple example with 3 processes (one generating the signal (parent), 1 handling the signal (child 1) and one reporting info on the signals (child 2)), or explain how this reporter process should handle the output with values of global shared variables?
Thanks

See How to avoid using printf() in a signal handler? for some information about what can be done in a signal handler.
I can't give you a 'simple' example for your 3 process request because the scenario you outline is incredibly complex — how on earth is the third process going to know about what signals the first process sent to the second process? Signals are very crude; there is very little information available other than 'a signal was sent' (slightly more if you use the sa_sigaction member of the struct sigaction and SA_SIGINFO flag when calling the sigaction() function). For most practical purposes, what you ask for can't be done.
If you're going to get close to your scenario, then maybe the method is to set up a shared memory segment in the parent which both children have access to. The second child (signal receiver) can then copy information into the shared memory when it receives a signal, while the third child copies the information out of shared memory and writes it. You'll need to look to see what coordinating functions (if any) are available to a signal handler function — the x-ref'd question has answers which cover this point (and the answer looks like 'none', or only crude ones like open() or mkdir()). Curiously, the POSIX standard does not list function such as strcpy() or memcpy() as signal-safe.
As to 'how to reliably display console output', what is your process going to do while waiting for signals to arrive? You can arrange for the signal handler to set a flag, and the looping code can arrange to check the flag, format and write the data (with standard I/O even; this isn't in a signal handler any more), before going back to waiting for the next signal to arrive.

Related

Signal handling - Async functions and multi threaded applications, Signal stack

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

Is there a way to identify how may signals delivered, pending to given process id?

Given a process id, I would like to find how may signals { including real time signals } are delivered, and handled. Is there any way to get from /proc file system?, If so, how to do that ?. Kindly guide.
Referring "pending signals":
One can use sigpending() to get a set of types of signals pending for a given process. This isn't the actual number of signals that had been sent to the process.
Referring "delivered signals":
One can set up a signal handler using sigaction() which in turn can count how often it is called. Anyhow the kernel or the run-time library (I'm not sure which) might decided to only call the handlers once for one or more signals of the same type having been sent close together in time.
An alternative way to collect signals is the use of sigwaitinfo(), probably in a dedicated thread.

How do unix signals work?

How do signals work in unix? I went through W.R. Stevens but was unable to understand. Please help me.
The explanation below is not exact, and several aspects of how this works differ between different systems (and maybe even the same OS on different hardware for some portions), but I think that it is generally good enough for you to satisfy your curiosity enough to use them. Most people start using signals in programming without even this level of understanding, but before I got comfortable using them I wanted to understand them.
signal delivery
The OS kernel has a data structure called a process control block for each process running which has data about that process. This can be looked up by the process id (PID) and included a table of signal actions and pending signals.
When a signal is sent to a process the OS kernel will look up that process's process control block and examines the signal action table to locate the action for the particular signal being sent. If the signal action value is SIG_IGN then the new signal is forgotten about by the kernel. If the signal action value is SIG_DFL then the kernel looks up the default signal handling action for that signal in another table and preforms that action. If the values are anything else then that is assumed to be a function address within the process that the signal is being sent to which should be called. The values for SIG_IGN and SIG_DFL are numbers cast to function pointers whose values are not valid addresses within a process's address space (such as 0 and 1, which are both in page 0, which is never mapped into a process).
If a signal handling function were registered by the process (the signal action value was neither SIG_IGN or SIG_DFL) then an entry in the pending signal table is made for that signal and that process is marked as ready to RUN (it may have been waiting on something, like data to become available for a call to read, waiting for a signal, or several other things).
Now the next time that the process is run the OS kernel will first add some data to the stack and changes the instruction pointer for that process so that it looks almost like the process itself has just called the signal handler. This is not entirely correct and actually deviates enough from what actually happens that I'll talk about it more in a little bit.
The signal handler function can do whatever it does (it is part of the process that it was called on behalf of, so it was written with knowledge about what that program should do with that signal). When the signal handler returns then the regular code for the process begins executing again. (again, not accurate, but more on that next)
Ok, the above should have given you a pretty good idea of how signals are delivered to a process. I think that this pretty good idea version is needed before you can grasp the full idea, which includes some more complicated stuff.
Very often the OS kernel needs to know when a signal handler returns. This is because signal handlers take an argument (which may require stack space), you can block the same signal from being delivered twice during the execution of the signal handler, and/or have system calls restarted after a signal is delivered. To accomplish this a little bit more than stack and instruction pointer changes.
What has to happen is that the kernel needs to make the process tell it that it has finished executing the signal handler function. This may be done by mapping a section of RAM into the process's address space which contains code to make this system call and making the return address for the signal handler function (the top value on the stack when this function started running) be the address of this code. I think that this is how it is done in Linux (at least newer versions). Another way to accomplish this (I don't know if this is done, but it could be) would be do make the return address for the signal handler function be an invalid address (such as NULL) which would cause an interrupt on most systems, which would give the OS kernel control again. It doesn't matter a whole lot how this happens, but the kernel has to get control again to fix up the stack and know that the signal handler has completed.
WHILE LOOKING INTO ANOTHER QUESTION I LEARNED
that the Linux kernel does map a page into the process for this, but that the actual system call for registering signal handlers (what sigaction calls ) takes a parameter sa_restore parameter, which is an address that should be used as the return address from the signal handler, and the kernel just makes sure that it is put there. The code at this address issues the I'm done system call (sigreturn)and the kernel knows that the signal handler has finished.
signal generation
I'm mostly assuming that you know how signals are generated in the first place. The OS can generate them on behalf of a process due to something happening, like a timer expiring, a child process dying, accessing memory that it should not be accessing, or issuing an instruction that it should not (either an instruction that does not exist or one that is privileged), or many other things. The timer case is functionally a little different from the others because it may occur when the process is not running, and so is more like the signals sent with the kill system call. For the non-timer related signals sent on behalf of the current process these are generated when an interrupt occurs because the current process is doing something wrong. This interrupt gives the kernel control (just like a system call) and the kernel generates the signal to be delivered to the current process.
Some issues that are not addressed in all of the above statements are multi core, running in kernel space while receiving a signal, sleeping in kernel space while receiving a signal, system call restarting and signal handler latency.
Here are a couple of issues to consider:
What if the kernel knows that a signal needs to be delivered to process X which is running on CPU_X, but the kernel learns about it while running on CPU_Y (CPU_X!=CPU_Y). So the kernel needs to stop the process from running on a different core.
What if the process is running in kernel space while receiving a signal? Every time a process makes a system call it enters kernel space and tinkers with data structures and memory allocations in kernel space. Does all of this hacking take place in kernel space too?
What if the process is sleeping in kernel space waiting for some other event? (read, write, signal, poll, mutex are just some options).
Answers:
If the process is running on another CPU the kernel, via cross CPU communication, will deliver an interrupt to the other CPU and a message for it. The other CPU will, in hardware, save state and jump to the kernel on the other CPU and then will do the delivery of the signal on the other CPU. This is all a part of trying not to execute the signal handler of the process on another CPU which will break cache locality.
If the process is running in kernel space it is not interrupted. Instead it is recorded that this process has received a signal. When the process exits kernel space (at the end of each system call), the kernel will setup the trampoline to execute the signal handler.
If the process, while running in kernel space, after having received a signal, reaches a sleep function, then that sleep function (and this is common to all sleep functions within the kernel) will check if the process has a signal pending. If it is so, it will not put the process to sleep and instead will cancel all that has been done while coming down into the kernel, and will exit to user space while setting up a trampoline to execute the signal handler and then restart the system call. You can actually control which signals you want to interrupt system calls and which you do not using the siginterrupt(2) system call. You can decide if you want system calls restartable for a certain signal when you register the signal using sigaction(2) with the SA_RESTART flag. If a system call is issued and is cut off by a signal and is not restarted automatically you will get an EINTR (interrupted) return value and you must handle that value. You can also look at the restart_syscall(2) system call for more details.
If the process is already sleeping/waiting in kernel space (actually all sleeping/waiting is always in kernel space) it is woken from the sleep, kernel code cleans up after itself and jump to signal handler on return to user space after which the system call is automatically restarted if the user so desired (very similar to previous explanation of what happens if the process is running in kernel space).
A few notes about why all of this is so complex:
You cannot just stop a process running in kernel space since the kernel developer allocates memory, does things to data structures and more. If you just take the control away you will corrupt the kernel state and cause a machine hang. The kernel code must be notified in a controlled way that it must stop its running, return to user space and allow user space to handle the signal. This is done via the return value of all (well, almost all) sleeping functions in the kernel. And kernel programmers are expected to treat those return values with respect and act accordingly.
Signals are asynchronous. This means that they should be delivered as soon as possible. Imagine a process that has only one thread, went to sleep for hour, and is delivered a signal. Sleep is inside the kernel. So you except the kernel code to wake up, clean up after itself, return to user space and execute the signal handler, possibly restarting the system call after the signal handler finished. You certainly do not expect that process to only execute the signal handler an hour later. Then you expect the sleep to resume. Great trouble is taken by the user space and kernel people to allow just that.
All in all signals are like interrupt handlers but for user space. This is a good analogy but not perfect. While interrupt handlers are generated by hardware some signal handlers originate from hardware but most are just software (signal about a child process dying, signal from another process using the kill(2) syscall and more).
So what is the latency of signal handling?
If when you get a signal some other process is running then it up to the kernel scheduler to decide if to let the other process finish its time slice and only then deliver the signal or not. If you are on a regular Linux/Unix system this means that you could be delayed by 1 or more time slices before you get the signal (which means milliseconds which are equivalent to eternity).
When you get a signal, if your process is high-priority or other processes already got their time slice you will get the signal quite fast. If you are running in user space you will get it "immediately", if you are running in kernel space you will shortly reach a sleep function or return from kernel in which case when you return to user space your signal handler will be called. That is usually a short time since not a lot of time is spent in the kernel.
If you are sleeping in the kernel, and nothing else is above your priority or needs to run, the kernel thread handling your system call is woken up, cleans up after all the stuff it did on the way down into the kernel, goes back to user space and executes your signal. This doesn't take too long (were talking microseconds here).
If you are running a real time version of Linux and your process has the highest real time priority then you will get the signal very soon after it is triggered. Were talking 50 microseconds or even better (depends on other factors that I cannot go into).
Think of the signal facility as interrupts, implemented by the OS (instead of in hardware).
As your program merrily traverses its locus of execution rooted in main(), these interrupts can occur, cause the program to be dispatched to a vector (handler), run the code there, and then return to the location where it got interrupted.
These interrupts (signals) can originate from a variety of sources e.g. hardware errors like accessing bad or misaligned addresses, death of a child process, user generated signals using the kill command, or from other processes using the kill system call. The way you consume signals is by designating handlers for them, which are dispatched by the OS when the signals occur. Note that some of these signals cannot be handled, and result in the process simply dying.
But those that can be handled, can be quite useful. You can use them for inter process communication i.e. one process sends a signal to another process, which handles it, and in the handler does something useful. Many daemons will do useful things like reread the configuration file if you send them the right signal.
Signal are nothing but an interrupt in the execution of the process. A process can signal itself or it can cause a signal to be passed to another process. Maybe a parent can send a signal to its child in order to terminate it, etc..
Check the following link to understand.
https://unix.stackexchange.com/questions/80044/how-signals-work-internally
http://www.linuxjournal.com/article/3985
http://www.linuxprogrammingblog.com/all-about-linux-signals?page=show

POSIX threads and signals

I've been trying to understand the intricacies of how POSIX threads and POSIX signals interact. In particular, I'm interested in:
What's the best way to control which thread a signal is delivered to (assuming it isn't fatal in the first place)?
What is the best way to tell another thread (that might actually be busy) that the signal has arrived? (I already know that it's a bad idea to be using pthread condition variables from a signal handler.)
How can I safely handle passing the information that a signal has occurred to other threads? Does this need to happen in the signal handler? (I do not in general want to kill the other threads; I need a far subtler approach.)
For reference about why I want this, I'm researching how to convert the TclX package to support threads, or to split it up and at least make some useful parts support threads. Signals are one of those parts that is of particular interest.
What's the best way to control which thread
a signal is delivered to?
As #zoli2k indicated, explicitly nominating a single thread to handle all signals you want handled (or a set of threads each with specific signal responsibilities), is a good technique.
What is the best way to tell another thread (that might actually be busy)
that the signal has arrived?[...]
How can I safely handle passing the information that a signal has occurred
to other threads? Does this need to happen in the signal handler?
I won't say "best," but here's my recommendation:
Block all desired signals in main, so that all threads are inherit that signal mask. Then, fashion the special signal receiving thread as a signal-driven event loop, dispatching newly arrived signals as some other intra-thread communication.
The simplest way to do this is to have the thread accept signals in a loop using sigwaitinfo or sigtimedwait. The thread then converts the signals somehow, perhaps broadcasting a pthread_cond_t, waking up other threads with more I/O, enqueuing a command in an application-specific thread-safe queue, whatever.
Alternatively, the special thread could allow signals to be delivered to a signal handler, unmasking for delivery only when ready to handle signals. (Signal delivery via handlers tends to be more error-prone than signal acceptance via the sigwait family, however.) In this case, the receiver's signal handler performs some simple and async-signal-safe action: setting sig_atomic_t flags, calling sigaddset(&signals_i_have_seen_recently, latest_sig), write() a byte to a non-blocking self-pipe, etc. Then, back in its masked main loop, the thread communicates receipt of the signal to other threads as above.
(UPDATED #caf rightly points out that sigwait approaches are superior.)
According to the POSIX standard all threads should appear with the same PID on the system and using pthread_sigmask() you can define the signal blocking mask for every thread.
Since it is allowed to define only one signal handler per PID, I prefer to handle all signals in one thread and send pthread_cancel() if a running thread need to be cancelled. It is the preferred way against pthread_kill() since it allows to define cleanup functions for the threads.
On some older systems, because of the lack of proper kernel support, the running threads may have different PID from the parent thread's PID. See FAQ for signal handling with linuxThreads on Linux 2.4.
Where I'm at so far:
Signals come in different major classes, some of which should typically just kill the process anyway (SIGILL) and some of which never need anything doing (SIGIO; easier to just do async IO right anyway). Those two classes need no action.
Some signals don't need to be dealt with immediately; the likes of SIGWINCH can be queued up until it is convenient (just like an event from X11).
The tricky ones are the ones where you want to respond to them by interrupting what you're doing but without going to the extent of wiping out a thread. In particular, SIGINT in interactive mode ought to leave things responsive.
I've still got to sort through signal vs sigaction, pselect, sigwait, sigaltstack, and a whole bunch of other bits and pieces of POSIX (and non-POSIX) API.
IMHO, Unix V signals and posix threads do not mix well.
Unix V is 1970. POSIX is 1980 ;)
There are cancellation Points and if you allow signals and pthreads in one application, you will eventually end up writing Loops around each call, which can surprisingly return EINTR.
So what I did in the (few) cases where I had to program multithreaded on Linux or QNX was, to mask out all signals for all (but one) threads.
When a Unix V Signal arrives, the process Switches the stack (that was as much concurrency in Unix V as you could get within a process).
As the other posts here hint, it might be possible now, to tell the System, which posix thread shall be the victim of that stack switching.
Once, you managed to get your Signal handler thread working, the question remains, how to transform the signal information to something civilized, other threads can use. An infrastructure for inter-thread communications is required. One pattern, useful is the actor pattern, where each of your threads is a target for some in-process Messaging mechanism.
So, instead of canceling other threads or killing them (or other weird stuff), you should try to marshall the Signal from the Signal context to your Signal handler thread, then use your actor pattern communications mechanisms to send semantically useful messages to those actors, who need the signal related Information.

How to synchronize multiple proccess in c through basic signal handling

people. For a academic exercise i have to implement a program in c for nix platform which is to synchronize multiple processes through signal handling, using only signal,pause,kill and fork basic functions.
I searched google and have not found any clear example: I hope the wisdom of one of you will light my way.
Thanks!
pause doesn't return until a signal is received. The basic design is thus:
fork to create the necessary workers
catch SIGINT in each worker. The handler sets a flag meaning the process should exit after finishing it's current job.
each process does work while it can, then pauses. Repeat unless SIGINT is received (test before & after pause).
when one process has work available for another process, it signals the other process with SIGCONT
when there is no more work for a process, signal it with SIGINT.
This doesn't quite include synchronized access to shared data. To do that, you could add an additional rule:
when a process signals another that work is available, it should pause
Of course, this rather defeats the purpose of concurrent programming.
Since most system calls are interrupted by signals (causing them to return -1, with errno set to EINTR), you'll have to handle this contingency, repeating each affected system call until it's successful. For example:
while ((readCount = read(...)) < 0 && errno == EINTR) {}
One important thing to be aware of is that Linux (at least, and possibly many other Unices) can collapse multiple signals of the same type into a single instance. So if you send a process one signal of value x, that process is guaranteed to receive it; but if you send 2 or more signals of value x, the process is only guaranteed to receive at least one of those signals.
Also, signals are not guaranteed to be received in the order they are sent.
(Why? Under the hood, Linux maintains a bitmask for each process recording which outstanding signals have been sent. Whenever a process is woken up by the scheduler, signal handlers for all outstanding signals are run, in some arbitrary order.)
What all this means is that signals are generally inappropriate for synchronising processes. They only work reliably when time intervals between signals are large with respect to the interval between wake-up times of the receiving process. And if a process spends a lot of time blocked, wake-up events can be arbitrarily far apart.
Conclusion: don't using signals for IPC.

Resources