我在 gen_server 的 init 部分有一个运行时错误。- Init 由 process_flag(trap_exit,true) 开始 - gen_server 是监督树的一部分 我尝试在终止模块中打印原因,但它似乎在其他地方退出。- 为什么不调用终止?应用程序以关机为原因停止。- 如何以及在哪里捕获运行时错误?
1 回答
在这种terminate
情况下通常会调用回调,即因为您已捕获退出。
唯一不是这种情况的地方是崩溃发生在 init 函数中。在这种情况下,责任在主管身上,主管通常会因此而终止自己的工作。然后这个错误爬上主管树,直到它终止你的整个应用程序。
通常,主管会记录一个上下文设置为 的主管报告start_error
。这是您的提示,即监督树的部分存在您应该处理的问题。您应该检查这一点,因为您可能对错误发生的位置有错误的假设。
从这里编辑
您的问题是您根本不了解 SASL。研究它。这是一个如何使用它的示例。
您的示例中的提升代码:
首先,bahlonga 需要告诉 Erlang 我们有一个 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]).
我们破解了 #state{} 记录,以便它可以与您的代码一起使用
-record(state, { name, port, socket_listen }).
基本的 start_linkage...
start_link() ->
gen_server:start_link({local, foo}, ?MODULE, [], []).
您的 init 函数,包括生成问题。
init([]) ->
Port = 3252,
Name = "foo",
为了简单起见,我们在上面做了一些修改......
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.
缺少功能的黑客攻击....
handle_accept(_) ->
#state{}.
其余的只是基础知识......所以我省略了它们。
现在对于foo_sup
主管foo
:
-module(foo_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
-define(SERVER, ?MODULE).
基本启动链接...
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
基本的 ChildSpec。让 foo 孩子启动并运行......
init([]) ->
FooCh = {foo, {foo, start_link, []},
permanent, 2000, worker, [foo]},
{ok, {{one_for_all,0,1}, [FooCh]}}.
启用 SASL 的引导 Erlang:
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)
让我们尝试产生主管......
1> foo_sup:start_link().
我们得到了这个:
=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}]}
上面我们看到foo:init/1
由于异常而崩溃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:
现在主管可以报告问题了!
=SUPERVISOR REPORT==== 9-Dec-2010::01:05:48 ===
Supervisor: {local,foo_sup}
Context: start_error
上下文正如我所说的那样......
Reason: {blabla,[{foo,init,1},
{gen_server,init_it,6},
{proc_lib,init_p_do_apply,3}]}
并具有预期的原因。
Offender: [{pid,undefined},
{name,foo},
{mfargs,{foo,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]