aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debugger')
-rw-r--r--lib/debugger/src/dbg_icmd.erl4
-rw-r--r--lib/debugger/src/dbg_ieval.erl61
-rw-r--r--lib/debugger/src/dbg_istk.erl49
3 files changed, 58 insertions, 56 deletions
diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl
index c158aad1cf..b230efaa7a 100644
--- a/lib/debugger/src/dbg_icmd.erl
+++ b/lib/debugger/src/dbg_icmd.erl
@@ -345,8 +345,8 @@ handle_user_msg({get,stack_frame,From,{Dir,SP}}, _Status, _Bs,_Ieval) ->
reply(From, stack_frame, dbg_istk:stack_frame(Dir, SP));
handle_user_msg({get,messages,From,_}, _Status, _Bs, _Ieval) ->
reply(From, messages, messages());
-handle_user_msg({get,backtrace,From,N}, _Status, _Bs, _Ieval) ->
- reply(From, backtrace, dbg_istk:backtrace(N)).
+handle_user_msg({get,backtrace,From,N}, _Status, _Bs, Ieval) ->
+ reply(From, backtrace, dbg_istk:backtrace(N, Ieval)).
set_stack_trace(true) ->
set_stack_trace(all);
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index e343e6f1e0..445eba3346 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -382,10 +382,11 @@ catch_value(throw, Reason) ->
%% Top level function of meta evaluator.
%% Return message to be replied to the target process.
%%--------------------------------------------------------------------
-eval_mfa(Debugged, M, F, As, Ieval) ->
+eval_mfa(Debugged, M, F, As, #ieval{level=Le}=Ieval0) ->
Int = get(int),
Bs = erl_eval:new_bindings(),
- try eval_function(M,F,As,Bs,extern,Ieval#ieval{top=true}) of
+ Ieval = Ieval0#ieval{level=Le+1,top=true},
+ try do_eval_function(M, F, As, Bs, extern, Ieval) of
{value, Val, _Bs} ->
{ready, Val}
catch
@@ -397,18 +398,21 @@ eval_mfa(Debugged, M, F, As, Ieval) ->
{exception, {Class, Reason, get(stacktrace)}}
end.
-eval_function(Mod, Fun, As0, Bs0, _Called, Ieval) when is_function(Fun);
- Mod =:= ?MODULE,
- Fun =:= eval_fun ->
+eval_function(Mod, Name, As, Bs, Called, Ieval0) ->
+ Ieval = dbg_istk:push(Bs, Ieval0),
+ Res = do_eval_function(Mod, Name, As, Bs, Called, Ieval),
+ dbg_istk:pop(),
+ Res.
+
+do_eval_function(Mod, Fun, As0, Bs0, _, Ieval) when is_function(Fun);
+ Mod =:= ?MODULE,
+ Fun =:= eval_fun ->
#ieval{level=Le, line=Li, top=Top} = Ieval,
case lambda(Fun, As0) of
{Cs,Module,Name,As,Bs} ->
- dbg_istk:push({Module,Name,As}, Bs0, Ieval),
trace(call_fun, {Le,Li,Name,As}),
{value, Val, _Bs} =
- fnk_clauses(Cs, Module, Name, As, Bs,
- Ieval#ieval{level=Le+1}),
- dbg_istk:pop(),
+ fnk_clauses(Cs, Module, Name, As, Bs, Ieval),
trace(return, {Le,Val}),
{value, Val, Bs0};
@@ -416,12 +420,9 @@ eval_function(Mod, Fun, As0, Bs0, _Called, Ieval) when is_function(Fun);
trace(call_fun, {Le,Li,Fun,As0}),
{value, {dbg_apply,erlang,apply,[Fun,As0]}, Bs0};
not_interpreted ->
- dbg_istk:push({Fun,As0}, Bs0, Ieval),
trace(call_fun, {Le,Li,Fun,As0}),
{value, Val, _Bs} =
- debugged_cmd({apply,erlang,apply,[Fun,As0]},Bs0,
- Ieval#ieval{level=Le+1}),
- dbg_istk:pop(),
+ debugged_cmd({apply,erlang,apply,[Fun,As0]}, Bs0, Ieval),
trace(return, {Le,Val}),
{value, Val, Bs0};
@@ -433,22 +434,19 @@ eval_function(Mod, Fun, As0, Bs0, _Called, Ieval) when is_function(Fun);
end;
%% Common Test adaptation
-eval_function(ct_line, line, As, Bs, extern, #ieval{level=Le}=Ieval) ->
+do_eval_function(ct_line, line, As, Bs, extern, #ieval{level=Le}=Ieval) ->
debugged_cmd({apply,ct_line,line,As}, Bs, Ieval#ieval{level=Le+1}),
{value, ignore, Bs};
-eval_function(Mod, Name, As0, Bs0, Called, Ieval) ->
- #ieval{level=Le, line=Li, top=Top} = Ieval,
-
- dbg_istk:push({Mod,Name,As0}, Bs0, Ieval),
+do_eval_function(Mod, Name, As0, Bs0, Called, Ieval0) ->
+ #ieval{level=Le,line=Li,top=Top} = Ieval0,
trace(call, {Called, {Le,Li,Mod,Name,As0}}),
-
+ Ieval = Ieval0#ieval{module=Mod,function=Name,arguments=As0},
case get_function(Mod, Name, As0, Called) of
Cs when is_list(Cs) ->
{value, Val, _Bs} =
fnk_clauses(Cs, Mod, Name, As0, erl_eval:new_bindings(),
- Ieval#ieval{level=Le+1}),
- dbg_istk:pop(),
+ Ieval),
trace(return, {Le,Val}),
{value, Val, Bs0};
@@ -456,9 +454,7 @@ eval_function(Mod, Name, As0, Bs0, Called, Ieval) ->
{value, {dbg_apply,Mod,Name,As0}, Bs0};
not_interpreted ->
{value, Val, _Bs} =
- debugged_cmd({apply,Mod,Name,As0}, Bs0,
- Ieval#ieval{level=Le+1}),
- dbg_istk:pop(),
+ debugged_cmd({apply,Mod,Name,As0}, Bs0, Ieval),
trace(return, {Le,Val}),
{value, Val, Bs0};
@@ -807,10 +803,11 @@ expr({dbg,Line,exit,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
%% Call to "safe" BIF, ie a BIF that can be executed in Meta process
expr({safe_bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
- Ieval = Ieval0#ieval{line=Line},
- {As,Bs} = eval_list(As0, Bs0, Ieval),
+ Ieval1 = Ieval0#ieval{line=Line},
+ {As,Bs} = eval_list(As0, Bs0, Ieval1),
trace(bif, {Le,Line,M,F,As}),
- dbg_istk:push({M,F,As}, Bs0, Ieval),
+ Ieval2 = dbg_istk:push(Bs0, Ieval1),
+ Ieval = Ieval2#ieval{module=M,function=F,arguments=As},
{_,Value,_} = Res = safe_bif(M, F, As, Bs, Ieval),
trace(return, {Le,Value}),
dbg_istk:pop(),
@@ -818,12 +815,12 @@ expr({safe_bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
%% Call to a BIF that must be evaluated in the correct process
expr({bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
- Ieval = Ieval0#ieval{line=Line},
- {As,Bs} = eval_list(As0, Bs0, Ieval),
+ Ieval1 = Ieval0#ieval{line=Line},
+ {As,Bs} = eval_list(As0, Bs0, Ieval1),
trace(bif, {Le,Line,M,F,As}),
- dbg_istk:push({M,F,As}, Bs0, Ieval),
- {_,Value,_} =
- Res = debugged_cmd({apply,M,F,As}, Bs, Ieval#ieval{level=Le+1}),
+ Ieval2 = dbg_istk:push(Bs0, Ieval1),
+ Ieval = Ieval2#ieval{module=M,function=F,arguments=As},
+ {_,Value,_} = Res = debugged_cmd({apply,M,F,As}, Bs, Ieval),
trace(return, {Le,Value}),
dbg_istk:pop(),
Res;
diff --git a/lib/debugger/src/dbg_istk.erl b/lib/debugger/src/dbg_istk.erl
index b852e1f8fd..2e7b114fab 100644
--- a/lib/debugger/src/dbg_istk.erl
+++ b/lib/debugger/src/dbg_istk.erl
@@ -18,9 +18,9 @@
%%
-module(dbg_istk).
-export([init/0,to_external/0,from_external/1,
- push/3,pop/0,pop/1,stack_level/0,
+ push/2,pop/0,pop/1,stack_level/0,
exception_stacktrace/2,
- bindings/1,stack_frame/2,backtrace/1,
+ bindings/1,stack_frame/2,backtrace/2,
in_use_p/2]).
-include("dbg_ieval.hrl").
@@ -30,7 +30,6 @@
-record(e,
{level, %Level
mfa, %{Mod,Func,Args|Arity}|{Fun,Args}
- cm, %Module called from
line, %Line called from
bindings
}).
@@ -61,17 +60,17 @@ init(Stack) ->
%% false - nothing is pushed
%% Whenever a function returns, the corresponding call frame is popped.
-push(MFA, Bs, #ieval{level=Le,module=Cm,line=Li,top=Lc}) ->
- Entry = #e{level=Le,mfa=MFA,cm=Cm,line=Li,bindings=Bs},
+push(Bs, #ieval{level=Le,module=Mod,function=Name,arguments=As,
+ line=Li,top=Lc}=Ieval) ->
+ Entry = #e{level=Le,mfa={Mod,Name,As},line=Li,bindings=Bs},
case get(trace_stack) of
- false -> ignore;
+ false ->
+ Ieval#ieval{level=Le+1};
no_tail when Lc ->
- case get(?STACK) of
- [] -> put(?STACK, [Entry]);
- [_Entry|Entries] -> put(?STACK, [Entry|Entries])
- end;
+ Ieval;
_ -> % all | no_tail when Lc =:= false
- put(?STACK, [Entry|get(?STACK)])
+ put(?STACK, [Entry|get(?STACK)]),
+ Ieval#ieval{level=Le+1}
end.
pop() ->
@@ -117,13 +116,15 @@ stack_level([#e{level=Le}|_]) -> Le.
%% function and convert argument lists to arity for all but the topmost
%% entry (and funs).
-exception_stacktrace(complete, #ieval{}) ->
- fix_stacktrace(1);
+exception_stacktrace(complete, #ieval{}=Ieval) ->
+ #ieval{module=Mod,function=Name,arguments=As} = Ieval,
+ Stk = [#e{mfa={Mod,Name,As}}|get(?STACK)],
+ fix_stacktrace(Stk);
exception_stacktrace(no_current, #ieval{}) ->
- fix_stacktrace(2).
+ fix_stacktrace(get(?STACK)).
-fix_stacktrace(Start) ->
- case fix_stacktrace2(sublist(get(?STACK), Start, 3)) of
+fix_stacktrace(Stk) ->
+ case fix_stacktrace2(sublist(Stk, 1, 3)) of
[] ->
[];
[H|T] ->
@@ -180,13 +181,15 @@ stack_frame(up, SP) ->
stack_frame(down, SP) ->
stack_frame(SP, down, lists:reverse(get(?STACK))).
-stack_frame(SP, up, [#e{level=Le,cm=Cm,line=Li,bindings=Bs}|_]) when Le < SP ->
+stack_frame(SP, up, [#e{level=Le,mfa={Cm,_,_},line=Li,bindings=Bs}|_])
+ when Le < SP ->
{Le,{Cm,Li},Bs};
-stack_frame(SP, down, [#e{level=Le,cm=Cm,line=Li,bindings=Bs}|_]) when Le > SP ->
+stack_frame(SP, down, [#e{level=Le,mfa={Cm,_,_},line=Li,bindings=Bs}|_])
+ when Le > SP ->
{Le,{Cm,Li},Bs};
stack_frame(SP, Dir, [#e{level=SP}|Stack]) ->
case Stack of
- [#e{level=Le,cm=Cm,line=Li,bindings=Bs}|_] ->
+ [#e{level=Le,mfa={Cm,_,_},line=Li,bindings=Bs}|_] ->
{Le,{Cm,Li},Bs};
[] when Dir =:= up ->
top;
@@ -200,10 +203,12 @@ stack_frame(SP, Dir, [_Entry|Stack]) ->
%% HowMany = all | int()
%% Backtrace = {Le, MFA}
%% Return all/the last N called functions, in reversed call order
-backtrace(HowMany) ->
+backtrace(HowMany, Ieval) ->
+ #ieval{level=Level,module=Mod,function=Name,arguments=As} = Ieval,
+ Stack0 = [#e{level=Level,mfa={Mod,Name,As}}|get(?STACK)],
Stack = case HowMany of
- all -> get(?STACK);
- N -> lists:sublist(get(?STACK), N)
+ all -> Stack0;
+ N -> lists:sublist(Stack0, N)
end,
[{Le,MFA} || #e{level=Le,mfa=MFA} <- Stack].