2011-05-11 7 views
4

제 젠 서버를 시작할 때 오류가 하나 있습니다. 디버깅 방법을 알고 싶습니다. 감사합니다!Erlang에서 오류를 디버깅하는 방법은 무엇입니까?

"예 : add_listener (self(),"127.0.0.1 ", 10999)를 실행합니다." start_link 이후.

오류 :

=ERROR REPORT==== 11-May-2011::13:41:57 === 
** Generic server <0.37.0> terminating 
** Last message in was {'EXIT',<0.35.0>, 
          {{timeout, 
           {gen_server,call, 
            [<0.35.0>, 
            {add_listener,"127.0.0.1",10999}]}}, 
          [{gen_server,call,2}, 
          {erl_eval,do_apply,5}, 
          {shell,exprs,6}, 
          {shell,eval_exprs,6}, 
          {shell,eval_loop,3}]}} 
** When Server state == {state,example, 
           {dict,0,16,16,8,80,48, 
            {[],[],[],[],[],[],[],[],[],[],[],[],[], 
             [],[],[]}, 
            {{[],[],[],[],[],[],[],[],[],[],[],[],[], 
             [],[],[]}}}, 
           {dict,0,16,16,8,80,48, 
            {[],[],[],[],[],[],[],[],[],[],[],[],[], 
             [],[],[]}, 
            {{[],[],[],[],[],[],[],[],[],[],[],[],[], 
             [],[],[]}}}, 
           []} 
** Reason for termination == 
** {{timeout,{gen_server,call,[<0.35.0>,{add_listener,"127.0.0.1",10999}]}}, 
    [{gen_server,call,2}, 
    {erl_eval,do_apply,5}, 
    {shell,exprs,6}, 
    {shell,eval_exprs,6}, 
    {shell,eval_loop,3}]} 
** exception exit: {timeout,{gen_server,call, 
             [<0.35.0>,{add_listener,"127.0.0.1",10999}]}} 
    in function gen_server:call/2 

내 코드는 다음과 같습니다 잘

-module(test_ess_tcp). 

-export([start_link/0, 
     add_listener/3, 
     remove_listener/3]). 

-export([init/2, handle_call/3, handle_cast/2, handle_info/2]). 
-export([terminate/2, sock_opts/0, new_connection/4]). 

-behavior(ess_tcp). 

start_link() -> 
    ess_tcp:start_link(?MODULE, []). 

add_listener(Pid, IpAddr, Port) -> 
    gen_server:call(Pid, {add_listener, IpAddr, Port}). 

remove_listener(Pid, IpAddr, Port) -> 
    gen_server:call(Pid, {remove_listener, IpAddr, Port}). 

init([], State) -> 
    %% Example storing callback module specific state 
    %% This modifies the server state 
    {ok, ess_tcp:store_cb_state([], State)}. 

handle_call({add_listener, IpAddr, Port}, _From, State) -> 
    %% Example of getting callback module state 
    io:format("Not used here, but just an example"), 
     [] = ess_tcp:get_cb_state(State), 
    case ess_tcp:add_listen_socket({IpAddr, Port}, State) of 
     {ok, State1} -> 
      {reply, ok, State1}; 
     Error -> 
      {reply, Error, State} 
    end; 
handle_call({remove_listener, IpAddr, Port}, _From, State) -> 
    case ess_tcp:remove_listen_socket({IpAddr, Port}, State) of 
     {ok, State1} -> 
      {reply, ok, State1}; 
     Error -> 
      {reply, Error, State} 
    end; 
handle_call(_Msg, _From, State) -> 
    {reply, ignored, State}. 

handle_cast(_Msg, State) -> 
    {noreply, State}. 

handle_info({tcp, Sock, Data}, State) -> 
    Me = self(), 
    P = spawn(fun() -> worker(Me, Sock, Data) end), 
    gen_tcp:controlling_process(Sock, P), 
    {noreply, State}; 

handle_info(_Msg, State) -> 
    {noreply, State}. 

terminate(_Reason, _State) -> 
    ok. 

sock_opts() -> 
    [binary, {active, once}, {packet, 0}]. 

new_connection(_IpAddr, _Port, Sock, State) -> 
    Me = self(), 
    P = spawn(fun() -> worker(Me, Sock) end), 
    gen_tcp:controlling_process(Sock, P), 
    {ok, State}. 

worker(Owner, Sock) -> 
    gen_tcp:send(Sock, "Hello\n"), 
    inet:setopts(Sock, [{active, once}]), 
    gen_tcp:controlling_process(Sock, Owner). 

worker(Owner, Sock, Data) -> 
    gen_tcp:send(Sock, Data), 
    inet:setopts(Sock, [{active, once}]), 
    gen_tcp:controlling_process(Sock, Owner). 

답변

7

, 당신의 gen_server : 호출 할 때 호출이 시간 제한을 받고있다. 즉, gen_server가 호출에 대한 기본 3 초 시간 초과보다 오래 걸리거나 어딘가에서 차단됩니다.

동작을 디버깅하는 데 추적을 사용하는 것이 이상적입니다. 예를 들어 당신이 테스트를 실행하기 전에 쉘이를 입력하면 :

dbg:tracer(),dbg:p(all,c),dbg:tpl(ess_tcp, x). 

당신은 거기에서 무슨 일이 일어나고 있는지 볼 수 ess_tcp 내에서 모든 기능에 추적합니다. dbg에 대한 자세한 내용은 http://www.erlang.org/doc/man/dbg.html

+0

감사합니다. 왜 아직도 gen_server가 차단 될 수 있는지 말해 주실 수 있습니까? – why

+1

@why : 디버거에서 인쇄 한 마지막 호출을보고 어떤 기능이 응답을 차단하는지 알려줍니다. –

+0

감사합니다! 나는 그것을 해결, 나는 gen_server에 잘못된 PID를 전달 :) – why

0

실제로 가장 좋은 도구는 io : format 문입니다. Put io : 의심스러운 부분을 형식화하고 예상 값을 얻는 지 확인합니다. 위의 질문에 대해서는 주로 어딘가에 붙어 있습니다 !!

관련 문제