崩溃报告(SASL)或多或少地提供了错误发生的位置和原因。 但是有可能改进这个(函数,代码行等)吗?
答案 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>
我希望这会有所帮助。