[erlang-bugs] [erlang-questions] Strange behaviour of exit(kill)
Loïc Hoguin
essen@REDACTED
Thu Oct 8 14:37:19 CEST 2015
On 10/07/2015 02:27 PM, Francesco Lattanzio wrote:
> I always thought that when a process dies because it was sent a 'kill'
> message it would broadcast to the linked processes a 'killed' EXIT
> message (see Concurrent Programming in Erlang - Part I, D.3 Exit
> signals, p. 193 ).
> However for some reason recent implementations of the VM broadcasts a
> 'kill' EXIT message (I could only test it on Erlang VMs as old as
> R13B04).
1> Pid = spawn_link(fun() -> receive after infinity -> ok end end).
<0.36.0>
2> exit(Pid, kill).
** exception exit: killed
3> f().
ok
4> Pid = spawn_link(fun() -> receive after infinity -> ok end end).
<0.41.0>
5> process_flag(trap_exit, true).
false
6> exit(Pid, kill).
true
7> flush().
Shell got {'EXIT',<0.41.0>,killed}
ok
Cheers,
> I'm not asking to revert this behaviour (I bet such a change would
> impact a lot of code), however it would be nice to know why it was
> chosen a two-semantics kill message instead of more obvious two
> one-semantic kill and killed message (if someone knows).
>
> On Wed, Oct 07, 2015 at 03:27:24AM -0700, Robert Virding wrote:
>> I still find that extremely inconsistent, there are actually 2 'kill' signals: one that is sent with exit(Pid, kill) and the other
>> which sent when you do exit(kill). So I can trap 'kill' and I can't trap 'kill', great.
>>
>> I would personally go the other way and say that kill is kill however it is sent. But I agree with you, I'm not holding my breath
>> waiting for it to be fixed.
>>
>> Robert
>>
>> P.S. I am not even going to mention the terribly inconsistent handling of errors in link/1.
>>
>>
>> On 7 October 2015 at 00:51, Håkan Huss <huss01@REDACTED> wrote:
>>
>> 2015-10-07 3:46 GMT+02:00 Robert Virding <rvirding@REDACTED>:
>>
>> It's all about signals and not messages. Sending a message to a process should *NEVER* by default kill it even if it has
>> the same format as an 'EXIT' message. NEVER!. A signal is converted to a message when it arrives at a process which is
>> trapping exits unless it is the 'kill' which is untrappable and the process always dies.
>>
>>
>> Yes, but the 'kill' signal is not an exit signal with reason kill. The 'kill' signal can only be sent by calling exit/2 with
>> Reason = kill, which is documented to have the effect that "an untrappable exit signal is sent to Pid which will
>> unconditionally exit with exit reason killed." There is no mention of how the exit reason in that exit signal, and since it is
>> not trappable there is no way to observe it.
>>
>>
>> Explicitly sending the SIGNAL with exit(Pid, kill) should unconditionally kill the process
>>
>> Yes.
>>
>>
>> as should dying with the reason 'kill' in exit(kill) which also sends the SIGNAL 'kill'.
>>
>> No, this sends an exit signal with reason kill, but that is not the same ass the signal sent using exit(Pid, kill).
>>
>>
>> In both cases the process receives the SIGNAL 'kill', as shown in my example, but in one case it is trappable and in the
>> other it is untrappable.
>>
>> No, in one case it receives an exit signal with reason kill, in the other case it receives the special untrappable exit signal
>> which causes unconditional termination.
>>
>>
>> My point is that the *same* signal results in different behaviour depending on how it was sent. That's incocnsistent.
>>
>> I agree that it is inconsistent. I would have preferred that the exit(Pid, kill) was a separate function, e.g., kill(Pid) and
>> that exit(Pid, kill) would be handled as any other exit/2 call. But I won't hold my breath in anticipation of that being
>> changed...
>>
>> /Håkan
>>
>>
>> Robert
>>
>>
>> On 6 October 2015 at 18:33, zxq9 <zxq9@REDACTED> wrote:
>>
>> On Wednesday 07 October 2015 10:25:38 zxq9 wrote:
>>
>> > or maybe it is that {'EXIT', Pid = self(), kill} *is* specifically untrappable by way of matching on self()?
>>
>> That was too much to hope for:
>>
>> 1> P = spawn(fun Loop() -> receive M -> io:format("Got ~p~n", [M]), Loop() end end).
>> <0.1889.0>
>> 2> P ! {'EXIT', P, kill}.
>> Got {'EXIT',<0.1889.0>,kill}
>> {'EXIT',<0.1889.0>,kill}
>> 3> P ! {'EXIT', P, blam}.
>> Got {'EXIT',<0.1889.0>,blam}
>> {'EXIT',<0.1889.0>,blam}
>> 4> exit(P, kill).
>> true
>> 5> P ! {'EXIT', P, blam}.
>> {'EXIT',<0.1889.0>,blam}
>>
>> If it *did* turn out that matching {'EXIT', self(), kill} was untrappable I would just say "ah, that makes sense -- now
>> I can understand the mechanism behind this without thinking about VM details". Instead it appears to be a case of
>> mysterious activity underlying a message form that is semantically overloaded. And that stinks.
>>
>> -Craig
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>>
>>
>>
>
>> _______________________________________________
>> erlang-bugs mailing list
>> erlang-bugs@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-bugs
>
>
--
Loïc Hoguin
http://ninenines.eu
Author of The Erlanger Playbook,
A book about software development using Erlang
More information about the erlang-bugs
mailing list