[erlang-questions] Some problem abount exit signal?

Robert Virding <>
Thu Dec 9 01:03:18 CET 2010


Yes, the problem is not with the "sender" of the signal. exit/1 and exit/2 are different: exit/1 ends the process which results in exit reason being sent as a signal to the processes in the link set; while exit/2 fakes a signal to the receiving process *as if* the process had died.

The problem occurs in the "receiving" process. If it receives a 'kill' signal it will behave differently depending on how the signal was sent. There should not be two different behaviours attached to one signal, kill, depending on how it was sent. A 'kill' should always be a 'kill' in the same way as a 'normal' is always a 'normal'. It is really not different if the signal 'normal' caused a process to terminate when sent with exit/2 but be ignored if the sending process dies with exit(normal).

Or writing a server where a request message means different things depending on who sent them.

Different behaviours should be caused by things with different names.

Robert


----- "Hynek Vychodil" <> wrote:

> I few moment I think there is the bug but after some experiments I
> have to say it is pretty clear here.
> 
> exit/1 doesn't sends any signal. It is simple "local exception" -
> termination which is catchable in catch and try. When it is not catch
> process terminates as usual and sends exit message to linked
> processes
> with reason. 'kill' reason is send as any other reason. There is not
> special meaning except 'normal' ...
> 
> exit/2 sends message and only when there is 'kill' reason it makes
> "untrappable" kill and is translated to 'killed' exit message to
> linked processes. exit/2 sends message which doesn't have "local"
> behavior even I send it to myself because it is just like any other
> message. I.e. it is uncatchable by catch or try. When exit signal is
> not trapped i.e. it is untrappable (only direct exit/2 'kill') or is
> not 'normal' and exit signals are not trapped then process dies and
> exit signal is resend to linked processes with reason translation to
> 'killed' just only for untrappable 'kill'.
> 
> It makes perfect sense for me and I can't see there any bug or
> misconception. Maybe documentation should be more explicit there.
> 
> On Sun, Dec 5, 2010 at 2:36 AM, Robert Virding
> <> wrote:
> > Yes, this is how it works, but I definitely consider this to be a
> bug. To elaborate with a simple example:
> >
> > 1> self().
> > <0.31.0>
> > 2> spawn_link(fun () -> exit(kill) end).
> > ** exception exit: killed
> > 3> self().
> > <0.35.0>
> >
> > Here I have received 'kill' signal and died as I should. Now I trap
> exits:
> >
> > 4> process_flag(trap_exit, true).
> > false
> > 5> spawn_link(fun () -> exit(kill) end).
> > <0.39.0>
> > 6> flush().
> > Shell got {'EXIT',<0.39.0>,kill}
> > ok
> >
> > This time I received a trappable 'kill' signal. Finally I explicitly
> send the 'kill' signal to me:
> >
> > 7> Self = self().
> > <0.35.0>
> > 8> process_flag(trap_exit, true).          %Just to be explicit
> > true
> > 9> spawn_link(fun () -> exit(Self, kill) end).
> > ** exception exit: killed
> > 10> self().
> > <0.45.0>
> >
> > And this time I received an untrappable 'kill' signal.
> >
> > This means that there are two different types of 'kill' signals,
> trappable and untrappable, in the systems depending on how they were
> sent. This is illogical and unclear as there should not be two
> different signals with the same name which behave differently. It is
> definitely a bug which should be fixed. I see two (three) different
> solutions:
> >
> > 1. Make it so that a process which does exit(kill) sends a real,
> untrappable kill signal to its link set (which then in turn transmit
> 'killed').
> >
> > 2. Make it so that a process which does exit(kill) behaves as if it
> were killed and so transmits 'killed' to its link set.
> >
> > 3. Leave it as it is and create a
> 'properly_behaving_really_untrappable_kill' signal which behaves
> sensibly.
> >
> > I think the first option is the best.
> >
> > Robert
> >
> > P.S. Now to copy all this to erlang-bugs.
> >
> > P.P.S. I have just noticed that doing exit(self(), normal) kills me
> while some other process doing exit(Me, normal) doesn't. Sigh, so
> normal isn't normal.
> >
> >
> > ----- "Ulf Wiger" <> wrote:
> >
> >> Process C terminates itself with exit(kill). The atom 'kill'
> >> is not special in this case, but simply a normal exit reason.
> >>
> >> A propagated exit signal can never act as a kill signal in the
> >> first place, but here, not even the original exit is an
> untrappable
> >> kill.
> >>
> >> Try:
> >>
> >> Eshell V5.8.1  (abort with ^G)
> >> 1> self().
> >> <0.31.0>
> >> 2> catch exit(kill).
> >> {'EXIT',kill}
> >> 3> self().
> >> <0.31.0>
> >>
> >> BR,
> >> Ulf W
> >>
> >> On 2 Dec 2010, at 05:37, sky wrote:
> >>
> >> > Hi guys,
> >> >
> >> > In the Joe's book <<progamming erlang>>, page 163, there are
> some
> >> description about exit signal :
> >> >
> >> > When an exit signal arrives at a process, then a number of
> >> different
> >> > things might happen. What happens depends upon the state of the
> >> > receiving process and upon the value of the exit signal and is
> >> deter-
> >> > mined by the following table:
> >> > <moz-screenshot.png>
> >> >
> >> > but when use edemo1:start(true, {die, kill}), the result is:
> >> >
> >> > edemo1:start(true, {die,kill}).
> >> > Process b received {'EXIT',<0.73.0>,kill}
> >> > process b (<0.72.0>) is alive
> >> > process c (<0.73.0>) is dead
> >> > ok
> >> > Why process b is alive? Cause as the descripion in this book,
>  when
> >> the exit signal
> >> > {'EXIT',<0.73.0>,kill}
> >> > arrived, the process b will die and broadcast the exit signal
> killed
> >> to the link set.
> >> >
> >> > the souce code of edemo1 module as following:
> >> >
> >> > %% ---
> >> > %%  Excerpted from "Programming Erlang",
> >> > %%  published by The Pragmatic Bookshelf.
> >> > %%  Copyrights apply to this code. It may not be used to create
> >> training material,
> >> > %%  courses, books, articles, and the like. Contact us if you are
> in
> >> doubt.
> >> > %%  We make no guarantees that this code is fit for any purpose.
> >> > %%  Visit http://www.pragmaticprogrammer.com/titles/jaerlang for
> >> more book information.
> >> > %%---
> >> >
> >> > -module(edemo1).
> >> > -export([start/2]).
> >> >
> >> > start(Bool, M) ->
> >> >     A = spawn(fun() -> a() end),
> >> >     B = spawn(fun() -> b(A, Bool) end),
> >> >     C = spawn(fun() -> c(B, M) end),
> >> >     sleep(1000),
> >> >     status(b, B),
> >> >     status(c, C).
> >> >
> >> >
> >> > a() ->
> >> >     process_flag(trap_exit, true),
> >> >     wait(a).
> >> >
> >> > b(A, Bool) ->
> >> >     process_flag(trap_exit, Bool),
> >> >     link(A),
> >> >     wait(b).
> >> >
> >> > c(B, M) ->
> >> >     link(B),
> >> >     case M of
> >> >     {die, Reason} ->
> >> >         exit(Reason);
> >> >     {divide, N} ->
> >> >         1/N,
> >> >         wait(c);
> >> >     normal ->
> >> >         true
> >> >     end.
> >> >
> >> >
> >> >
> >> > wait(Prog) ->
> >> >     receive
> >> >     Any ->
> >> >         io:format("Process ~p received ~p~n",[Prog, Any]),
> >> >         wait(Prog)
> >> >     end.
> >> >
> >> >
> >> >
> >> > sleep(T) ->
> >> >     receive
> >> >     after T -> true
> >> >     end.
> >> >
> >> > status(Name, Pid) ->
> >> >     case erlang:is_process_alive(Pid) of
> >> >     true ->
> >> >         io:format("process ~p (~p) is alive~n", [Name, Pid]);
> >> >     false ->
> >> >         io:format("process ~p (~p) is dead~n", [Name,Pid])
> >> >     end.
> >> >
> >> >
> >>
> >> Ulf Wiger, CTO, Erlang Solutions, Ltd.
> >> http://erlang-solutions.com
> >
> > ________________________________________________________________
> > erlang-questions (at) erlang.org mailing list.
> > See http://www.erlang.org/faq.html
> > To unsubscribe; mailto:
> >
> >
> 
> 
> 
> -- 
> --Hynek (Pichi) Vychodil
> 
> Analyze your data in minutes. Share your insights instantly. Thrill
> your boss.  Be a data hero!
> Try GoodData now for free: www.gooddata.com


More information about the erlang-questions mailing list