Related
I have a simple supervisor that looks like this
-module(a_sup).
-behaviour(supervisor).
%% API
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local,?MODULE}, ?MODULE, []).
init(_Args) ->
RestartStrategy = {simple_one_for_one, 5, 3600},
ChildSpec = {
a_gen_server,
{a_gen_server, start_link, []},
permanent,
brutal_kill,
worker,
[a_gen_server]
},
{ok, {RestartStrategy,[ChildSpec]}}.
When I run this on the shell, it works perfectly fine. But now I want to run different instances of this supervisor on different nodes, called foo and bar (started as erl -sname foo and erl -sname bar, from a separate node called main erl -sname main). This is how I try to initiate this rpc:call('foo#My-MacBook-Pro', a_sup, start_link, [])., but after replying with ok it immediately fails with this message
{ok,<9098.117.0>}
=ERROR REPORT==== 7-Mar-2022::16:05:45.416820 ===
** Generic server a_sup terminating
** Last message in was {'EXIT',<9098.116.0>,
{#Ref<0.3172713737.1597505552.87599>,return,
{ok,<9098.117.0>}}}
** When Server state == {state,
{local,a_sup},
simple_one_for_one,
{[a_gen_server],
#{a_gen_server =>
{child,undefined,a_gen_server,
{a_gen_server,start_link,[]},
permanent,false,brutal_kill,worker,
[a_gen_server]}}},
{maps,#{}},
5,3600,[],0,never,a_sup,[]}
** Reason for termination ==
** {#Ref<0.3172713737.1597505552.87599>,return,{ok,<9098.117.0>}}
(main#Prachis-MacBook-Pro)2> =CRASH REPORT==== 7-Mar-2022::16:05:45.416861 ===
crasher:
initial call: supervisor:a_sup/1
pid: <9098.117.0>
registered_name: a_sup
exception exit: {#Ref<0.3172713737.1597505552.87599>,return,
{ok,<9098.117.0>}}
in function gen_server:decode_msg/9 (gen_server.erl, line 481)
ancestors: [<9098.116.0>]
message_queue_len: 0
messages: []
links: []
dictionary: []
trap_exit: true
status: running
heap_size: 610
stack_size: 29
reductions: 425
neighbours:
From the message it looks like the call expects the supervisor to be a gen_server instead? And when I try to initiat a gen_server on the node like this, it works out just fine, but not with supervisors. I can't seem to figure out if there's something different in trying to initiate supervisor on local/remote nodes, and if yes, what should we do to fix the issue?
As per #JoséM's suggestion, the supervisor in the remote node is also linked to the ephemeral RPC process. However since supervisor does not provide a start method, modifying the start_link() method as
start_link() ->
Pid = supervisor:start_link({local,?MODULE}, ?MODULE, []).
unlink(Pid),
{ok, Pid}.
solves the issue.
I'm trying to run my server. I copied my src files into a fresh cowboy install, this is the error I'm getting.
~/cowboy_ninja:.ls src
action_handler.erl gate.beam resolution.beam
arena.beam gate.erl resolution.erl
arena.erl guestbook.beam temple.beam
cowboy_ninja_app.erl guestbook.erl temple.erl
cowboy_ninja_sup.erl hello_handler.erl
~/cowboy_ninja:.
cat src/cowboy_ninja_app.erl
-module(cowboy_ninja_app).
-behaviour(application).
-export([start/2]).
-export([stop/1]).
start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/action", action_handler, []},
{"/join", hello_handler, []}]}
]),
{ok, _} = cowboy:start_clear(my_http_listener, 100,
[{port, 8080}],
#{env => #{dispatch => Dispatch}}
),
{ok, Pid} = gate:start_link(),
register(gate, Pid),
{ok, Guestbook} = guestbook:start_link(),
register(guestbook, Guestbook),
gate:action(Pid, {fight}),
cowboy_ninja_sup:start_link().
stop(_State) ->
ok.
See below.
~/cowboy_ninja:.gmake run
===> Starting relx build process ...
===> Resolving OTP Applications from directories:
/Users/quantum/cowboy_ninja/ebin
/Users/quantum/cowboy_ninja/deps
/usr/local/Cellar/erlang/19.1/lib/erlang/lib
/Users/quantum/cowboy_ninja/apps
/Users/quantum/cowboy_ninja/_rel
===> Resolved cowboy_ninja_release-1
===> Including Erts from /usr/local/Cellar/erlang/19.1/lib/erlang
===> release successfully created!
===> tarball /Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release/cowboy_ninja_release-1.tar.gz successfully created!
Exec: /Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release/erts-8.1/bin/erlexec -boot /Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release/releases/1/cowboy_ninja_release -mode embedded -boot_var ERTS_LIB_DIR /Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release/erts-8.1/../lib -config /Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release/releases/1/sys.config -args_file /Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release/releases/1/vm.args -- console
Root: /Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release
/Users/quantum/cowboy_ninja/_rel/cowboy_ninja_release
heart_beat_kill_pid = 52128
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
=INFO REPORT==== 1-Jan-2017::17:03:57 ===
application: cowboy_ninja
exited: {bad_return,
{{cowboy_ninja_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy_router,compile,
[[{'_',
[{"/action",action_handler,[]},
{"/join",hello_handler,[]}]}]],
[]},
{cowboy_ninja_app,start,2,
[{file,"src/cowboy_ninja_app.erl"},{line,8}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,273}]}]}}}}
type: permanent
{"Kernel pid terminated",application_controller,"{application_start_failure,cowboy_ninja,{bad_return,{{cowboy_ninja_app,start,[normal,[]]},{'EXIT',{undef,[{cowboy_router,compile,[[{'_',[{\"/action\",action_handler,[]},{\"/join\",hello_handler,[]}]}]],[]},{cowboy_ninja_app,start,2,[{file,\"src/cowboy_ninja_app.erl\"},{line,8}]},{application_master,start_it_old,4,[{file,\"application_master.erl\"},{line,273}]}]}}}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,cowboy_ninja,{bad_return,{{cowboy_ninja_app,start,[normal,[]]},{'EXIT',{undef,[{cowboy_router,compile,[[{'_',[{"/action",acti
heart: Sun Jan 1 17:03:58 2017: Erlang is crashing .. (waiting for crash dump file)
heart: Sun Jan 1 17:03:58 2017: Would reboot. Terminating.
gmake: *** [erlang.mk:6448: run] Error 1
It looks like it can't find my files? What is this error message saying?
You need to create a cowboy_ninja.app file and list all the applications you are using (cowboy, etc.). Relx will look at that file to see which applications it needs to include in your release.
http://learnyousomeerlang.com/building-otp-applications
Currently it is not including the cowboy application or any of it's compiled modules into your release.
Here is an example from the cowboy examples
{application, 'hello_world', [
{description, "Cowboy Hello World example"},
{vsn, "1"},
{modules, ['hello_world_app','hello_world_sup','toppage_handler']},
{registered, [hello_world_sup]},
{applications, [kernel,stdlib,cowboy]},
{mod, {hello_world_app, []}},
{env, []}
]}.
You also need to tell relx where to look for your applications (in your relx.config).
{lib_dirs, [
"/usr/local/lib/elixir/lib/*/ebin", "./_build/prod/lib/*/ebin", "./deps/*/ebin"]}.
If you are not using a build tool for your app take a look at erlang.mk. it automatically creates an app file for you.
I cross compiled erlang for arm system.
Later, installed Erlang into target as bellow:
./Install -sasl <ERL_ROOT>
When I check the Erlang on the target getting bellow error:
$ erl
Erlang:
=INFO REPORT==== 1-Jan-2015::19:30:44 ===
application: sasl
exited: {bad_return,
{{sasl,start,[normal,[]]},
{'EXIT',
{undef,
[{sasl,start,[normal,[]],[]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,273}]}]}}}}
type: permanent
Eshell V8.0 (abort with ^G)
1> {"Kernel pid terminated",application_controller,
"{application_start_failure,sasl,{bad_return,{{sasl,start,[normal,[]]},
{'EXIT',{undef,[{sasl,start,[normal,[]],[]},
{application_master,start_it_old,4,[{file,\"application_master.erl\"},
{line,273}]}]}}}}}"}
Crash dump is being written to: erl_crash.dump...done
Kernel pid terminated (application_controller)
({application_start_failure,sasl,
{bad_return,
{{sasl,start,[normal,[]]},{'EXIT',{undef,[{sasl,start,[normal,[]],[]},{application_master,start_it_old,4,[{f
Does anyone know about this error?
Thanks in advance.
This part of the error message:
{application_master,start_it_old,4,[{file,\"application_master.erl\"},{line,273}]}
shows the place where the error is found. If you loo at the code of application_master.erl you find:
start_it_old(Tag, From, Type, ApplData) ->
{M,A} = ApplData#appl_data.mod,
----> the line where the error message is built
case catch M:start(Type, A) of
{ok, Pid} ->
link(Pid),
From ! {Tag, {ok, self()}},
loop_it(From, Pid, M, []);
{ok, Pid, AppState} ->
link(Pid),
From ! {Tag, {ok, self()}},
loop_it(From, Pid, M, AppState);
{'EXIT', normal} ->
From ! {Tag, {error, {{'EXIT',normal},{M,start,[Type,A]}}}};
{error, Reason} ->
From ! {Tag, {error, {Reason, {M,start,[Type,A]}}}};
----> the case statement which manages the result
Other ->
From ! {Tag, {error, {bad_return,{{M,start,[Type,A]},Other}}}}
end.
so you know the the result of the evaluation of M:start(Type,A) has returned {'EXIT',{undef,[{sasl,start,[normal,[]],[]}. This means that the VM is not able to locate the file sasl.beam. So either it does not exist (the erlang libraries compilation is not completed) or something is wrong in the path (the file should be at "Installation_Path/../lib/sasl-x.y/ebin/sasl.beam"
I am trying to run a custom application but get multiple errors. I believe the main egs app gets an error because it calls the egs patch app which has an undefined type. I cant figure out how to get this working I have tried recompiling the code many times in regards to others with a similar problem but nothing seems to work. The cowboy start listener remains undefined.
This is the error I receive.
=CRASH REPORT==== 10-Apr-2013::21:02:00 ===
crasher:
initial call: application_master:init/4
pid: <0.106.0>
registered_name: []
exception exit: {bad_return,
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{patch,11030},
10,cowboy_tcp_transport,
[{port,11030}],
egs_patch_protocol,[]],
[]},
{egs_patch_app,start_listeners,1,
[{file,"src/egs_patch_app.erl"},
{line,44}]},
{egs_patch_app,start,2,
[{file,"src/egs_patch_app.erl"},
{line,31}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
in function application_master:init/4 (application_master.erl, line 138)
ancestors: [<0.105.0>]
messages: [{'EXIT',<0.107.0>,normal}]
links: [<0.105.0>,<0.7.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 610
stack_size: 27
reductions: 124
neighbours:
=INFO REPORT==== 10-Apr-2013::21:02:00 ===
application: egs_patch
exited: {bad_return,
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{patch,11030},
10,cowboy_tcp_transport,
[{port,11030}],
egs_patch_protocol,[]],
[]},
{egs_patch_app,start_listeners,1,
[{file,"src/egs_patch_app.erl"},{line,44}]},
{egs_patch_app,start,2,
[{file,"src/egs_patch_app.erl"},{line,31}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
type: temporary
=CRASH REPORT==== 10-Apr-2013::21:02:00 ===
crasher:
initial call: application_master:init/4
pid: <0.75.0>
registered_name: []
exception exit: {bad_return,
{{egs_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{login,12030},
10,cowboy_ssl_transport,
[{port,12030},
{certfile,"priv/ssl/servercert.pem"},
{keyfile,"priv/ssl/serverkey.pem"},
{password,"alpha"}],
egs_login_protocol,[]],
[]},
{egs_app,start_login_listeners,1,
[{file,"src/egs_app.erl"},{line,55}]},
{egs_app,start,2,
[{file,"src/egs_app.erl"},{line,38}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
in function application_master:init/4 (application_master.erl, line 138)
ancestors: [<0.74.0>]
messages: [{'EXIT',<0.76.0>,normal}]
links: [<0.74.0>,<0.7.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 987
stack_size: 27
reductions: 185
neighbours:
=INFO REPORT==== 10-Apr-2013::21:02:00 ===
application: egs
exited: {bad_return,
{{egs_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{login,12030},
10,cowboy_ssl_transport,
[{port,12030},
{certfile,"priv/ssl/servercert.pem"},
{keyfile,"priv/ssl/serverkey.pem"},
{password,"alpha"}],
egs_login_protocol,[]],
[]},
{egs_app,start_login_listeners,1,
[{file,"src/egs_app.erl"},{line,55}]},
{egs_app,start,2,
[{file,"src/egs_app.erl"},{line,38}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
type: temporary
Here are the files from which the errors originate.
egs_patch_app.erl
-module(egs_patch_app).
-behaviour(application).
-export([start/2, stop/1]). %% API.
-type application_start_type()
:: normal | {takeover, node()} | {failover, node()}.
%% API.
-spec start(application_start_type(), term()) -> {ok, pid()}.
start(_Type, _StartArgs) ->
{ok, PatchPorts} = application:get_env(patch_ports),
start_listeners(PatchPorts),
egs_patch_sup:start_link().
-spec stop(term()) -> ok.
stop(_State) ->
ok.
%% Internal.
-spec start_listeners([inet:ip_port()]) -> ok.
start_listeners([]) ->
ok;
start_listeners([Port|Tail]) ->
{ok, _Pid} = cowboy:start_listener({patch, Port}, 10,
cowboy_tcp_transport, [{port, Port}],
egs_patch_protocol, []),
start_listeners(Tail).
egs_app.erl
-module(egs_app).
-behaviour(application).
-export([start/2, stop/1]). %% API.
-include("/home/mattk/Desktop/egs-master/apps/egs/include/records.hrl").
-type application_start_type()
:: normal | {takeover, node()} | {failover, node()}.
-define(SSL_OPTIONS, [{certfile, "priv/ssl/servercert.pem"},
{keyfile, "priv/ssl/serverkey.pem"}, {password, "alpha"}]).
%% API.
-spec start(application_start_type(), term()) -> {ok, pid()}.
start(_Type, _StartArgs) ->
{ok, Pid} = egs_sup:start_link(),
application:set_env(egs_patch, patch_ports, egs_conf:read(patch_ports)),
application:start(egs_patch),
start_login_listeners(egs_conf:read(login_ports)),
{_ServerIP, GamePort} = egs_conf:read(game_server),
{ok, _GamePid} = cowboy:start_listener({game, GamePort}, 10,
cowboy_ssl_transport, [{port, GamePort}] ++ ?SSL_OPTIONS,
egs_game_protocol, []),
{ok, Pid}.
-spec stop(term()) -> ok.
stop(_State) ->
ok.
%% Internal.
-spec start_login_listeners([inet:ip_port()]) -> ok.
start_login_listeners([]) ->
ok;
start_login_listeners([Port|Tail]) ->
{ok, _Pid} = cowboy:start_listener({login, Port}, 10,
cowboy_ssl_transport, [{port, Port}] ++ ?SSL_OPTIONS,
egs_login_protocol, []),
start_login_listeners(Tail).
Here's our hint:
.....
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener, .....
The tuple {egs_patch_app,start,[normal,[]]} tells us that the error occurred in egs_patch_app:start/2. The atom EXIT is the tag of a notification message sent when a process has exited, or the result of an expression like catch error(someerror). Now we get to the interesting part. undef means an attempt was made to call an undefined function. A function is undefined if its Name/Arity doesn't match any known function. In this case, the undefined function is cowboy:start_listener().
Once again, the problem is that Cowboy has evolved while egs has not. Major changes in the Cowboy API have made the two incompatible. Since the last change in egs was about a year ago (assuming you're using essen's branch), you could try reverting to an older Cowboy tag by changing the corresponding rebar.config line to something like this:
{cowboy, ".*", {git, "git://github.com/extend/cowboy.git", {tag, "0.6.0"}}
Notice how "HEAD" changed to {tag, "0.6.0"}. The Cowboy reference may have to be changed in several applications (at least egs and egs_patch). You'll quite possibly need to clear your deps/ first.
Erlang error messages can be difficult to parse, but as a general rule of thumb, you should be on the lookout for a few atoms:
case_clause, meaning no clause in a case expression matched.
function_clause, meaning no function clause matched the arguments.
undef, as noted above, meaning a call to an external (not local to module) function couldn't be resolved.
badarg, which is Erlang's "illegal argument" exception.
badarith, a sneaky bastard that sometimes shows up when you mistype a variable name as an atom in an arithmetic expression, such as 1/x instead of 1/X.
To learn more about Erlang's error handling mechanisms, read the docs.
I have a run-time error in the init part of a gen_server.
- Init begin by process_flag(trap_exit,true)
- gen_server is part of a supervision tree
I try to print the reason in the terminate module but it seems to exit elsewhere.
- why terminate is not called ?
The application stops with shutdown as reason.
- How and where to catch the run-time error ?
The terminate callback is normally called in this situation, namely because you have trapped exits.
The only place where this is not the case is if the crash happens in the init-function. In that case, the responsibility is on the supervisor, who usually terminates itself as a result. Then this error crawls up the supervisor tree until it ends up terminating your whole application.
Usually, the supervisor will log a supervisor report with the context set to start_error. This is your hint that the part of the supervision tree has problems you should handle. You should check for this, because you may have the wrong assumption on where the error occurs.
EDITED FROM HERE
Your problem is that you don't know about SASL at all. Study it. Here is an example of how to use it.
Hoisted code from your example:
First, the bahlonga needed to tell Erlang we have a gen_server.
-module(foo).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
We hack the #state{} record so it can be used with your code
-record(state, { name, port, socket_listen }).
Basic start_linkage...
start_link() ->
gen_server:start_link({local, foo}, ?MODULE, [], []).
Your init function, spawn problem included.
init([]) ->
Port = 3252,
Name = "foo",
Above we have hacked a bit for the sake of simplification...
process_flag(trap_exit, true),
erlang:error(blabla),
Opts = [binary, {reuseaddr, true},
{backlog,5}, {packet, 0}, {active, false}, {nodelay, true}],
case gen_tcp:listen(Port,Opts) of
{ok,Socket_Listen} ->
logger:fmsg("--> [~s,init] Socket_Listen crée = ~p",
[Name,Socket_Listen]),
{ok,handle_accept(#state{socket_listen=Socket_Listen})};
{error, Reason} ->
logger:fmsg("--> [~s,init] Erreur, Raison =~p",
[Name,Reason]), {stop, Reason}
end.
Hacks for missing functions....
handle_accept(_) ->
#state{}.
The rest is just the basics..., so I omit them.
Now for foo_sup the supervisor for foo:
-module(foo_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
-define(SERVER, ?MODULE).
Basic start link...
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
Basic ChildSpec. Get the foo child up and running...
init([]) ->
FooCh = {foo, {foo, start_link, []},
permanent, 2000, worker, [foo]},
{ok, {{one_for_all,0,1}, [FooCh]}}.
Boot Erlang with SASL enabled:
jlouis#illithid:~$ erl -boot start_sasl
Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
=PROGRESS REPORT==== 9-Dec-2010::01:01:51 ===
[..]
Eshell V5.8.3 (abort with ^G)
Let us try to spawn the supervisor...
1> foo_sup:start_link().
And we get this:
=CRASH REPORT==== 9-Dec-2010::01:05:48 ===
crasher:
initial call: foo:init/1
pid: <0.58.0>
registered_name: []
exception exit: {blabla,[{foo,init,1},
{gen_server,init_it,6},
{proc_lib,init_p_do_apply,3}]}
Above we see that we have a crash in foo:init/1 due to an exception blabla.
in function gen_server:init_it/6
ancestors: [foo_sup,<0.45.0>]
messages: []
links: [<0.57.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 233
stack_size: 24
reductions: 108
neighbours:
And now the supervisor gets to report about the problem!
=SUPERVISOR REPORT==== 9-Dec-2010::01:05:48 ===
Supervisor: {local,foo_sup}
Context: start_error
The context is exactly as I said it would be...
Reason: {blabla,[{foo,init,1},
{gen_server,init_it,6},
{proc_lib,init_p_do_apply,3}]}
And with the expected reason.
Offender: [{pid,undefined},
{name,foo},
{mfargs,{foo,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]