1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
-module(stacktrace).
-export([?MODULE/0]).
?MODULE() ->
OldDepth = erlang:system_flag(backtrace_depth, 32),
try
do_try()
catch
throw:done:Stk0 ->
Stk = trim(Stk0),
{done,Stk}
after
erlang:system_flag(backtrace_depth, OldDepth)
end.
trim([{int_eval_SUITE,_,_,_}|_]) ->
[];
trim([H|T]) ->
[H|trim(T)];
trim([]) -> [].
do_try() ->
try
0 = id(42)
catch
error:{badmatch,42} ->
do_try2() %Tail-recursive
end.
do_try2() ->
try
0 = id(42)
catch
error:{badmatch,42} ->
do_try3() %Not tail-recursive
end,
?LINE.
do_try3() ->
try id(42) of
42 -> do_try4() %Tail-recursive
catch
error:ignore -> %Should never catch
?LINE
end.
do_try4() ->
try
do_recv() %Not tail-recursive
catch
error:ignore -> %Should never catch
?LINE
end.
do_recv() ->
self() ! x,
receive
x -> do_recv2() %Not tail-recursive
end,
?LINE.
do_recv2() ->
self() ! y,
receive
y -> do_recv3() %Tail-recursive
end.
do_recv3() ->
receive
after 0 -> do_recv4() %Tail-recursive
end.
do_recv4() ->
receive
after 0 -> do_if(true) %Not tail-recursive
end,
?LINE.
do_if(Bool) ->
if
Bool -> do_if2(Bool) %Tail-recursive
end.
do_if2(Bool) ->
if
Bool -> do_case(Bool) %Not tail-recursive
end,
?LINE.
do_case(Bool) ->
case Bool of
true -> do_case2(Bool) %Tail-recursive
end.
do_case2(Bool) ->
case Bool of
true -> do_fun(Bool) %Not tail-recursive
end,
?LINE.
do_fun(Bool) ->
F = fun(true) ->
do_fun2(Bool) %Tail-recursive
end,
F(Bool). %Tail-recursive
do_fun2(Bool) ->
F = fun(true, _) ->
cons(Bool) %Tail-recursive
end,
F(Bool, F), %Not tail-recursive. (The fun is not inlined)
?LINE.
cons(Bool) ->
[Bool|tuple()].
tuple() ->
{ok,op()}.
op() ->
1 + lc().
lc() ->
[done() || true].
done() ->
tail(100),
throw(done).
tail(0) -> ok;
tail(N) -> tail(N-1).
id(I) ->
I.
|