1

考虑下面的代码:

 -module(except).
 -compile(export_all).

 divone(X)->    erlang:error({badnews,erlang:get_stacktrace()}),1/X-1.
 tryreturn(X)->

      try divone(X) of
     Val->{result,2/Val}
    catch
    exit:Reason->{exit,Reason};
    throw:Throw->{throw,Throw};
    error:Error->{error,Error}
 end.

在shell中测试代码:

 Eshell V5.9.1  (abort with ^G)

 1> c(except).
 {ok,except}
 2> except:tryreturn(10). **%why cant't get stack trace info here?**
 {error,{badnews,[]}}          
 3> except:tryreturn(10). **%why can get here?**
 {error,{badnews,[{except,divone,1,
                     [{file,"except.erl"},{line,4}]},
             {except,tryreturn,1,[{file,"except.erl"},{line,7}]},
             {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,576}]},
             {shell,exprs,7,[{file,"shell.erl"},{line,668}]},
             {shell,eval_exprs,7,[{file,"shell.erl"},{line,623}]},
             {shell,eval_loop,3,[{file,"shell.erl"},{line,608}]}]}}
4

2 回答 2

1

如果没有任何异常,则返回的堆栈跟踪erlang:backtrace()为空。

比对您更有帮助erlang:backtrace()的是包含指令指针和进程的调用堆栈的东西,无论您是否捕获了异常。

这应该是票:

io:format("~s~n", [element(2, process_info(self(), backtrace))]).

(当然,自己可以与他人自由交换Pid

于 2012-09-04T02:34:23.297 回答
0

根据文件

以元组列表的形式获取调用进程中最后一个异常的调用堆栈回溯 ( stacktrace ) 。第一个元组中的字段 Arity 可以是该函数调用的参数列表,而不是一个 arity 整数,具体取决于异常。{Module,Function,Arity,Location}

请注意上述文本中的最后一个例外。在您第一次调用期间,还没有任何异常,因此没有任何堆栈跟踪要返回。然后你使用所以下一个调用返回上一个调用的堆栈跟踪来制作errorclass[1] 异常!erlang:error/1

有成语如何获取当前代码的堆栈跟踪:

try throw(foo) catch foo -> erlang:get_stacktrace() end.

或使用较旧(过时)的方式:

catch throw(foo), erlang:get_stacktrace().

[1]:异常分为三类:throw, error, exit.

于 2017-02-14T17:03:10.663 回答