[erlang-questions] Parent crashes when child crashes in ssl:ssl_accept

Michael Smith michael@REDACTED
Thu Apr 2 15:29:40 CEST 2009


Hi,

I'm an Erlang newbie, maintaining an absolutely tiny Erlang program -- it's
essentially an SSL wrapper around a C program using open_port.

I'm updating from R11B to R12B-5 and I noticed ssl:accept/2 is deprecated, so
I'm switching to ssl:transport_accept in the parent followed by ssl:ssl_accept
in the child after proc_lib:spawn.

Normally, if I have a crash in the child, that particular connection drops and
the parent keeps listening. But if ssl:ssl_accept throws an error due to timeout
or garbage on the socket, my child crashes and then my parent stops listening. I
get two crash reports, one for my child and one for gen_server:call/1. It's
strange because I'm not referencing gen_server anywhere in my code.

I tried playing with the trap_exit flag, but it didn't seem to help.

The crash reports are below, followed by a short test program. Any hints would
be appreciated.

=CRASH REPORT==== 2-Apr-2009::09:19:51 ===
  crasher:
    pid: <0.55.0>
    registered_name: []
    exception error: no match of right hand side value {error,esslerrssl}
      in function  ssl_crashme:serve_client/1
    initial call: ssl_crashme:serve_client/1
    ancestors: [<0.46.0>,<0.1.0>]
    messages: []
    links: []
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 233
    stack_size: 23
    reductions: 92
  neighbours:

=CRASH REPORT==== 2-Apr-2009::09:19:51 ===
  crasher:
    pid: <0.46.0>
    registered_name: []
    exception exit: {normal,
                        {gen_server,call,
                            [<0.54.0>,
                             {release_msgs,<0.46.0>,<0.55.0>},
                             infinity]}}
      in function  gen_server:call/3
      in call from ssl_crashme:server_loop/1
    initial call: ssl_crashme:server_loop/1
    ancestors: [<0.1.0>]
    messages: []
    links: [<0.45.0>]
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 377
    stack_size: 23
    reductions: 337
  neighbours:



-module(ssl_crashme).

-export([start/0, server_loop/1, serve_client/1]).

start() ->
    application:start(sasl),
    application:start(ssl),
    {ok, ListenSocket} = ssl:listen(5050, [list,
                                           {certfile, "./cert/host.cert"},
                                           {keyfile, "./cert/host.key"},
                                           {verify, 0},
                                           {depth, 0},
                                           {active, false}]),
    {A,B,C} = now(),
    ssl:seed(<<A:16,B:32,C:32>>),
    Pid = proc_lib:spawn(?MODULE, server_loop, [ListenSocket]),
    ssl:controlling_process(ListenSocket, Pid),
    io:format("server listening to requests~n").

server_loop(ListenSocket) ->
    case ssl:transport_accept(ListenSocket, 3000) of
        {error, timeout} ->
            ?MODULE:server_loop(ListenSocket);
        {ok, Socket} ->
            io:format("server got connection, spawning process~n"),
            Pid = proc_lib:spawn(?MODULE, serve_client, [Socket]),
            ssl:controlling_process(Socket, Pid),
            ?MODULE:server_loop(ListenSocket);
        _ ->
             %% lets try again for all other errors
            ?MODULE:server_loop(ListenSocket)
    end.

serve_client(Socket) ->
    ok = ssl:ssl_accept(Socket, 15000),
    {ok, Str} = ssl:recv(Socket, 0, 15000),
    io:format("got string: ~s~n", [Str]),
    ok = ssl:send(Socket, "thanks").



Thanks,
Mike




More information about the erlang-questions mailing list