summaryrefslogtreecommitdiff
path: root/lib/debugger
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2020-02-18 06:26:33 +0100
committerBjörn Gustavsson <bjorn@erlang.org>2020-02-21 10:16:21 +0100
commit38df9be8e5fabf9de15524fe176696b7e3bbeac7 (patch)
tree04d854ba115edc3cd9c0adf424d2f3b9aec90353 /lib/debugger
parent468b9a20b7f9d9585df750987b52e9e8f942f0ff (diff)
downloaderlang-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.erl15
-rw-r--r--lib/debugger/src/dbg_iload.erl2
-rw-r--r--lib/debugger/test/exception_SUITE.erl81
-rw-r--r--lib/debugger/test/int_eval_SUITE_data/stacktrace.erl13
-rw-r--r--lib/debugger/test/line_number_SUITE.erl4
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