2013-06-05 1 views
0

어린이 오류보고를 잡기 위해 "process_flag"를 사용하려고하면 로그에 trap_exit이 작동하지 않는다고 표시됩니다. 문제는 20 시간 동안 나를 괴롭힌다.왜 process_flag 트랩 출구가 작동하지 않습니까?

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. 

===

:

다음 로그 == 다음 " 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 

처럼 여기에 표시해야 내 트랩 로그를 포함하지 않는 것은 내 예제 코드입니다

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}), 

으로 바꾸고 무슨 일이 일어나는 지 확인하는 것입니다.

+0

매우 감사합니다. –