[erlang-questions] Some problem abount exit signal?

Robert Virding robert.virding@REDACTED
Sun Dec 5 02:36:02 CET 2010


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" <ulf.wiger@REDACTED> 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


More information about the erlang-questions mailing list