[erlang-bugs] gen_server:start hangs

Raimo Niskanen <>
Wed Jul 1 12:20:02 CEST 2009


On Wed, Jun 24, 2009 at 01:32:01PM -0500, Brentley Jones wrote:
> Hello,
> 
> I came across a weird hang when using gen_server:start. When inside  
> Module:init/1 and it returns the wrong value, erlang:error's,  
> erlang:exit's, or erlang:throw's, this gets passed onto the caller.  
> But when you spawn_link a process and it dies before Module:init/1  
> returns, gen_server:start hangs.

This seems to be a bug, indeed. Thankfully the most common way to
start a gen_server is start_link, and then there is no problem.

The caller hangs in proc_lib:sync_wait/2 since gen_server:init_it/6
fails to call proc_lib:init_ack/2 when killed by a process link.

In case you use gen_server:start_link and process_flag(trap_exit,
true) in your test program, it is caught by proc_lib:sync_wait/2,
so the code tries to handle this but fails when there is no
process link, hence it must be a bug now when we can use monitors.

The solution would probably be to use a monitor in proc_lib.

We will fix this in a future release.

> 
> Here is the output and code to demonstrate it:
> 
> Erlang R13B01 (erts-5.7.2) [source] [64-bit] [smp:2:2] [rq:2] [async- 
> threads:0] [kernel-poll:false]
> 
> Eshell V5.7.2  (abort with ^G)
> 1> gen_server_bug:test(throw).
> {error,{bad_return_value,throw_fail}}
> 2> gen_server_bug:test(error).
> {error,{error_fail,[{gen_server_bug,init,1},
>                     {gen_server,init_it,6},
>                     {proc_lib,init_p_do_apply,3}]}}
> 3> gen_server_bug:test(exit).
> {error,exit_fail}
> 4> gen_server_bug:test(spawn_bug).
> % hangs here...
> 
> 
> %% gen_server_bug.erl
> -module(gen_server_bug).
> 
> -export([init/1]).
> -export([test/1]).
> 
> test(Type) ->
>     gen_server:start(?MODULE, Type, []).
> 
> init(throw) ->
>     erlang:throw(throw_fail),
>     {ok, ok};
> init(error) ->
>     erlang:error(error_fail),
>     {ok, ok};
> init(exit) ->
>     erlang:exit(exit_fail),
>     {ok, ok};
> init(spawn_bug) ->
>     spawn_link(fun() -> erlang:exit(spawn_exit) end),
>     %% Wait so this process dies from the linked process dieing
>     receive
> 	after 1000 -> ok
>     end,
>     {ok, ok}.
> 
> 
> 
> Also, no response on the Dialyzer bugs? ( 
> http://www.erlang.org/cgi-bin/ezmlm-cgi?2:mss:1347:200906:lgkhjjcjokhpllgmkinj 
>  and 
>  http://www.erlang.org/cgi-bin/ezmlm-cgi?2:mss:1350:200906:nmcjgdfnlcnjelpijacl 
>  )
> 
> 
> ________________________________________________________________
> erlang-bugs mailing list. See http://www.erlang.org/faq.html
> erlang-bugs (at) erlang.org

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


More information about the erlang-bugs mailing list