如何优化调试?

时间:2011-02-08 15:04:00

标签: erlang

崩溃报告(SASL)或多或少地提供了错误发生的位置和原因。 但是有可能改进这个(函数,代码行等)吗?

2 个答案:

答案 0 :(得分:2)

如果您可以重现错误,获取更多信息的最佳方法是在相关部分放置dbg跟踪并查看该输出。

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

这通常对我有用。将Mod和Func替换为您要调试的任何模块和函数。

如果您正在寻找更详细的事后记录,那么sasl和error_logger是您的朋友。当然,SASL没有给你足够的信息,如果你的系统中发生了很多这种情况,你可能要么学会更好地理解SASL输出,要么编写自己的日志处理程序。将您自己的错误处理程序插入SASL并根据需要输出内容非常容易。

然而,您将永远不会获得行号,因为在编译时该信息被销毁,并且VM无法知道哪条线路崩溃了。然而它确实知道哪个函数以及可能与哪些参数相关,因此通常可以找出出错的地方。除非你编写很长的函数,否则IMO代码很难闻,并且你应该将代码重构为较小的函数。

答案 1 :(得分:2)

一般来说,没有。 erlang .beam文件不包含原始代码中的行号,因此很难知道问题出在哪一行。我在项目中使用了许多宏,包括"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])).

这确实为你提供了一些日程行来寻找。为了进行调试,我还经常使用 eper 套件中的 redbug 工具:

https://github.com/massemanet/eper

它允许您在呼叫发生时实时跟踪:

 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> 

我希望这会有所帮助。