How to refine the debugging?

2019-05-26 00:46发布

问题:

Crash report (SASL) gives more or less where and why a bug happens. But is it possible to refine this (the function, the line de code, etc) ?

回答1:

If you can reproduce the fault, the best way to get more information is to put a dbg trace on sections in question and review that output.

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

This usually does the trick for me. Replace Mod and Func with whatever module and function you want to debug.

If you are looking for more detailed post-mortem logging then sasl and the error_logger are your friends. There are of course times when SASL does not give you enough info, if this happens a lot in your system you probably should either learn to understand the SASL output better or write your own log handler. It is quite easy to plug-in your own error handler into SASL and output things as you want.

You will however never get line number as that information is destroyed at compilation time and there is no way for the VM to know which line crashed. It does however know which function and possibly with which arguments, given this it is usually possible to find out where things went wrong. Unless you write very long functions, which IMO is bad code smell and a sign that you should refactor your code to smaller functions.



回答2:

In general, no. The erlang .beam files does not contain the line numbers from the original code, so it is hard to know at what line the problem occurred. I do have a number of macros I use in my project, included as "log.hrl":

-define(INFO(T), error_logger:info_report(T)).
-define(WARN(T), error_logger:warning_report(
    [process_info(self(), current_function), {line, ?LINE} | T])).
-define(ERR(T), error_logger:error_report(
    [process_info(self(), current_function), {line, ?LINE} | T])).

-define(DEBUG(Format, Args), io:format("D(~p:~p:~p) : "++Format++"~n",
                                   [self(),?MODULE,?LINE]++Args)).
-define(DEBUGP(Args), io:format("D(~p:~p:~p) : ~p~n",
                                   [self(),?MODULE,?LINE, Args])).

and this does give you some log lines in the program to hunt for. For debugging I often also use the redbug tool from the eper suite:

https://github.com/massemanet/eper

It allows you to trace in realtime whenever a call happens:

 Eshell V5.8.3  (abort with ^G)
 1> redbug:start("erlang:now() -> stack;return", [{time, 60*1000}]).
 ok
 2> erlang:now().
 {1297,183814,756227}

 17:50:14 <{erlang,apply,2}> {erlang,now,[]}
   shell:eval_loop/3 
   shell:eval_exprs/7 
   shell:exprs/7 

 17:50:14 <{erlang,apply,2}> {erlang,now,0} -> {1297,183814,756227}
 3> 

I hope this helps.



标签: erlang