erlang - Erlang堆栈跟踪中包含多少条目?

erlang - Erlang堆栈跟踪中包含多少条目?,第1张

当从Erlang程序中查看错误的堆栈跟踪时,有时在我看来,我没有看到整个图片,有些条目已被删除。堆栈跟踪中包含的条目数是否有限制?

最佳答案:

1 个答案:

答案 0 :(得分:4)

首先,如果将堆栈跟踪打印为Erlang术语,请注意io:format如果列表足够深,可能会截断列表。如果发生这种情况,您会在输出中看到...

其次,如果看起来堆栈跟踪中间缺少条目,则可能是因为尾部调用优化。如果函数做的最后一件事就是调用另一个函数,那么调用函数的堆栈帧就会被消除,并且在堆栈跟踪中不可见。

除此之外,堆栈跟踪中仅包含最后一个(最里面的)八个堆栈帧。例如,如果程序发出十二帧深度的错误信号(参见下面的清单),则会得到以下结果:

1> foo:one().
** exception error: this_is_twelve
     in function  foo:twelve/0 (foo.erl, line 49)
     in call from foo:eleven/0 (foo.erl, line 45)
     in call from foo:ten/0 (foo.erl, line 41)
     in call from foo:nine/0 (foo.erl, line 37)
     in call from foo:eight/0 (foo.erl, line 33)
     in call from foo:seven/0 (foo.erl, line 29)
     in call from foo:six/0 (foo.erl, line 25)
     in call from foo:five/0 (foo.erl, line 21)

请注意,堆栈跟踪中不包含最外面的四个条目,只剩下最内层的八个条目。

八是默认值。您可以使用backtrace_depth致电erlang:system_flag/2来更改它。 (它返回旧值。)

2> erlang:system_flag(backtrace_depth, 10).
8
3> foo:one().                              
** exception error: this_is_twelve
     in function  foo:twelve/0 (foo.erl, line 49) 
     in call from foo:eleven/0 (foo.erl, line 45)
     in call from foo:ten/0 (foo.erl, line 41)
     in call from foo:nine/0 (foo.erl, line 37)
     in call from foo:eight/0 (foo.erl, line 33)
     in call from foo:seven/0 (foo.erl, line 29)
     in call from foo:six/0 (foo.erl, line 25)
     in call from foo:five/0 (foo.erl, line 21)
     in call from foo:four/0 (foo.erl, line 17)
     in call from foo:three/0 (foo.erl, line 13)

这是foo.erlx原子用于防止函数调用成为尾调用,这意味着调用者的堆栈帧将从堆栈跟踪中删除。

-module(foo).
-compile(export_all).

one() ->
   two(),
   x.

two() ->
   three(),
   x.

three() ->
   four(),
   x.

four() ->
   five(),
   x.

five() ->
   six(),
   x.

six() ->
   seven(),
   x.

seven() ->
   eight(),
   x.

eight() ->
   nine(),
   x.

nine() ->
   ten(),
   x.

ten() ->
   eleven(),
   x.

eleven() ->
   twelve(),
   x.

twelve() ->
   error(this_is_twelve),
   x.
本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复