<p dir="ltr">At 9, the spawned process is killing itself with reason kill, and the shell received a trappable exit message. At 11, the spawned process is killing the *shell* with reason kill. That's not a trappable signal coming from another process: it's an emulator command to kill the specified process, and the reason kill makes it untrappable.</p>
<p dir="ltr">It's a little nuanced, but pretty straightforward otherwise. When a process dies, it informs linked processes by way of message, which forces exit unless the receiving process is trapping exits. *exit/2 does not produce a message*, it tries to terminate the process. It's only converted into a message if the process is trapping exits, and reason kill bypasses the trapping logic.</p>
<div class="gmail_quote">On Oct 6, 2015 9:00 PM, "Robert Virding" <<a href="mailto:rvirding@gmail.com">rvirding@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div>I am giving an Erlang course and we are looking at the error handling. When showing examples I found a very strange behaviour (to me) of doing exit(kill). The linked process gets the 'kill' but it is trappable. However, if I use exit(P, kill) to send the kill signal it is, as it should be, not trappable.<br><br>Erlang/OTP 18 [erts-7.0] [source-4d83b58] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]<br><br>Eshell V7.0  (abort with ^G)<br>1> process_flag(trap_exit, true).<br>false<br>2> spawn_link(fun () -> exit(normal) end).<br><0.36.0><br>3> flush().                               <br>Shell got {'EXIT',<0.36.0>,normal}<br>ok<br>4> spawn_link(fun () -> exit(die) end).   <br><0.39.0><br>5> flush().                            <br>Shell got {'EXIT',<0.39.0>,die}<br>ok<br>6> S = self().<br><0.33.0><br>7> spawn_link(fun () -> exit(S, die) end).<br><0.43.0><br>8> flush().                               <br>Shell got {'EXIT',<0.43.0>,die}<br>Shell got {'EXIT',<0.43.0>,normal}<br>ok<br>9> spawn_link(fun () -> exit(kill) end).  <br><0.46.0><br>10> flush().                               <br>Shell got {'EXIT',<0.46.0>,kill}<br>ok<br>11> spawn_link(fun () -> exit(S, kill) end).<br>** exception exit: killed<br><br></div>The shell evaluator process traps exits and then spawn_links a number of processes which exit/1 and exit/2 with different reasons. Everything behaves normally until 9> where I spawn_link a process which does an exit(kill). I get the 'kill' signal, but it is a trappable 'kill' signal! If I send the 'kill' signal with exit/2 it is not trappable, as it shouldn't be.<br><br></div>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.<br><br></div>Robert<br><br></div>
<br>_______________________________________________<br>
erlang-bugs mailing list<br>
<a href="mailto:erlang-bugs@erlang.org">erlang-bugs@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-bugs" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-bugs</a><br>
<br></blockquote></div>