考虑以下代码:
-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}]}]}}
答案 0 :(得分:1)
如果没有任何异常,erlang:backtrace()
返回的堆栈跟踪为空。
比erlang:backtrace()
更有用的东西包括指令指针和进程的callstack,无论你是否遇到异常。
这应该是门票:
io:format("~s~n", [element(2, process_info(self(), backtrace))]).
(当然,自我可以与另一个Pid
)
答案 1 :(得分:0)
将调用进程中的最后一个异常的调用堆栈反向跟踪( stacktrace )作为
{Module,Function,Arity,Location}
元组列表获取。第一个元组中的Field Arity可以是该函数调用的参数列表,而不是arity整数,具体取决于异常。
请注意上述文本中的上一个例外。在第一次调用期间,还没有任何异常,因此没有任何堆栈跟踪返回。然后使用error
使erlang:error/1
类[1]异常,以便下一次调用返回上一次调用的stacktrace!
有成语如何获得当前代码的堆栈跟踪:
try throw(foo) catch foo -> erlang:get_stacktrace() end.
或使用旧的(过时的)方式:
catch throw(foo), erlang:get_stacktrace().
[1]:有三类例外:throw
,error
,exit
。