2

I'm going over a very basic erlang book while using yaws. I'm editing a single yaws file and refreshing the browser. Often (3rd time now) the process will just start to show this error. and i look and look for a syntax error or anything, and eventually i just restart the process and everything works. without any change to the source file.

right now this is the source file that triggered the error this last time

<erl>
out(Arg) ->
        {ehtml,
                {table, [{width, "100%"}],
                        {tr,[],
                                [{td, [{width, "50%"}], "hello world!"},
                                {td, [{width, "50%"}], "hi again."}]
                        }
                }
        }.

</erl>

I tried searching the error, but where all the search results have a meaningful context like "no access" all i get is "<<>>"

=ERROR REPORT==== 26-Nov-2013::20:17:32 ===
Yaws process died: {{badmatch,<<>>},
                    [{yaws_server,skip_data,2,
                                  [{file,"yaws_server.erl"},{line,2951}]},
                     {yaws_server,deliver_dyn_file,6,
                                  [{file,"yaws_server.erl"},{line,2717}]},
                     {yaws_server,aloop,4,
                                  [{file,"yaws_server.erl"},{line,1152}]},
                     {yaws_server,acceptor0,2,
                                  [{file,"yaws_server.erl"},{line,1013}]},
                     {proc_lib,init_p_do_apply,3,
                               [{file,"proc_lib.erl"},{line,227}]}]}

Some version info:

  • Yaws 1.94
  • Debian GNU/Linux 7.2 (wheezy)
  • Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux
  • Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]

Any ideas what this is telling me?

Also, any suggestions for debuggers that are good for beginners is very welcome.

gcb
  • 13,901
  • 7
  • 67
  • 92
  • On yaws master from github, which is just a few commits past version 1.98, I'm unable to reproduce this issue. Can you try updating to [version 1.98 from here](http://yaws.hyber.org/download/) to see if you still get the same problem? – Steve Vinoski Nov 28 '13 at 16:28
  • 2
    As far as debuggers go, there's the [Erlang debugger](http://www.erlang.org/doc/apps/debugger/debugger_chapter.html), but IMO it's worth learning [Erlang tracing](http://www.erlang.org/doc/man/dbg.html) instead, as it's much more powerful and easier than a debugger. In over 7 years of using Erlang I've used the debugger only twice but use tracing all the time. – Steve Vinoski Nov 28 '13 at 16:31
  • I also just tried beating on a copy of your .yaws file with siege against Yaws 1.94 and R15B01 but still couldn't reproduce it. – Steve Vinoski Nov 28 '13 at 16:39

2 Answers2

4

For debugging, I think using Erlang tracing will be helpful. We want to figure out why the yaws_server:skip_data/2 function would be getting a badmatch exception, and specifically why it's getting an empty binary passed to it as that's the only way it could encounter that error. So we need to trace that condition. Try these steps (and don't forget the trailing period on each Erlang shell command):

  1. Run yaws in interactive mode: yaws -i
  2. Once yaws comes up, hit enter to get an Erlang shell prompt.
  3. Create a tracing function for dbg so we get a reasonably formatted backtrace from the trace data: F = fun({trace,_,_,_,Dump},[]) -> io:format("~s~n", [binary_to_list(Dump)]), [] end.
  4. Turn on tracing with this command: dbg:tracer(process, {F, []}).
  5. Trace calls in all processes: dbg:p(all, call).

Now trace the condition of yaws_server:skip_data/2 getting an empty binary as a first argument, and when it does, get a backtrace:

dbg:tpl(yaws_server,skip_data,dbg:fun2ms(fun([<<>>, _]) -> message(process_dump()) end)).

With this in place, start hitting your .yaws page until you provoke the condition, at which point a backtrace will be displayed in your Erlang shell. If you get that backtrace, please copy it into a gist or pastebin and post a link to it as a follow-up here.

Steve Vinoski
  • 19,847
  • 3
  • 31
  • 46
  • thank you! will try that as soon as it happens. I noticed that it only happens when i'm altering the file a lot. – gcb Dec 01 '13 at 03:59
0

If I am correct the output of the out function is supposed to be a list. I didn't check your whole code but the following should work:

<erl>
out(Arg) ->
        [{ehtml,
                {table, [{width, "100%"}],
                        {tr,[],
                                [{td, [{width, "50%"}], "hello world!"},
                                {td, [{width, "50%"}], "hi again."}]
                        }
                }
        }].

</erl>
Pascal
  • 13,977
  • 2
  • 24
  • 32
  • it is optional. you can return a tuple (all earlier examples on the book are just one tuple) or a list, if you want to say, send headers along with the html output. Remeber that i mention that just restarting the server is enough to get rid of the failing condition. no change in code need to happen. – gcb Nov 27 '13 at 18:24
  • 1
    ooops, I didn't read enough carefully your question... Not too bad, I learned something. – Pascal Nov 28 '13 at 06:53