2013-06-05 89 views
0

當我嘗試使用「process_flag」來捕獲兒童的錯誤報告時,日誌顯示trap_exit不起作用。這個問題讓我麻煩了20個小時。爲什麼process_flag陷阱出口不能在這裏工作?

以下日誌不包含我的陷阱日誌應該顯示在這裏,像" lager:info("loop_1_0,~p,~p",[From,Reason]); %%<---should show this line."

([email protected])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

也許它是由同步調用引起的。當兩個pid(鏈接在一起)之間進行同步調用時,兩者都會崩潰,另一個pid不會收到退出消息。 –

回答

1

其中一個原因可能是當您在handle_call/3中生成錯誤時,它會導致gen_server:call/2生成異常並導致調用過程崩潰。你永遠不會輸入loop/0函數。簡單的方法來測試,這將是與

catch gen_server:call(Pid,{test_only}), 

更換gen_server呼叫,看看會發生什麼。

+0

非常感謝你的配合。 –