diff options
Diffstat (limited to 'lib/debugger')
-rw-r--r-- | lib/debugger/src/dbg_ieval.erl | 24 | ||||
-rw-r--r-- | lib/debugger/src/dbg_istk.erl | 83 |
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 |