2011-05-11 48 views
4

啓動我的gen服務器時出現一個錯誤,我想知道如何調試它,謝謝!如何在Erlang中調試錯誤?

我跑 「的例子:add_listener(個體經營(), 」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秒超時長,要麼在某處被阻塞。

使用跟蹤調試樣的行爲是理想的。例如,如果你在運行測試之前,在shell鍵入:

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 2011-05-11 08:06:07

+1

@why:嘗試查看調試器打印的最後一個調用,這可能會提示您哪些函數阻止了響應。 – 2011-05-11 08:51:21

+0

謝謝!我解決它,我把錯誤的PID傳給gen_server :) – why 2011-05-11 09:27:14

0

二郎調試其實最好的工具是IO:報表格式。把io:你有疑問的格式,看看你是否得到期望的值。 關於上述問題,它主要是卡在某處!