Как отлаживать ошибки в Erlang? - PullRequest
4 голосов
/ 11 мая 2011

Я получил одну ошибку при запуске моего сервера gen, я хочу знать, как его отладить, спасибо!

Я запускаю "пример: 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).

Ответы [ 2 ]

7 голосов
/ 11 мая 2011

Ну, ваш gen_server: call получает тайм-аут при вызове. Это означает, что 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 голосов
/ 14 мая 2011

на самом деле лучший инструмент для отладки в erlang - это операторы io: format.Поместите форматы io: туда, где у вас есть сомнения, и посмотрите, получите ли вы ожидаемые значения.Относительно вышеупомянутого вопроса это в основном где-то застряло !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...