4 Stimmen

Wie lassen sich Fehler in Erlang beheben?

Ich habe einen Fehler beim Starten meines Gen-Servers, ich möchte wissen, wie ich ihn beheben kann, danke!

Ich führe "example:add_listener(self(), "127.0.0.1", 10999)." nach start_link aus.

Der Fehler lautet:

=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

Mein Code lautet:

-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).

7voto

Lukas Punkte 5067

Nun, Ihr gen_server:call erhält einen Timeout, wenn er aufgerufen wird. Das bedeutet, dass der gen_server entweder länger als die standardmäßige 3-Sekunden-Zeitüberschreitung für einen Aufruf benötigt oder irgendwo blockiert ist.

Die Verwendung von Tracing zur Fehlersuche ist ideal. Zum Beispiel, wenn Sie dies in der Shell eingeben, bevor Sie den Test ausführen:

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

werden Sie alle Funktionen innerhalb von ess_tcp verfolgen, um zu sehen, was dort vor sich geht. Für weitere Informationen über dbg siehe http://www.erlang.org/doc/man/dbg.html

0voto

niting112 Punkte 2348

Das beste Werkzeug zum Debuggen in Erlang sind io:format-Anweisungen. Setzen Sie io:formats dort ein, wo Sie Zweifel haben, und sehen Sie, ob Sie die erwarteten Werte erhalten. In Bezug auf obige Frage ist es vor allem irgendwo stecken !!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X