* abort() PID 1 @ 2016-07-04 8:09 Jorge Almeida 2016-07-04 8:28 ` Igmar Palsenberg 2016-07-04 9:31 ` Szabolcs Nagy 0 siblings, 2 replies; 7+ messages in thread From: Jorge Almeida @ 2016-07-04 8:09 UTC (permalink / raw) To: musl The recent thread about abort() and PID 1 left me in a state of confusion, in a matter I thought was clear enough: What I thought I understood: - the kernel will not deliver any signal to process 1, unless a signal handler for that particular signal has been installed -if process 1 calls abort() (regardless of what purpose that would fill), then: - if a handler was setup, it should be done whatever the handler does - if a handler was not setup, nothing should happen (as in: process didn't receive any signal at all) What the standards say: (http://pubs.opengroup.org/onlinepubs/9699919799/) "The SIGABRT signal shall be sent to the calling process as if by means of raise() with the argument SIGABRT." "The effect of the raise() function shall be equivalent to calling: pthread_kill(pthread_self(), sig);" man raise(3): The raise() function sends a signal to the caling process or thread. In a single-threaded program it is equivalent to kill(getpid(), sig); So, what should " kill(1, SIGABRT)" do? It doesn't seem ambiguous to me. IOW, there's nothing special about SIGABRT regarding PID 1. DISCLAIMER: well-meaning amateur here. I'm pretty sure I understood what I quoted, but I'm assuming the standard doesn't have any self-inconsistencies. I'm also assuming the site is authoritative. So, can one trust the man pages? Thanks Jorge Almeida ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: abort() PID 1 2016-07-04 8:09 abort() PID 1 Jorge Almeida @ 2016-07-04 8:28 ` Igmar Palsenberg 2016-07-04 9:37 ` Jorge Almeida 2016-07-04 9:31 ` Szabolcs Nagy 1 sibling, 1 reply; 7+ messages in thread From: Igmar Palsenberg @ 2016-07-04 8:28 UTC (permalink / raw) To: musl > The recent thread about abort() and PID 1 left me in a state of > confusion, in a matter I thought was clear enough: > > What I thought I understood: > > - the kernel will not deliver any signal to process 1, unless a signal > handler for that particular signal has been installed > > -if process 1 calls abort() (regardless of what purpose that would fill), then: > > - if a handler was setup, it should be done whatever the handler does > > - if a handler was not setup, nothing should happen (as in: > process didn't receive any signal at all) Pid 1 can ignore sigkill / sigstop. "Normal" processes can't. "Normal" processes have defaults handling signals, pid 1 ignores all by default, unless it instructs the kernel it wants to receive it. > > What the standards say: > > (http://pubs.opengroup.org/onlinepubs/9699919799/) > > "The SIGABRT signal shall be sent to the calling process as if by > means of raise() with the argument SIGABRT." > > "The effect of the raise() function shall be equivalent to calling: > > pthread_kill(pthread_self(), sig);" > > man raise(3): > The raise() function sends a signal to the caling process or > thread. In a single-threaded program it is equivalent to > kill(getpid(), sig); > > So, what should " kill(1, SIGABRT)" do? It doesn't seem ambiguous to > me. IOW, there's nothing special about SIGABRT regarding PID 1. The "problem" in this case is that the "normal" abort() sends a SIGABRT, if that doesn't work, unblocks signals and retries. While that works with "normal" processes, it doesn't work with pid 1, because the default action on that process for SIGABRT isn't terminate. Hence the infinite loop you see. IMHO, we should leave this as it is, unless the abort() call fails to successfully terminate the process on non-pid 1 processes. That is a bug, failing to terminate pid 1 isn't. Igmar ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: abort() PID 1 2016-07-04 8:28 ` Igmar Palsenberg @ 2016-07-04 9:37 ` Jorge Almeida 0 siblings, 0 replies; 7+ messages in thread From: Jorge Almeida @ 2016-07-04 9:37 UTC (permalink / raw) To: musl On Mon, Jul 4, 2016 at 1:28 AM, Igmar Palsenberg <igmar@palsenberg.com> wrote: > > >> >> -if process 1 calls abort() (regardless of what purpose that would fill), then: >> >> - if a handler was setup, it should be done whatever the handler does >> >> - if a handler was not setup, nothing should happen (as in: >> process didn't receive any signal at all) > > Pid 1 can ignore sigkill / sigstop. "Normal" processes can't. "Normal" > processes have defaults handling signals, pid 1 ignores all by default, > unless it instructs the kernel it wants to receive it. > Yes, just what I said. >> >> What the standards say: >> >> (http://pubs.opengroup.org/onlinepubs/9699919799/) >> >> "The SIGABRT signal shall be sent to the calling process as if by >> means of raise() with the argument SIGABRT." >> >> "The effect of the raise() function shall be equivalent to calling: >> >> pthread_kill(pthread_self(), sig);" >> >> man raise(3): >> The raise() function sends a signal to the caling process or >> thread. In a single-threaded program it is equivalent to >> kill(getpid(), sig); >> >> So, what should " kill(1, SIGABRT)" do? It doesn't seem ambiguous to >> me. IOW, there's nothing special about SIGABRT regarding PID 1. > > The "problem" in this case is that the "normal" abort() sends a SIGABRT, > if that doesn't work, unblocks signals and retries. > While that works with "normal" processes, it doesn't work with pid 1, > because the default action on that process for SIGABRT isn't terminate. As I see it: the process that issues abort() is really saying to the kernel: "pretty please, send SIGABRT to this process--hey, that would be me!" and the kernel replies "nope, you're process 1, I won't send you anything" or else "sure, you have a signal handler, knock yourself out". If the handler has something like _exit, this will cause a kernel panic. Whoever writes the code may have a use for a panic on demand, who knows? If the handler doesn't return, that's it, abort() has done its job, per the man page. If the handler returns, abort() must "restore the default disposition for SIGABRT and then raise the signal a 2nd time" --restoring the default disposition means removing the handler, and so the 2nd time the kernel won't send a signal, and end of story. I just can't see why there should be any remaining issue. Why shoul there be any loop at all? Thanks, Jorge ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: abort() PID 1 2016-07-04 8:09 abort() PID 1 Jorge Almeida 2016-07-04 8:28 ` Igmar Palsenberg @ 2016-07-04 9:31 ` Szabolcs Nagy 2016-07-04 9:49 ` Jorge Almeida 2016-07-04 13:30 ` Igmar Palsenberg 1 sibling, 2 replies; 7+ messages in thread From: Szabolcs Nagy @ 2016-07-04 9:31 UTC (permalink / raw) To: musl; +Cc: Jorge Almeida * Jorge Almeida <jjalmeida@gmail.com> [2016-07-04 01:09:32 -0700]: > What I thought I understood: > > - the kernel will not deliver any signal to process 1, unless a signal > handler for that particular signal has been installed > not all signals behave that way. > -if process 1 calls abort() (regardless of what purpose that would fill), then: > > - if a handler was setup, it should be done whatever the handler does > > - if a handler was not setup, nothing should happen (as in: > process didn't receive any signal at all) > this is raise(SIGABRT), abort is different. > > What the standards say: > > (http://pubs.opengroup.org/onlinepubs/9699919799/) > > "The SIGABRT signal shall be sent to the calling process as if by > means of raise() with the argument SIGABRT." > it also says "The abort() function shall cause abnormal process termination to occur, unless the signal SIGABRT is being caught and the signal handler does not return." and "The abort() function shall not return." (in c11 abort is _Noreturn and returning from such a function is undefined behaviour). > DISCLAIMER: well-meaning amateur here. I'm pretty sure I understood > what I quoted, but I'm assuming the standard doesn't have any > self-inconsistencies. there is no inconsistency. abort should raise(SIGABRT) and it should terminate the process. (normally there should be an abort syscall provided by the kernel, but linux does not have it.) > So, can one trust the man pages? not always, use the standard for standard interfaces. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: abort() PID 1 2016-07-04 9:31 ` Szabolcs Nagy @ 2016-07-04 9:49 ` Jorge Almeida 2016-07-04 13:30 ` Igmar Palsenberg 1 sibling, 0 replies; 7+ messages in thread From: Jorge Almeida @ 2016-07-04 9:49 UTC (permalink / raw) To: musl, Jorge Almeida On Mon, Jul 4, 2016 at 2:31 AM, Szabolcs Nagy <nsz@port70.net> wrote: > * Jorge Almeida <jjalmeida@gmail.com> [2016-07-04 01:09:32 -0700]: >> What I thought I understood: >> >> - the kernel will not deliver any signal to process 1, unless a signal >> handler for that particular signal has been installed >> > > not all signals behave that way. Would you elaborate on that? (links?) > > this is raise(SIGABRT), abort is different. Quotes in my first message say it's the same: >> >> (http://pubs.opengroup.org/onlinepubs/9699919799/) >> >> "The SIGABRT signal shall be sent to the calling process as if by >> means of raise() with the argument SIGABRT." >> > > it also says > > "The abort() function shall cause abnormal process termination > to occur, unless the signal SIGABRT is being caught and the > signal handler does not return." > > and > > "The abort() function shall not return." > This is where I see an inconsistency... > > there is no inconsistency. > > abort should raise(SIGABRT) and it should terminate the process. > > (normally there should be an abort syscall provided by the kernel, > but linux does not have it.) > >> So, can one trust the man pages? > > not always, use the standard for standard interfaces. Too bad... Thanks Jorge ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: abort() PID 1 2016-07-04 9:31 ` Szabolcs Nagy 2016-07-04 9:49 ` Jorge Almeida @ 2016-07-04 13:30 ` Igmar Palsenberg 2016-07-05 3:14 ` Rich Felker 1 sibling, 1 reply; 7+ messages in thread From: Igmar Palsenberg @ 2016-07-04 13:30 UTC (permalink / raw) To: musl; +Cc: Jorge Almeida > > - the kernel will not deliver any signal to process 1, unless a signal > > handler for that particular signal has been installed > > > > not all signals behave that way. For pid 1 this is the case. Unless some signals are exempt from this. > > -if process 1 calls abort() (regardless of what purpose that would fill), then: > > > > - if a handler was setup, it should be done whatever the handler does > > > > - if a handler was not setup, nothing should happen (as in: > > process didn't receive any signal at all) > > > > this is raise(SIGABRT), abort is different. Different how ? The manual says it's just a signal unblock followed by a kill(self, SIGABRT). > > > > > What the standards say: > > > > (http://pubs.opengroup.org/onlinepubs/9699919799/) > > > > "The SIGABRT signal shall be sent to the calling process as if by > > means of raise() with the argument SIGABRT." > > > > it also says > > "The abort() function shall cause abnormal process termination > to occur, unless the signal SIGABRT is being caught and the > signal handler does not return." > > and > > "The abort() function shall not return." > > (in c11 abort is _Noreturn and returning from such a function > is undefined behaviour). Hmm.. What happens if a hander is installed, but that never returns ? (but also doesn't terminate the process). If I read the manpage correct, it says it's OK, but also says it isn't. Igmar ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: abort() PID 1 2016-07-04 13:30 ` Igmar Palsenberg @ 2016-07-05 3:14 ` Rich Felker 0 siblings, 0 replies; 7+ messages in thread From: Rich Felker @ 2016-07-05 3:14 UTC (permalink / raw) To: musl On Mon, Jul 04, 2016 at 03:30:23PM +0200, Igmar Palsenberg wrote: > > > > > - the kernel will not deliver any signal to process 1, unless a signal > > > handler for that particular signal has been installed > > > > > > > not all signals behave that way. > > For pid 1 this is the case. Unless some signals are exempt from this. > > > > > -if process 1 calls abort() (regardless of what purpose that would fill), then: > > > > > > - if a handler was setup, it should be done whatever the handler does > > > > > > - if a handler was not setup, nothing should happen (as in: > > > process didn't receive any signal at all) > > > > > > > this is raise(SIGABRT), abort is different. > > Different how ? The manual says it's just a signal unblock followed by a > kill(self, SIGABRT). The man page is likely wrong. Read the actual specification. It's specified to raise SIGABRT as if by raise, but also to cause the program to terminate with abnormal status in cases where raising the signal does not cause termination already. And it's explicitly forbidden from returning, ever. > > > What the standards say: > > > > > > (http://pubs.opengroup.org/onlinepubs/9699919799/) > > > > > > "The SIGABRT signal shall be sent to the calling process as if by > > > means of raise() with the argument SIGABRT." > > > > > > > it also says > > > > "The abort() function shall cause abnormal process termination > > to occur, unless the signal SIGABRT is being caught and the > > signal handler does not return." > > > > and > > > > "The abort() function shall not return." > > > > (in c11 abort is _Noreturn and returning from such a function > > is undefined behaviour). > > Hmm.. What happens if a hander is installed, but that never returns ? (but > also doesn't terminate the process). If I read the manpage correct, it > says it's OK, but also says it isn't. If the handler never returns then the program does not terminate from the abort call. This could happen if the signal handler is exited using longjmp/siglongjmp, or just by remaining in the signal-handling context indefinitely, or by performing some other action to terminate the process as part of the signal handler (e.g. _Exit). Rich ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-07-05 3:14 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-07-04 8:09 abort() PID 1 Jorge Almeida 2016-07-04 8:28 ` Igmar Palsenberg 2016-07-04 9:37 ` Jorge Almeida 2016-07-04 9:31 ` Szabolcs Nagy 2016-07-04 9:49 ` Jorge Almeida 2016-07-04 13:30 ` Igmar Palsenberg 2016-07-05 3:14 ` Rich Felker
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/musl/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).