I know that SIGSEGV
can't be ignored when the kernel uses it to report a memory access violation. But if I install a signal handler for SIGSEGV
that does nothing, and then another process uses kill
to send me that signal, will this behave the same as if I had used a "normal" signal (like SIGUSR1
) instead?
-
See [this](http://stackoverflow.com/a/16204696/841108), and [this](http://stackoverflow.com/questions/21204209/why-cant-capture-sigsegv-using-signalfd/21204438) and [this](http://stackoverflow.com/questions/20304720/catching-signals-such-as-sigsegv-and-sigfpe-in-multithreaded-program/20310127#20310127) – Basile Starynkevitch Jan 26 '14 at 08:20
3 Answers
Grijesh Chauhan's answer is technically correct but difficult to understand, so I am going to write out my own exposition of basically the same points. With footnotes.0
Dima asks what happens when one thread installs a do-nothing handler for SIGSEGV
and then another thread uses kill
1 to generate SIGSEGV
on that thread. The one-sentence answer is that the handler runs, does nothing, and then control returns to normal flow within the interrupted thread. Unlike when the kernel generates SIGSEGV
as a response to an actual memory access violation, this scenario does not trigger undefined behavior2. However, the intended purpose of SIGSEGV
and its friends (SIGBUS
, SIGFPE
, and SIGILL
) is for the kernel to tell your program that it has done something so heinous that there must be a bug, normal execution cannot continue, would you like to clean up a little before you get killed? It is therefore unwise to use them for anything else. There are several signals (SIGUSR1
, SIGUSR2
, and SIGRTMIN
through SIGRTMAX
) reserved for each application to use however it likes; you should use one of those instead.
For the longer answer, I am going to crib from the POSIX standard,3 subsection Signal Actions. First, the four signals SIGFPE
, SIGILL
, SIGSEGV
, and SIGBUS
, like any other signal, can be delivered "asynchronously"—at no particular time—because some piece of code used a system call (such as kill
) to generate them. When this happens, they are treated exactly the same as any other signal whose default "action" happens to be "terminate the program abnormally"; note that many other signals have this property, including those reserved for application use. If your program only ever has to worry about receiving SIGFPE
, SIGILL
, SIGSEGV
, and SIGBUS
when they are generated by kill
and friends, it can do all of the normal things with them: block them, ignore them, establish signal handlers that do anything that is valid for an asynchronous signal handler,4 receive them via sigwait
or signalfd
rather than the normal asynchronous system trap-like delivery mechanism.
However. SIGFPE
, SIGILL
, SIGSEGV
, and SIGBUS
are also generated "synchronously" by the kernel in response to different kinds of erroneous program behavior that trigger hardware exceptions, such as attempting to access unmapped memory. Synchronously means that the signal is delivered immediately upon execution of the offending CPU instruction, and on that same thread rather than any thread in the process that happens to have it unblocked. And we're really not kidding about the "immediately" part: if there's a signal handler, when it executes, the saved program counter will be pointing at the exact instruction that caused whatever sort of hardware exceptions it was. The kernel can't allow execution to proceed through an instruction that causes the CPU to issue a hardware exception, so POSIX says this about attempting to discard these signals rather than terminate the process or take some drastic recovery action:
The behavior of a process is undefined after it ignores a
SIGFPE
,SIGILL
,SIGSEGV
, orSIGBUS
signal that was not generated bykill()
,sigqueue()
, orraise()
.
("After it ignores" in context means "if the kernel tries to generate one of these signals synchronously when the action is set to SIG_IGN
.)
The behavior of a process is undefined after it returns normally from a signal-catching function for a SIGBUS, SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(), sigqueue(), or raise().
("Returns normally" means "not by calling (sig)longjmp
". It is valid, at least as far as the kernel is concerned, to unwind the stack and resume execution somewhere else; you may be in for trouble if you haven't sufficiently fixed up the damaged data structure that caused the fault in the first place, though. It's also valid, as Basile mentioned, to mess with the saved processor state so that returning "normally" doesn't just try to run the same bad instruction again; but doing that tends to involve manually interpreting machine instructions and other such black magic.)
If any of the SIGFPE, SIGILL, SIGSEGV, or SIGBUS signals are generated while they are blocked, the result is undefined, unless the signal was generated by the action of another process, or by one of the functions kill(), pthread_kill(), raise(), or sigqueue().
(I'm not sure why this wording is a little different from the other two; probably just because the person who wrote the specific documentation for sigprocmask
didn't coordinate with the person who wrote the general documentation for signal actions.)
0 Dima tagged their question "Linux", but I am going to put in this caveat anyway, for the benefit of future readers: Everything I write here should be assumed to apply only to POSIX-conformant operating systems; to first order, that means "all OSes you are likely to encounter, except Windows." The exception is important. Windows has a rather different notion of the relationship between threads and processes than POSIX does, and a completely different (superior!) fundamental mechanism for reporting CPU-generated erroneous-program exceptions. Signals on Windows are emulated by the C library and probably do not behave as I describe.
1 presumably actually pthread_kill
.
2 please read this entire series of blog posts
3 specifically, the online copy of The Open Group Base Specifications Issue 7, 2013 edition, which is also "simultaneously" the 2013 edition of IEEE Standard 1003.1, POSIX.
4 not a lot, but more than nothing; there's a list in the "Signal Actions" document, but no fragment ID allowing me to point you right at it.

- 135,547
- 38
- 252
- 361
I have function that receive signal
SIGSEGV
but do nothing with it, does it mean that signal is ignored ?
Yes, you caught the signal SIGSEGV and do nothing in handler, control returns.
In general ignoring real SIGSEGV doesn't mean the error won't enable the program to continue executing meaningfully. Note SIGSEGV is not a signal that sent via user requests (some key-combination), SIGSEGV raises when a program tries to read or write outside the memory that is allocated for it. The name is an abbreviation for "segmentation violation".
SIG35-C. Do not return from a computational exception signal handler
According to the C Standard, subclause 7.14.1.1 ISO/IEC 9899:2011, if a signal handler entered as a result of a computational exception (that is, with the value of its argument of SIGFPE , SIGILL, or SIGSEGV or any other implementation-defined value corresponding to such an exception) returns, the behavior is undefined.
The behavior of a process is undefined after it ignores a
SIGFPE
,SIGILL
,SIGSEGV
, orSIGBUS
signal that was not generated bykill()
,sigqueue()
, orraise()
.
Second
Does signal pass to default implementation?
No, according to standard quote behavior or your code is not undefined as you generates signal by kill()
. Default implementation will immediately kill your process execution and generate code dump (Ref: Standard Signals).
Your code has well-defined behavior - the signal will be received, the handler will run, it will do nothing, control will return to normal flow - but you should still change it to use some other signal.
SIGUSR1
andSIGUSR2
are intended to be used the way you are usingSIGSEGV
right now, as internal application messages-to-self.
The GNU C Library is a good resource to learn Signal Handling.

- 1
- 1

- 57,103
- 20
- 141
- 208
-
-
@tristan May be I am not sure, I think I should write `core-dump with termination` ?? – Grijesh Chauhan Jan 26 '14 at 08:36
-
@GrijeshChauhan OK. my impression is that term might mean termination without core (like the SIGKILL action) – tristan Jan 26 '14 at 08:39
-
@tristan you are write but I didn't read that SIGSEGV will give Core-dump. Core-dumps are generated on SIGINT and SIGQUIT but I am not very sure too.. btw I refers this http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC337 – Grijesh Chauhan Jan 26 '14 at 08:46
-
My question is when thread call kill on another thread what steps is take from this moments ? – Dima Jan 26 '14 at 08:48
-
@Dima When thread send to other thread this signal then process will be killed(all threads will be killed) as default action. But It you ignores the Signal as you are doing then behavior is Undefined as I added in my answer.. – Grijesh Chauhan Jan 26 '14 at 08:50
-
@Dima Read Maxim Yegorushkin [this answer](http://stackoverflow.com/a/6981734/1673391) He also added a reference. – Grijesh Chauhan Jan 26 '14 at 08:57
-
Grijesh: The "that was not generated by ..." clause in your quote from the C standard is very important. The OP's code is *not* provoking undefined behavior. When generated by `kill(2)`, `SIGSEGV` is no different than any other signal. – zwol Jan 26 '14 at 15:21
-
2@Dima: Your code has well-defined behavior - the signal will be received, the handler will run, it will do nothing, control will return to normal flow - but you should still change it to use some other signal. `SIGUSR1` and `SIGUSR2` are intended to be used the way you are using `SIGSEGV` right now, as internal application messages-to-self. – zwol Jan 26 '14 at 15:24
-
@Zack You means "if a signal handler entered as a result of a computational exception" line ?? – Grijesh Chauhan Jan 26 '14 at 15:27
-
1@GrijeshChauhan Your second quote block, beginning SIG35-C: "The behavior of a process is undefined after it ignores a `SIGFPE`, `SIGILL`, `SIGSEGV`, or `SIGBUS` signal **that was not generated by `kill()`, `sigqueue()`, or `raise()`**". (Emphasis mine.) – zwol Jan 26 '14 at 15:27
-
@Zack Oh!! correct... It means OP code doesn't calls undefined behaviour.. your are correct. I should correct my answer too. Thanks! – Grijesh Chauhan Jan 26 '14 at 15:29
-
1@GrijeshChauhan You should know that the CERT secure coding guidelines were written by people with a taste for absolute pronouncements. "Don't return from a handler for `SIGFPE`, `SIGILL`, `SIGSEGV`, or `SIGBUS`" is good advice for the vast majority of cases, where someone *isn't* doing clever things e.g. with `raise`, and they felt that adding caveats would distract people. Unfortunately, nearly all nontrivial C programs wind up doing *something* clever, and so the CERT guidelines wind up being less than helpful. – zwol Jan 26 '14 at 15:32
-
@Zack Thanks Can you share any link. I don't know this "Don't return from a handler for SIGFPE, SIGILL, SIGSEGV, or SIGBUS". Thanks very much for correcting me I learn something to which I was unaware. – Grijesh Chauhan Jan 26 '14 at 15:36
-
1@GrijeshChauhan I was talking about the CERT coding guidelines that YOU linked to! – zwol Jan 26 '14 at 16:59
I have function that receive signal SIGSEGV but do nothing with it, does it mean that signal is ignored?
Technically it's not ignored. You defined the signal handler and it does handle the signal though the function doesn't do anything. Note that as far as signal is concerned, IGNORE means the kernel doesn't handle the signal, that is, it doesn't take any action.
Each signal has a default action. It's coredump(terminate with core) for SEGV and terminate for SEGKILL, etc...
User can change the default action with signal() or sigaction() API and the action can be set up to one of:
- perform the default action
- ignore the signal
- catch the signal with a signal handler
So in your case, it's the third one. I'd say ignoring signal if you used the second action.
Does signal pass to default implementation ?
No.
read http://man7.org/linux/man-pages/man7/signal.7.html for more.

- 4,235
- 2
- 21
- 45