I want to have a signal handler on the fatal signals that default to dumping core that will log the ocurrence and then the core will still be dumped (unless disabled with ulimit or core pattern).
I have tested (on Linux 4.15) that if the signal handler simply returns, this is what happens. However, I have not found any explicit statement in the documentation that would clearly state this.
So is it defined, in POSIX or Linux documentation, what shall happen when the signal handler returns, and where?
I did the first test by tweaking the code I needed to make work and it was more convoluted then I thought. When I tested with simple example program, the only way that works for all cases is to reset the handler and re-raise the signal as described in the accepted answer.
Core files have a definition in POSIX.1-2017 XBD (3.117 Core File):
A file of unspecified format that may be generated when a process terminates abnormally.
POSIX.1-2017 XSH (2.4.3 Signal Actions, under SIG_DFL) contains the following text (with any emphasized part from here on meaning that the corresponding text in the standard is XSI-shaded):
If the default action is to terminate the process abnormally, the process is terminated as if by a call to
_exit()
, except that the status made available towait()
,waitid()
, andwaitpid()
indicates abnormal termination by the signal. If the default action is to terminate the process abnormally with additional actions, implementation-defined abnormal termination actions, such as creation of a core file, may also occur.
In XBD (13. Headers, under <signal.h>) we see SIGABRT
, SIGBUS
, SIGFPE
, SIGILL
, SIGQUIT
, SIGSEGV
, SIGSYS
, SIGTRAP
, SIGXCPU
and SIGXFSZ
tagged as
A -- Abnormal termination of the process with additional actions.
So from a POSIX perspective you can't rely on a core file being generated, irrespective of signal dispositions.
However, every signal with a default action of "A" in POSIX is listed with a default disposition of "Core" in the Linux manual (signal(7)
). That may be what the following excerpt of the manual about SIGSYS
, SIGXCPU
and SIGXFSZ
refers to:
Linux 2.4 conforms to the POSIX.1-2001 requirements for these signals, terminating the process with a core dump.
As the POSIX excerpts above tell us, it's not a hard requirement in POSIX.1-2017.
Now that still doesn't answer the question if registering a signal-catching function nullifies the signal action of abnormal termination. I believe that if it does, it results in undefined behavior for at least a few signals, as per the following paragraph from XSH (2.4.3 Signal Actions, under Pointer to a Function):
The behavior of a process is undefined after it returns normally from a signal-catching function for a
SIGBUS
,SIGFPE
,SIGILL
, orSIGSEGV
signal that was not generated bykill()
,sigqueue()
, orraise()
.
So to avoid UB in all cases, I believe you have to reset the signal disposition to SIG_DFL
and then re-raise()
the signal from within the signal handler anyway. Also, any handlers catching those signals should probably run on an alternate signal stack but I'm not quite sure if that would make it generally safe to do so and if it is in the first place.