Crash on gen_server:start_link/3

Dinislam Salikhov Dinislam.Salikhov@REDACTED
Fri Apr 30 14:15:54 CEST 2021

Hi Zsolt,

It's ok that shell process exits, but I find it awkward that it binds the variable at the same time. So it looks like the function has returned and right after that there is a side effect of exit signal.

Maybe, the docs should be enhanced with a piece that unless exit signal is trapped the caller will be killed with it when Module:init/1 returns {stop, Reason} or 'ignore' (but gen_server:start_link() still returns the value)? But I'd like to be sure about the intended behavior before making any such changes.

Using gen_sersver:start/3 would be nice, but there is a time window between gen_server:start() return and linking when the gen_server may cease to exist. I don't want to fix one problem by introducing another one:)

Dinislam Salikhov
From: Zsolt Laky <zsolt.laky@REDACTED>
Sent: Friday, April 30, 2021 2:49:28 PM
To: Dinislam Salikhov
Cc: erlang-questions@REDACTED
Subject: Re: Crash on gen_server:start_link/3

Hi Danislam,

I think this is the expected behaviour.

In the below example, gen_server:start_link/3 spawns and links a process to the shell, so when that process exits because of the {stop, 42} return, it sends an exit signal to the shell that exits (crash) and restarts.

If you want to handle it, use gen_server:start/3 instead. You may check the result and decide whether to link or not. This case you will not receive an exit signal from the process.

When two processes are linked, either one stops, will send an exit signal to the other. If the other does not handle it (trap_exit) it will also die.

Kind regards,

> On Apr 30, 2021, at 12:59 PM, Dinislam Salikhov <Dinislam.Salikhov@REDACTED> wrote:
> Hello,
> I have a gen_server that may fail in init/1. It returns {stop, Error} in this case.
> According to documentation, I should get {error, Error} as a result of gen_server:start_link/3, but instead of that the calling process crashes with Error reason.
> If I make trap_exit before gen_server:start_link() then I get the expected {error, Error} but there's a message about exited gen_server process in my mailbox.
> But I can't distinguish it from other similar messages as I don't have a pid of the failed gen_server.
> Even more interesting behavior is in shell.
> # cat my_gen_server.erl
> -module(my_gen_server).
> -export([init/1]).
> init(Arg) -> {stop, Arg}.
> # erl
> 1> self().
> <0.79.0>
> 2> Q = gen_server:start_link(my_gen_server, 42, []).
> {error,42}
> =CRASH REPORT==== 30-Apr-2021::13:09:41.507086 ===
> ...
> ** exception error: 42
> 3> Q.
> {error,42}
> 4> self().
> <0.84.0>
> The process crashes, but the shell keeps the return value intact.
> So, it looks like either docs or implementation has a bug. What's the intended behavior?
> By now, there is a workaround way to start linked gen_server without a crash:
> spawn_link a proxy process which will trap_exit and do gen_server:start_link() and then provide the result in the outer process. Is there less ugly way?
> P.S. I tried it in OTP-, erts-11.1.8
> Dinislam Salikhov

More information about the erlang-questions mailing list