mailing list of musl libc
 help / color / mirror / code / Atom feed
* 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: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  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  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).