[erlang-questions] Strange behaviour of exit(kill)

zxq9 <>
Wed Oct 7 03:25:38 CEST 2015

On Tuesday 06 October 2015 18:00:10 Robert Virding wrote:

> 7> spawn_link(fun () -> exit(S, die) end).
> <0.43.0>
> 8> flush().
> Shell got {'EXIT',<0.43.0>,die}
> Shell got {'EXIT',<0.43.0>,normal}
> ok
> 9> spawn_link(fun () -> exit(kill) end).
> <0.46.0>
> 10> flush().
> Shell got {'EXIT',<0.46.0>,kill}
> ok
> 11> spawn_link(fun () -> exit(S, kill) end).
> ** exception exit: killed

> What gives? So just receiving a 'kill' signal is not what kills me but it
> has to be sent in a certain way. So the process receiving a signal knows
> how the signal was sent. This is really inconsistent! It should be the
> signal itself which determines what the receiving process does. I would
> definitely class this as a bug.

Hi, Robert.


This has bothered me too whenever I stop to think about it (usually I don't). It is definitely hard to understand when you're trying to build a mental model of how things work.

Is it really a bug? It is documented to work this way, and seems to have been made this way on purpose. So maybe not that kind of a bug, but a design bug.

It is semantically overloaded from the perspective of the user:

    Case 1:
I receive a message {'EXIT', Pid, Reason = kill} where Pid /= self() which is just informing me of the demise of another process due to Reason.

    Case 2:
I receive a message {'EXIT', Pid, Reason = kill} where Pid /= self() which is telling me I should exit with Reason.

What is the difference? It is invisible at the level that we normally deal with the environment. I am really uncomfortable with the result of the flush() on line 8.

'kill' is supposed to be special, but it is only special to the first process receiving the message. An identically formed message *appears* to propagate, but clearly something more interesting is happening underneath. And no clues are provided to the user about why there is a difference. I feel like exit(Pid, kill) should send something special and clearly untrappable to Pid (like {'EXIT', Pid, kill} is an untrappable form, always -- or maybe it is that {'EXIT', Pid = self(), kill} *is* specifically untrappable by way of matching on self()?), and then Pid should propagate something different like {'EXIT', Pid, killed} to make the difference clear.


More information about the erlang-questions mailing list