当我尝试使用“process_flag”来捕获孩子的错误报告时,日志显示trap_exit不起作用。这个问题让我麻烦了20个小时。
以下日志不包含应在此处显示的陷阱日志,如" lager:info("loop_1_0,~p,~p",[From,Reason]); %%<---should show this line."
(emacs@yus-iMac.local)20> 05:18:26.048 [info] test_a_1
05:18:26.249 [info] levi_simulate_init_1,false
05:18:26.250 [error] gen_server pid_simulate_reader_user terminated with reason: no match of right hand value 3 in levi_simulate:handle_call/3 line 471
05:18:26.250 [error] CRASH REPORT Process pid_simulate_reader_user with 0 neighbours exited with reason: no match of right hand value 3 in levi_simulate:handle_call/3 line 471 in gen_server:terminate/6 line 747
==以下是我的示例代码:
1. `levi_simulate_tests.erl` main content
error_test_a()->
close_server(?PID_SIMULATE_READER_USER),
timer:sleep(200),
lager:info("test_a_1"),
spawn_trap_exit(fun crash_test_a/0),
pass.
spawn_trap_exit(Fun)->
_Pid = spawn(fun()->
process_flag(trap_exit,true),
Fun(),
loop(),
lager:info("receive_after loop")
end).
loop()->
receive
{'EXIT',From,Reason}->
lager:info("loop_1_0,~p,~p",[From,Reason]); %%<---should show this line.
X ->
lager:info("loop_2,~p",[X]),
loop()
after 3000 ->
ok
end.
crash_test_a()->
close_server(?PID_SIMULATE_READER_USER),
timer:sleep(200),
{ok,Pid} = levi_simulate:start_link(false,?PID_SIMULATE_READER_USER,true,[]),
Id = 1,
gen_server:call(Pid,{test_only}),
ok.
close_server(Server)->
try
Pid = whereis(Server),
case is_process_alive(Pid) of
true ->
exit(Pid,shut);
false ->
ok
end
catch
_:_->
ok
end.
===
2. levi_simulate.erl main content
-module(levi_simulate).
-compile([{parse_transform, lager_transform}]).
-behaviour(gen_server).
start_link(Need_link_ui_pid,Server_name,Connection_condition,
Tag_id_list) ->
gen_server:start_link({local,Server_name},?MODULE,
[Need_link_ui_pid,Server_name,
Connection_condition,Tag_id_list], []).
init([Need_link_ui_pid,Server_name,Connection_condition,Tag_id_list]) ->
case Need_link_ui_pid of
true ->
true = erlang:link(whereis(?PID_UI));
false ->
lager:info("levi_simulate_init_1,false"),
ok
end,
%% A = 2,
%% A = 3,
ok = levi_tag:init(Tag_id_list),
{ok, #state{connection_condition=Connection_condition,
pid_symbol = Server_name}}.
handle_call(Request, From, State) ->
A = 2,
A = 3, %% <------ create exit here
{reply,ok,State}.
答案 0 :(得分:1)
一个原因可能是当您在handle_call/3
中生成错误时,它会导致gen_server:call/2
生成异常并导致调用进程崩溃。您将永远不会输入loop/0
功能。测试此问题的简便方法是用
gen_server
调用
catch gen_server:call(Pid,{test_only}),
看看会发生什么。