From 32c1c7e5de9240eedd421f81f84c5469e6a5d0da Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Fri, 31 Mar 2017 16:41:48 +0200 Subject: debugger: Improve handling of pids, ports, and refs The extended parser is used by the debugger for handling pids, ports, references, and external funs in the evaluator area and in the bindings area. Notice that pids, ports, references, and external funs that cannot be created in the currently running are ignored (as before). --- lib/debugger/src/dbg_icmd.erl | 44 +++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'lib/debugger/src/dbg_icmd.erl') diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl index 57a3719a50..4cd3dce670 100644 --- a/lib/debugger/src/dbg_icmd.erl +++ b/lib/debugger/src/dbg_icmd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2016. All Rights Reserved. +%% Copyright Ericsson AB 1998-2017. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -382,14 +382,19 @@ eval_restricted({From,_Mod,Cmd,SP}, Bs) -> case catch parse_cmd(Cmd, 1) of {'EXIT', _Reason} -> From ! {self(), {eval_rsp, 'Parse error'}}; - [{var,_,Var}] -> + {[{var,_,Var}], XBs} -> Bs2 = bindings(Bs, SP), Res = case get_binding(Var, Bs2) of {value, Value} -> Value; - unbound -> unbound + unbound -> + case get_binding(Var, XBs) of + {value, _} -> + 'Only possible to inspect variables'; + unbound -> unbound + end end, From ! {self(), {eval_rsp, Res}}; - _Forms -> + {_Forms, _XBs} -> Rsp = 'Only possible to inspect variables', From ! {self(), {eval_rsp, Rsp}} end. @@ -404,22 +409,22 @@ eval_nonrestricted({From, _Mod, Cmd, _SP}, Bs, {'EXIT', _Reason} -> From ! {self(), {eval_rsp, 'Parse error'}}, Bs; - Forms -> + {Forms, XBs} -> mark_running(Line, Le), + Bs1 = merge_bindings(Bs, XBs), {Res, Bs2} = lists:foldl(fun(Expr, {_Res, Bs0}) -> eval_nonrestricted_1(Expr,Bs0,Ieval) end, - {null, Bs}, + {null, Bs1}, Forms), mark_break(M, Line, Le), From ! {self(), {eval_rsp, Res}}, - Bs2 + remove_binding_structs(Bs2, XBs) end. eval_nonrestricted_1({match,_,{var,_,Var},Expr}, Bs, Ieval) -> - {value,Res,Bs2} = - dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{top=false}), + {Res,Bs2} = eval_expr(Expr, Bs, Ieval), Bs3 = case lists:keyfind(Var, 1, Bs) of {Var,_Value} -> lists:keyreplace(Var, 1, Bs2, {Var,Res}); @@ -433,10 +438,21 @@ eval_nonrestricted_1({var,_,Var}, Bs, _Ieval) -> end, {Res,Bs}; eval_nonrestricted_1(Expr, Bs, Ieval) -> - {value,Res,Bs2} = - dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{top=false}), + eval_expr(Expr, Bs, Ieval). + +eval_expr(Expr, Bs, Ieval) -> + {value,Res,Bs2} = + dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{top=false}), {Res,Bs2}. +%% XBs have unique keys. +merge_bindings(Bs1, XBs) -> + Bs1 ++ erl_eval:bindings(XBs). + +remove_binding_structs(Bs1, XBs) -> + lists:foldl(fun({N, _V}, Bs) -> lists:keydelete(N, 1, Bs) + end, Bs1, erl_eval:bindings(XBs)). + mark_running(LineNo, Le) -> put(next_break, running), put(user_eval, [{LineNo, Le} | get(user_eval)]), @@ -450,9 +466,9 @@ mark_break(Cm, LineNo, Le) -> dbg_iserver:cast(get(int), {set_status,self(),break,{Cm,LineNo}}). parse_cmd(Cmd, LineNo) -> - {ok,Tokens,_} = erl_scan:string(Cmd, LineNo), - {ok,Forms} = erl_parse:parse_exprs(Tokens), - Forms. + {ok,Tokens,_} = erl_scan:string(Cmd, LineNo, [text]), + {ok,Forms,Bs} = lib:extended_parse_exprs(Tokens), + {Forms, Bs}. %%==================================================================== %% Library functions for attached process handling -- cgit v1.2.3