aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debugger')
-rw-r--r--lib/debugger/src/dbg_ieval.erl24
-rw-r--r--lib/debugger/src/dbg_istk.erl83
2 files changed, 55 insertions, 52 deletions
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index fe7f9af1a9..32848a00ff 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -168,10 +168,18 @@ check_exit_msg(_Msg, _Bs, _Ieval) ->
%% and then raise the exception.
%%--------------------------------------------------------------------
exception(Class, Reason, Bs, Ieval) ->
- exception(Class, Reason, dbg_istk:delayed_stacktrace(Ieval),
- Bs, Ieval).
-
-exception(Class, Reason, Stacktrace, Bs, #ieval{module=M, line=Line}) ->
+ exception(Class, Reason, Bs, Ieval, false).
+
+exception(Class, Reason, Bs, Ieval, false) ->
+ do_exception(Class, Reason,
+ dbg_istk:delayed_stacktrace(no_args, Ieval),
+ Bs, Ieval);
+exception(Class, Reason, Bs, Ieval, true) ->
+ do_exception(Class, Reason,
+ dbg_istk:delayed_stacktrace(include_args, Ieval),
+ Bs, Ieval).
+
+do_exception(Class, Reason, Stacktrace, Bs, #ieval{module=M, line=Line}) ->
ExitInfo = {{M,Line}, Bs, dbg_istk:to_external()},
put(exit_info, ExitInfo),
put(stacktrace, Stacktrace),
@@ -249,7 +257,7 @@ meta_loop(Debugged, Bs, #ieval{level=Le} = Ieval) ->
Depth = max(0, Depth0 - length(Stk)),
Stk ++ MakeStk0(Depth)
end,
- exception(Class, Reason, MakeStk, Bs, Ieval);
+ do_exception(Class, Reason, MakeStk, Bs, Ieval);
%% Error must have occured within a re-entry to
%% interpreted code, simply raise the exception
@@ -463,7 +471,7 @@ do_eval_function(Mod, Name, As0, Bs0, Called, Ieval0) ->
{value, Val, Bs0};
undef ->
- exception(error, undef, Bs0, Ieval)
+ exception(error, undef, Bs0, Ieval, true)
end.
lambda(eval_fun, [Cs,As,Bs,{Mod,Name}=F]) ->
@@ -580,7 +588,7 @@ fnk_clauses([{clause,Line,Pars,Gs,Body}|Cs], M, F, As, Bs0, Ieval) ->
fnk_clauses(Cs, M, F, As, Bs0, Ieval)
end;
fnk_clauses([], _M, _F, _As, Bs, Ieval) ->
- exception(error, function_clause, Bs, Ieval).
+ exception(error, function_clause, Bs, Ieval, true).
seq([E], Bs0, Ieval) ->
case dbg_icmd:cmd(E, Bs0, Ieval) of
@@ -1013,7 +1021,7 @@ safe_bif(M, F, As, Bs, Ieval) ->
{value,Value,Bs}
catch
Class:Reason ->
- exception(Class, Reason, Bs, Ieval)
+ exception(Class, Reason, Bs, Ieval, true)
end.
eval_send(To, Msg, Bs, Ieval) ->
diff --git a/lib/debugger/src/dbg_istk.erl b/lib/debugger/src/dbg_istk.erl
index 2c4c2a3518..34070aa8f2 100644
--- a/lib/debugger/src/dbg_istk.erl
+++ b/lib/debugger/src/dbg_istk.erl
@@ -19,7 +19,7 @@
-module(dbg_istk).
-export([init/0,to_external/0,from_external/1,
push/2,pop/0,pop/1,stack_level/0,
- delayed_stacktrace/0,delayed_stacktrace/1,
+ delayed_stacktrace/0,delayed_stacktrace/2,
bindings/1,stack_frame/2,backtrace/2,
in_use_p/2]).
@@ -107,60 +107,55 @@ stack_level([]) -> 1;
stack_level([#e{level=Le}|_]) -> Le.
%% delayed_stacktrace() -> CreateStacktraceFun
-%% delayed_stacktrace(#ieval{}) -> CreateStacktraceFun
+%% delayed_stacktrace(ArgFlag, #ieval{}) -> CreateStacktraceFun
+%% ArgFlag = no_args | include_args
%% CreateStacktraceFun = fun(NumberOfEntries)
%%
%% Return a fun that can convert the internal stack format to
%% an imitation of the regular stacktrace.
-%%
-%% Max three elements, no repeated (recursive) calls to the same
-%% function and convert argument lists to arity for all but the topmost
-%% entry (and funs).
delayed_stacktrace() ->
- Stack = get(?STACK),
- do_delayed_stacktrace(Stack).
+ Stack0 = get(?STACK),
+ fun(NumEntries) ->
+ Stack = stacktrace(NumEntries, Stack0, []),
+ [ArityOnly || {ArityOnly,_} <- Stack]
+ end.
-delayed_stacktrace(Ieval) ->
+delayed_stacktrace(include_args, Ieval) ->
#ieval{module=Mod,function=Name,arguments=As} = Ieval,
- Stack = [#e{mfa={Mod,Name,As}}|get(?STACK)],
- do_delayed_stacktrace(Stack).
-
-do_delayed_stacktrace(Stack) ->
- fun(_NumEntries) ->
- fix_stacktrace(Stack)
+ Stack0 = [#e{mfa={Mod,Name,As}}|get(?STACK)],
+ fun(NumEntries) ->
+ case stacktrace(NumEntries, Stack0, []) of
+ [] ->
+ [];
+ [{_,WithArgs}|Stack] ->
+ [WithArgs | [ArityOnly || {ArityOnly,_} <- Stack]]
+ end
+ end;
+delayed_stacktrace(no_args, Ieval) ->
+ #ieval{module=Mod,function=Name,arguments=As} = Ieval,
+ Stack0 = [#e{mfa={Mod,Name,As}}|get(?STACK)],
+ fun(NumEntries) ->
+ Stack = stacktrace(NumEntries, Stack0, []),
+ [ArityOnly || {ArityOnly,_} <- Stack]
end.
-fix_stacktrace(Stack) ->
- case fix_stacktrace2(sublist(Stack, 1, 3)) of
- [] ->
- [];
- [H|T] ->
- [H|args2arity(T)]
- end.
+stacktrace(N, [E|T], []) ->
+ stacktrace(N-1, T, [normalize(E)]);
+stacktrace(N, [E|T], [{P,_}|_]=Acc) when N > 0 ->
+ case normalize(E) of
+ {P,_} ->
+ stacktrace(N, T, Acc);
+ New ->
+ stacktrace(N-1, T, [New|Acc])
+ end;
+stacktrace(_, _, Acc) ->
+ lists:reverse(Acc).
-sublist([], _Start, _Length) ->
- []; % workaround, lists:sublist([],2,3) fails
-sublist(L, Start, Length) ->
- lists:sublist(L, Start, Length).
-
-fix_stacktrace2([#e{mfa={M,F,As1}}, #e{mfa={M,F,As2}}|_])
- when length(As1) =:= length(As2) ->
- [{M,F,As1}];
-fix_stacktrace2([#e{mfa={Fun,As1}}, #e{mfa={Fun,As2}}|_])
- when length(As1) =:= length(As2) ->
- [{Fun,As1}];
-fix_stacktrace2([#e{mfa=MFA}|Entries]) ->
- [MFA|fix_stacktrace2(Entries)];
-fix_stacktrace2([]) ->
- [].
-
-args2arity([{M,F,As}|Entries]) when is_list(As) ->
- [{M,F,length(As)}|args2arity(Entries)];
-args2arity([Entry|Entries]) ->
- [Entry|args2arity(Entries)];
-args2arity([]) ->
- [].
+normalize(#e{mfa={_,Fun,As}}) when is_function(Fun) ->
+ {{Fun,length(As)},{Fun,As}};
+normalize(#e{mfa={M,F,As}}) ->
+ {{M,F,length(As)},{M,F,As}}.
%% bindings(SP) -> Bs
%% SP = Le % stack pointer