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