2
votes

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.

2
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 to see if you still get the same problem?Steve Vinoski
As far as debuggers go, there's the Erlang debugger, but IMO it's worth learning Erlang tracing 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
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

2 Answers

4
votes

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.

0
votes

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>