diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2020-02-18 06:26:33 +0100 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2020-02-21 10:16:21 +0100 |
commit | 38df9be8e5fabf9de15524fe176696b7e3bbeac7 (patch) | |
tree | 04d854ba115edc3cd9c0adf424d2f3b9aec90353 /lib/debugger | |
parent | 468b9a20b7f9d9585df750987b52e9e8f942f0ff (diff) | |
download | erlang-38df9be8e5fabf9de15524fe176696b7e3bbeac7.tar.gz |
Don't keep stacktraces forever
The `erlang:get_stacktrace/0` BIF retrieves the stacktrace from
the previous error in the process. The problem is that the very
existence of `erlang:get_stacktrace/0` means that the stacktrace
and potentially function arguments must be kept indefinitely.
Therefore, in OTP 21, the `erlang:get_stacktrace/0` BIF was deprecated
and the syntax of try/catch extended to allow matching out the
stacktrace directly.
This commit changes `erlang:get_stacktrace/0` for OTP 23 to always
return an empty list (`[]`) and eliminates the need to keep the
stacktrace forever.
`erlang:get_stacktrace/0` is scheduled for removal in OTP 24.
Diffstat (limited to 'lib/debugger')
-rw-r--r-- | lib/debugger/src/dbg_ieval.erl | 15 | ||||
-rw-r--r-- | lib/debugger/src/dbg_iload.erl | 2 | ||||
-rw-r--r-- | lib/debugger/test/exception_SUITE.erl | 81 | ||||
-rw-r--r-- | lib/debugger/test/int_eval_SUITE_data/stacktrace.erl | 13 | ||||
-rw-r--r-- | lib/debugger/test/line_number_SUITE.erl | 4 |
5 files changed, 41 insertions, 74 deletions
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl index 74cff8595c..38c2035c5c 100644 --- a/lib/debugger/src/dbg_ieval.erl +++ b/lib/debugger/src/dbg_ieval.erl @@ -693,7 +693,7 @@ expr({'try',Line,Es,CaseCs,CatchCs,[]}, Bs0, Ieval0) -> end catch Class:Reason when CatchCs =/= [] -> - catch_clauses({Class,Reason,[]}, CatchCs, Bs0, Ieval) + catch_clauses({Class,Reason,get_stacktrace()}, CatchCs, Bs0, Ieval) end; expr({'try',Line,Es,CaseCs,CatchCs,As}, Bs0, Ieval0) -> Ieval = Ieval0#ieval{line=Line}, @@ -706,7 +706,7 @@ expr({'try',Line,Es,CaseCs,CatchCs,As}, Bs0, Ieval0) -> end catch Class:Reason when CatchCs =/= [] -> - catch_clauses({Class,Reason,[]}, CatchCs, Bs0, Ieval) + catch_clauses({Class,Reason,get_stacktrace()}, CatchCs, Bs0, Ieval) after seq(As, Bs0, Ieval#ieval{top=false}) end; @@ -905,14 +905,9 @@ expr({dbg,Line,self,[]}, Bs, #ieval{level=Le}) -> Self = get(self), trace(return, {Le,Self}), {value,Self,Bs}; -expr({dbg,Line,get_stacktrace,[]}, Bs, #ieval{level=Le}) -> - trace(bif, {Le,Line,erlang,get_stacktrace,[]}), - Stacktrace = get_stacktrace(), - trace(return, {Le,Stacktrace}), - {value,Stacktrace,Bs}; expr({dbg,Line,raise,As0}, Bs0, #ieval{level=Le}=Ieval0) -> - %% Since erlang:get_stacktrace/0 is emulated, we will - %% need to emulate erlang:raise/3 too so that we can + %% Since stacktraces are emulated, we will + %% need to emulate erlang:raise/3 so that we can %% capture the stacktrace. Ieval = Ieval0#ieval{line=Line}, {[Class,Reason,Stk0]=As,Bs} = eval_list(As0, Bs0, Ieval), @@ -1383,7 +1378,7 @@ catch_clauses(Exception, [{clause,_,[P],G,B}|CatchCs], Bs0, Ieval) -> nomatch -> catch_clauses(Exception, CatchCs, Bs0, Ieval) end; -catch_clauses({Class,Reason,[]}, [], _Bs, _Ieval) -> +catch_clauses({Class,Reason,_}, [], _Bs, _Ieval) -> erlang:Class(Reason). receive_clauses(Cs, Bs0, [Msg|Msgs]) -> diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl index ef3cf866ab..d15292d51d 100644 --- a/lib/debugger/src/dbg_iload.erl +++ b/lib/debugger/src/dbg_iload.erl @@ -438,8 +438,6 @@ expr({'fun',Anno,{function,M,F,A}}, _Lc) -> {make_ext_fun,ln(Anno),MFA}; expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,self}},[]}, _Lc) -> {dbg,ln(Anno),self,[]}; -expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,get_stacktrace}},[]}, _Lc) -> - {dbg,ln(Anno),get_stacktrace,[]}; expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,throw}},[_]=As}, _Lc) -> {dbg,ln(Anno),throw,expr_list(As)}; expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,error}},[_]=As}, _Lc) -> diff --git a/lib/debugger/test/exception_SUITE.erl b/lib/debugger/test/exception_SUITE.erl index ef824b00be..506d4d0366 100644 --- a/lib/debugger/test/exception_SUITE.erl +++ b/lib/debugger/test/exception_SUITE.erl @@ -275,67 +275,43 @@ ba_bnot(A) -> {'EXIT', {badarith, _}} = (catch bnot A). stacktrace(Conf) when is_list(Conf) -> - Tag = make_ref(), - {_,Mref} = spawn_monitor(fun() -> exit({Tag,erlang:get_stacktrace()}) end), - {Tag,[]} = receive {'DOWN',Mref,_,_,Info} -> Info end, V = [make_ref()|self()], {value2,{caught1,badarg,[{erlang,abs,[V],_}|_]=St1}} = stacktrace_1({'abs',V}, error, {value,V}), - St1 = erase(stacktrace1), - St1 = erase(stacktrace2), - St1 = erlang:get_stacktrace(), {caught2,{error,badarith},[{?MODULE,my_add,2,_}|_]=St2} = stacktrace_1({'div',{1,0}}, error, {'add',{0,a}}), - [{?MODULE,my_div,2,_}|_] = erase(stacktrace1), - St2 = erase(stacktrace2), - St2 = erlang:get_stacktrace(), {caught2,{error,{try_clause,V}},[{?MODULE,stacktrace_1,3,_}|_]=St3} = stacktrace_1({value,V}, error, {value,V}), - St3 = erase(stacktrace1), - St3 = erase(stacktrace2), - St3 = erlang:get_stacktrace(), {caught2,{throw,V},[{?MODULE,foo,1,_}|_]=St4} = stacktrace_1({value,V}, error, {throw,V}), - [{?MODULE,stacktrace_1,3,_}|_] = erase(stacktrace1), - St4 = erase(stacktrace2), - St4 = erlang:get_stacktrace(), ok. stacktrace_1(X, C1, Y) -> - erase(stacktrace1), - erase(stacktrace2), try try foo(X) of C1 -> value1 catch - C1:D1 -> {caught1,D1,erlang:get_stacktrace()} + C1:D1:S1 -> {caught1,D1,S1} after - put(stacktrace1, erlang:get_stacktrace()), foo(Y) end of V2 -> {value2,V2} catch - C2:D2 -> {caught2,{C2,D2},erlang:get_stacktrace()} - after - put(stacktrace2, erlang:get_stacktrace()) + C2:D2:S2 -> {caught2,{C2,D2},S2} end. nested_stacktrace(Conf) when is_list(Conf) -> V = [{make_ref()}|[self()]], - value1 = - nested_stacktrace_1({{value,{V,x1}},void,{V,x1}}, - {void,void,void}), + value1 = nested_stacktrace_1({{value,{V,x1}},void,{V,x1}}, + {void,void,void}), {caught1, [{?MODULE,my_add,2,_}|_], - value2, - [{?MODULE,my_add,2,_}|_]} = - nested_stacktrace_1({{'add',{V,x1}},error,badarith}, - {{value,{V,x2}},void,{V,x2}}), + value2} = nested_stacktrace_1({{'add',{V,x1}},error,badarith}, + {{value,{V,x2}},void,{V,x2}}), {caught1, [{?MODULE,my_add,2,_}|_], - {caught2,[{erlang,abs,[V],_}|_]}, - [{erlang,abs,[V],_}|_]} = + {caught2,[{erlang,abs,[V],_}|_]}} = nested_stacktrace_1({{'add',{V,x1}},error,badarith}, {{'abs',V},error,badarg}), ok. @@ -344,15 +320,13 @@ nested_stacktrace_1({X1,C1,V1}, {X2,C2,V2}) -> try foo(X1) of V1 -> value1 catch - C1:V1 -> - S1 = erlang:get_stacktrace(), - T2 = - try foo(X2) of - V2 -> value2 - catch - C2:V2 -> {caught2,erlang:get_stacktrace()} + C1:V1:S1 -> + T2 = try foo(X2) of + V2 -> value2 + catch + C2:V2:S2 -> {caught2,S2} end, - {caught1,S1,T2,erlang:get_stacktrace()} + {caught1,S1,T2} end. @@ -363,17 +337,14 @@ raise(Conf) when is_list(Conf) -> try try foo({'div',{1,0}}) catch - error:badarith -> - put(raise, A0 = erlang:get_stacktrace()), + error:badarith:A0 -> + put(raise, A0), erlang:raise(error, badarith, A0) end catch - error:badarith -> - A1 = erlang:get_stacktrace(), + error:badarith:A1 -> A1 = get(raise) end, - A = erlang:get_stacktrace(), - A = get(raise), [{?MODULE,my_div,2,_}|_] = A, %% N = 8, % Must be even @@ -381,19 +352,18 @@ raise(Conf) when is_list(Conf) -> try even(N) catch error:function_clause -> ok end, - B = odd_even(N, []), - B = erlang:get_stacktrace(), %% - C0 = odd_even(N+1, []), - C = lists:sublist(C0, N), - try odd(N+1) - catch error:function_clause -> ok + C = odd_even(N+1, []), + try + odd(N+1) + catch + error:function_clause -> ok end, - C = erlang:get_stacktrace(), - try erlang:raise(error, function_clause, C0) - catch error:function_clause -> ok + try + erlang:raise(error, function_clause, C) + catch + error:function_clause -> ok end, - C = erlang:get_stacktrace(), ok. odd_even(N, R) when is_integer(N), N > 1 -> @@ -436,7 +406,6 @@ my_abs(X) -> abs(X). gunilla(Config) when is_list(Config) -> {throw,kalle} = gunilla_1(), - [] = erlang:get_stacktrace(), ok. gunilla_1() -> diff --git a/lib/debugger/test/int_eval_SUITE_data/stacktrace.erl b/lib/debugger/test/int_eval_SUITE_data/stacktrace.erl index 3380178fdc..591841ada3 100644 --- a/lib/debugger/test/int_eval_SUITE_data/stacktrace.erl +++ b/lib/debugger/test/int_eval_SUITE_data/stacktrace.erl @@ -3,10 +3,15 @@ ?MODULE() -> OldDepth = erlang:system_flag(backtrace_depth, 32), - done = (catch do_try()), - Stk = trim(erlang:get_stacktrace()), - erlang:system_flag(backtrace_depth, OldDepth), - {done,Stk}. + try + do_try() + catch + throw:done:Stk0 -> + Stk = trim(Stk0), + {done,Stk} + after + erlang:system_flag(backtrace_depth, OldDepth) + end. trim([{int_eval_SUITE,_,_,_}|_]) -> []; diff --git a/lib/debugger/test/line_number_SUITE.erl b/lib/debugger/test/line_number_SUITE.erl index 276473b95f..4ad84b5a3b 100644 --- a/lib/debugger/test/line_number_SUITE.erl +++ b/lib/debugger/test/line_number_SUITE.erl @@ -90,8 +90,8 @@ close_calls(Where) -> %Line 86 call2(), %Line 90 call3(), %Line 91 no_crash %Line 92 - catch error:crash -> - erlang:get_stacktrace() %Line 94 + catch error:crash:Stk -> + Stk %Line 94 end. %Line 95 call1() -> %Line 97 |