0

When I start up a function within the erl shell, it works fine. When I try to invoke the same function with erl ... -s module function, it fails.

The line of code that eventually fails is:

start(Port) ->
    mochiweb_http:start([{port, Port}, {loop, fun dispatch_requests/1}]).

I'm positive that Port is set correctly. My error message is:

=CRASH REPORT==== 17-Jan-2010::00:21:09 ===
  crasher:
    initial call: mochiweb_socket_server:acceptor_loop/1
    pid: <0.65.0>
    registered_name: []
    exception exit: {error,closed}
      in function  mochiweb_socket_server:acceptor_loop/1
    ancestors: [mochiweb_http,<0.1.0>]
    messages: []
    links: []
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 377
    stack_size: 24
    reductions: 93
  neighbours:

I tried the debugger and it lets me step through right up until the line of code above is given. After I pass that, it gives me this crash report.

Any help is greatly appreciated.

Eli
  • 1,269
  • 8
  • 17
  • Can you paste in a minimal code that reproduces this error? – Zed Jan 17 '10 at 09:41
  • Zed: http://pastie.org/781981 – Eli Jan 17 '10 at 17:03
  • I realized that what I pasted wouldn't have compiled. This doesn't even work for me: http://pastie.org/782752 What system are you running on? I'm on OS X with Erlang R13B02. – Eli Jan 18 '10 at 06:16

4 Answers4

1

Hm, I think that should work. Are all modules compiled with the same compiler version? IIRC there might be weird errors on the socket level if not. BTW, you might call your entry point function start which is the default for -s.

andi5
  • 1,606
  • 1
  • 11
  • 10
  • andi5: how do I check the compiler version on each? – Eli Jan 17 '10 at 17:04
  • proplists:get_value(version, Mod:module_info(compile)). should show it for the module Mod. Using lists:foreach/2 and code:all_loaded() you can iterate over the list of all loaded modules. – andi5 Jan 17 '10 at 19:45
  • Everything appears to be either undefined or 4.6.3. Check out http://pastie.org/782757. Also, this fails too, which uses start as the entry point: http://pastie.org/782752 – Eli Jan 18 '10 at 06:24
  • There is nothing about mochiweb_http. Are you sure you tried to start your server before checking the compiler versions? – andi5 Jan 19 '10 at 22:15
  • Ah yeah, that'd help. I reran it after loading that up and it's still all 4.6.3 or undefined. – Eli Jan 20 '10 at 03:50
  • andi: I'm pretty sure that the problem is coming from http://www.google.com/codesearch/p?hl=en#1XZncvCHC48/trunk/src/mochiweb_socket_server.erl&q=%7Berror,%20closed%7D%20package:http://mochiweb%5C.googlecode%5C.com&sa=N&cd=1&ct=rc&l=172 -- any ideas on what might cause gen_tcp to throw {error, closed}? – Eli Jan 21 '10 at 01:22
  • Eli: You are probably right about the source code location throwing the error. If it is not the compiler version, does adding an infinite receive loop at the end of start/0 change anything? – andi5 Jan 22 '10 at 23:37
  • andi5: for some reason, this works: http://pastie.org/791300 ! Any idea why this works but what I did before didn't? – Eli Jan 23 '10 at 16:18
  • Ok, I am not an expert with mochiweb, but this sounds like your loop function is not correct then. http://www.codeweblog.com/mochiweb-design/ might have better information. Please note that x is an atom, whereas X is either a bound or unbound variable. – andi5 Jan 23 '10 at 19:38
1

Alternatively you can try the -eval option:

erl -eval 'module:start(9090).'
legoscia
  • 39,593
  • 22
  • 116
  • 167
0

when using -s, the arguments are collected into a list, so the port would actually be enclosed in a list. you can check both cases (list or int) with a wrapper function (like start([Port])).

jspcal
  • 50,847
  • 7
  • 72
  • 76
  • I actually had a wrapper around that. I'm actually calling start_all/0 which calls start. My command is: erl -boot start_sasl -s server_util start_all – Eli Jan 17 '10 at 07:35
0

When you use -s to run Erlang functions, arguments are put into a list of atoms. When you use -run to run Erlang functions, arguments are put into a list of strings.

If you need an integer value to pass on, you will need to do the proper conversions. If you want to cover all cases, something like this could help:

start([Port]) when is_atom(Port) ->
    start([atom_to_list(Port)]);
start([Port]) when is_list(Port) ->
    start(list_to_integer(Port));
start(Port) when is_integer(Port) ->
    mochiweb_http:start([{port, Port}, {loop, fun dispatch_requests/1}]).

Consult the man page for erl ("erl -man erl") for details.

ndim
  • 35,870
  • 12
  • 47
  • 57
  • Thanks for the details. However, I should have edited my question, because I'm actually calling start/0 which calls start/1 with my default port. I started removing things and eventually simplified my problem to this: http://pastie.org/782752 -- does this work for you? It fails for me on OS X. Any ideas? Much appreciated. – Eli Jan 21 '10 at 04:09
  • Well, the 'loop' fun is not a loop. I am not familiar with mochiweb, so I cannot tell you that this is your issue. Anyway, that paste looks like a completely separate issue to me, like one of proper mochiweb API usage, not of "erl -s" startup. Probably better open a new question with that new problem. – ndim Jan 21 '10 at 14:36
  • ndim: but it works fine when I invoke it from within the erl console. Additionally, fixing it to a real loop doesn't help: http://pastie.org/788592. The problem is that gen_tcp:listen is returning {error, closed} for some reason. – Eli Jan 21 '10 at 18:58