why
why

Reputation: 24861

How to debug errors in Erlang?

I got one error when starting my gen server, i want to know how to debug it, thanks!

I run "example:add_listener(self(), "127.0.0.1", 10999)." after start_link.

The error is :

=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

My code is :

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

Upvotes: 4

Views: 1578

Answers (2)

niting112
niting112

Reputation: 2640

actually best tool to debug in erlang is io:format statements. Put io:formats where you have doubts and see if you get the expected values. Regarding above question it is mainly stuck somewhere !!

Upvotes: 0

Lukas
Lukas

Reputation: 5327

Well, your gen_server:call is getting a timeout when called. That means that the gen_server is either taking longer than the default 3 second timeout for a call or it is blocked somewhere.

using tracing to debug kind of behaviour is ideal. For instance if you type this in the shell before running the test:

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

you will trace on all functions within ess_tcp to see what is going on in there. For more info about dbg see http://www.erlang.org/doc/man/dbg.html

Upvotes: 7

Related Questions