diff options
author | Sverker Eriksson <[email protected]> | 2017-08-30 21:00:35 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2017-08-30 21:00:35 +0200 |
commit | 44a83c8860bbd00878c720a7b9d940b4630bab8a (patch) | |
tree | 101b3c52ec505a94f56c8f70e078ecb8a2e8c6cd /lib/debugger | |
parent | 7c67bbddb53c364086f66260701bc54a61c9659c (diff) | |
parent | 040bdce67f88d833bfb59adae130a4ffb4c180f0 (diff) | |
download | otp-44a83c8860bbd00878c720a7b9d940b4630bab8a.tar.gz otp-44a83c8860bbd00878c720a7b9d940b4630bab8a.tar.bz2 otp-44a83c8860bbd00878c720a7b9d940b4630bab8a.zip |
Merge tag 'OTP-20.0' into sverker/20/binary_to_atom-utf8-crash/ERL-474/OTP-14590
Diffstat (limited to 'lib/debugger')
-rw-r--r-- | lib/debugger/doc/src/Makefile | 2 | ||||
-rw-r--r-- | lib/debugger/doc/src/debugger_chapter.xml | 8 | ||||
-rw-r--r-- | lib/debugger/doc/src/i.xml | 4 | ||||
-rw-r--r-- | lib/debugger/doc/src/notes.xml | 61 | ||||
-rw-r--r-- | lib/debugger/src/Makefile | 2 | ||||
-rw-r--r-- | lib/debugger/src/dbg_icmd.erl | 44 | ||||
-rw-r--r-- | lib/debugger/src/dbg_ieval.erl | 3 | ||||
-rw-r--r-- | lib/debugger/src/dbg_iload.erl | 157 | ||||
-rw-r--r-- | lib/debugger/src/dbg_iserver.erl | 40 | ||||
-rw-r--r-- | lib/debugger/src/dbg_wx_code.erl | 4 | ||||
-rw-r--r-- | lib/debugger/src/dbg_wx_src_view.erl | 4 | ||||
-rw-r--r-- | lib/debugger/src/dbg_wx_trace.erl | 18 | ||||
-rw-r--r-- | lib/debugger/src/dbg_wx_view.erl | 12 | ||||
-rw-r--r-- | lib/debugger/src/dbg_wx_win.erl | 7 | ||||
-rw-r--r-- | lib/debugger/src/int.erl | 6 | ||||
-rw-r--r-- | lib/debugger/test/Makefile | 1 | ||||
-rw-r--r-- | lib/debugger/test/andor_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/debugger/test/bs_bincomp_SUITE.erl | 1 | ||||
-rw-r--r-- | lib/debugger/test/int_SUITE.erl | 5 | ||||
-rw-r--r-- | lib/debugger/test/map_SUITE.erl | 22 | ||||
-rw-r--r-- | lib/debugger/test/overridden_bif_SUITE.erl | 99 | ||||
-rw-r--r-- | lib/debugger/test/test_lib.erl | 7 | ||||
-rw-r--r-- | lib/debugger/vsn.mk | 2 |
23 files changed, 374 insertions, 137 deletions
diff --git a/lib/debugger/doc/src/Makefile b/lib/debugger/doc/src/Makefile index 6c9617ca69..0f724b6f17 100644 --- a/lib/debugger/doc/src/Makefile +++ b/lib/debugger/doc/src/Makefile @@ -114,7 +114,7 @@ release_docs_spec: docs $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" - (/bin/cp -rf $(HTMLDIR) "$(RELSYSDIR)/doc") + ($(CP) -rf $(HTMLDIR) "$(RELSYSDIR)/doc") $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" diff --git a/lib/debugger/doc/src/debugger_chapter.xml b/lib/debugger/doc/src/debugger_chapter.xml index 45dfdb3776..3c37d4b924 100644 --- a/lib/debugger/doc/src/debugger_chapter.xml +++ b/lib/debugger/doc/src/debugger_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2016</year> + <year>1997</year><year>2017</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -652,8 +652,10 @@ c_break(Bindings) -> <item><p>The Bindings area, displaying all variables bindings. If you click a variable name, the value is displayed in the Evaluator area. Double-click a variable name to open a window where - the variable value can be edited. Notice however that pid, - reference, binary, or port values cannot be edited.</p> + the variable value can be edited. Notice however that pid, port, + reference, or fun + values cannot be edited unless they can be represented in the + running system.</p> </item> <item><p>The Trace area, which displays a trace output for the diff --git a/lib/debugger/doc/src/i.xml b/lib/debugger/doc/src/i.xml index db89f23494..628b91e9e4 100644 --- a/lib/debugger/doc/src/i.xml +++ b/lib/debugger/doc/src/i.xml @@ -45,7 +45,7 @@ attached manually or automatically.</p> <p>By preference, these functions can be included in module - <seealso marker="stdlib:shell_default"><c>stdlib:shell_default</c></seealso>. + <seealso marker="stdlib:shell_default"><c>shell_default</c></seealso>. By default, they are included in that module.</p> </description> @@ -372,7 +372,7 @@ </fsummary> <desc> <p>Returns the current version number of the interpreter. - Same as the version number of the <c>Debugger</c> application.</p> + Same as the version number of the Debugger application.</p> </desc> </func> diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml index 2e0d834269..fa85567a84 100644 --- a/lib/debugger/doc/src/notes.xml +++ b/lib/debugger/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2004</year><year>2016</year> + <year>2004</year><year>2017</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -33,6 +33,65 @@ <p>This document describes the changes made to the Debugger application.</p> +<section><title>Debugger 4.2.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> The Erlang shell, <c>qlc:string_to_handle()</c>, and + the Debugger (the Evaluator area and Edit variable window + of the Bindings area) can parse pids, ports, references, + and external funs, as long as they can be created in the + running system. </p> + <p> + Own Id: OTP-14296</p> + </item> + <item> + <p> Fix editing of simple binary values in the Bindings + area of the Debugger's Attach Process Window. </p> + <p> + Own Id: OTP-14318</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> Miscellaneous updates due to atoms containing + arbitrary Unicode characters. </p> + <p> + Own Id: OTP-14285</p> + </item> + </list> + </section> + +</section> + +<section><title>Debugger 4.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Update build scripts to not make assumtions about where + env, cp and perl are located.</p> + <p> + Own Id: OTP-13800</p> + </item> + <item> + <p> + A bug causing non-interpreted code to crash the debugger + has been fixed.</p> + <p> + Own Id: OTP-13756</p> + </item> + </list> + </section> + +</section> + <section><title>Debugger 4.2</title> <section><title>Improvements and New Features</title> diff --git a/lib/debugger/src/Makefile b/lib/debugger/src/Makefile index 9594a0bfe3..118cb6b758 100644 --- a/lib/debugger/src/Makefile +++ b/lib/debugger/src/Makefile @@ -85,7 +85,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE) # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_COMPILE_FLAGS += +warn_obsolete_guard -Werror +ERL_COMPILE_FLAGS += -Werror # ---------------------------------------------------- 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 diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl index f5e079ef7e..88c7caacb0 100644 --- a/lib/debugger/src/dbg_ieval.erl +++ b/lib/debugger/src/dbg_ieval.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. @@ -1486,7 +1486,6 @@ guard_expr({map,_,E0,Fs0}, Bs) -> Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi); ({map_exact,K,V}, Mi) -> maps:update(K,V,Mi) end, E, Fs), - io:format("~p~n", [{E,Value}]), {value,Value}; guard_expr({bin,_,Flds}, Bs) -> {value,V,_Bs} = diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl index 369b456524..468f6a809f 100644 --- a/lib/debugger/src/dbg_iload.erl +++ b/lib/debugger/src/dbg_iload.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2015. 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. @@ -72,8 +72,7 @@ store_module(Mod, File, Binary, Db) -> exit({Mod,too_old_beam_file}); {raw_abstract_v1,Code0} -> Code = interpret_file_attribute(Code0), - {_,_,Forms0,_} = sys_pre_expand:module(Code, []), - Forms0 + standard_transforms(Code) end, dbg_idb:insert(Db, mod_file, File), dbg_idb:insert(Db, defs, []), @@ -94,6 +93,11 @@ store_module(Mod, File, Binary, Db) -> dbg_idb:insert(Db, mod_bin, NewBinary), dbg_idb:insert(Db, mod_raw, <<Src/binary,0:8>>). %% Add eos +standard_transforms(Forms0) -> + Forms = erl_expand_records:module(Forms0, []), + erl_internal:add_predefined_functions(Forms). + + %% Adjust line numbers using the file/2 attribute. %% Also take the absolute value of line numbers. %% This simple fix will make the marker point at the correct line @@ -102,7 +106,6 @@ store_module(Mod, File, Binary, Db) -> interpret_file_attribute(Code) -> epp:interpret_file_attribute(Code). - abstr(Bin) when is_binary(Bin) -> binary_to_term(Bin); abstr(Term) -> Term. @@ -124,8 +127,9 @@ store_forms([{function,_,Name,Arity,Cs0}|Fs], Mod, Db, Exp) -> store_forms(Fs, Mod, Db, Exp); store_forms([{attribute,_,_Name,_Val}|Fs], Mod, Db, Exp) -> store_forms(Fs, Mod, Db, Exp); -store_forms([F|_], _Mod, _Db, _Exp) -> - exit({unknown_form,F}); +store_forms([_|Fs], Mod, Db, Exp) -> + %% Ignore other forms such as {eof,_} or {warning,_}. + store_forms(Fs, Mod, Db, Exp); store_forms([], _, _, _) -> ok. @@ -216,12 +220,36 @@ pattern({op,_,'-',{float,Anno,I}}) -> pattern({op,_,'+',{float,Anno,I}}) -> {value,ln(Anno),I}; pattern({bin,Anno,Grp}) -> - Grp1 = pattern_list(Grp), + Grp1 = pattern_list(bin_expand_strings(Grp)), {bin,ln(Anno),Grp1}; -pattern({bin_element,Anno,Expr,Size,Type}) -> - Expr1 = pattern(Expr), - Size1 = expr(Size, false), - {bin_element,ln(Anno),Expr1,Size1,Type}. +pattern({bin_element,Anno,Expr0,Size0,Type0}) -> + {Size1,Type} = make_bit_type(Anno, Size0, Type0), + Expr1 = pattern(Expr0), + Expr = coerce_to_float(Expr1, Type0), + Size = pattern(Size1), + {bin_element,ln(Anno),Expr,Size,Type}; +%% Evaluate compile-time expressions. +pattern({op,_,'++',{nil,_},R}) -> + pattern(R); +pattern({op,_,'++',{cons,Li,H,T},R}) -> + pattern({cons,Li,H,{op,Li,'++',T,R}}); +pattern({op,_,'++',{string,Li,L},R}) -> + pattern(string_to_conses(Li, L, R)); +pattern({op,_Line,_Op,_A}=Op) -> + pattern(erl_eval:partial_eval(Op)); +pattern({op,_Line,_Op,_L,_R}=Op) -> + pattern(erl_eval:partial_eval(Op)). + +string_to_conses(Anno, Cs, Tail) -> + lists:foldr(fun (C, T) -> {cons,Anno,{char,Anno,C},T} end, Tail, Cs). + +coerce_to_float({value,Anno,Int}=E, [float|_]) when is_integer(Int) -> + try + {value,Anno,float(Int)} + catch + error:badarg -> E + end; +coerce_to_float(E, _) -> E. %% These patterns are processed "in parallel" for purposes of variable %% definition etc. @@ -297,13 +325,14 @@ gexpr({map,Anno,E0,Fs0}) -> Fs1 = map_fields(Fs0, fun gexpr/1), {map,ln(Anno),E1,Fs1}; gexpr({bin,Anno,Flds0}) -> - Flds = gexpr_list(Flds0), + Flds = gexpr_list(bin_expand_strings(Flds0)), {bin,ln(Anno),Flds}; -gexpr({bin_element,Anno,Expr0,Size0,Type}) -> +gexpr({bin_element,Anno,Expr0,Size0,Type0}) -> + {Size1,Type} = make_bit_type(Anno, Size0, Type0), Expr = gexpr(Expr0), - Size = gexpr(Size0), + Size = gexpr(Size1), {bin_element,ln(Anno),Expr,Size,Type}; -%%% The previous passes have added the module name 'erlang' to +%%% The erl_expand_records pass has added the module name 'erlang' to %%% all BIF calls, even in guards. gexpr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,self}},[]}) -> {dbg,ln(Anno),self,[]}; @@ -383,18 +412,21 @@ expr({'receive',Anno,Cs0,To0,ToEs0}, Lc) -> ToEs1 = exprs(ToEs0, Lc), Cs1 = icr_clauses(Cs0, Lc), {'receive',ln(Anno),Cs1,To1,ToEs1}; -expr({'fun',Anno,{clauses,Cs0},{_,_,Name}}, _Lc) when is_atom(Name) -> +expr({'fun',Anno,{clauses,Cs0}}, _Lc) -> %% New R10B-2 format (abstract_v2). Cs = fun_clauses(Cs0), + Name = new_fun_name(), {make_fun,ln(Anno),Name,Cs}; -expr({'fun',Anno,{function,F,A},{_Index,_OldUniq,Name}}, _Lc) -> +expr({'fun',Anno,{function,F,A}}, _Lc) -> %% New R8 format (abstract_v2). Line = ln(Anno), As = new_vars(A, Line), + Name = new_fun_name(), Cs = [{clause,Line,As,[],[{local_call,Line,F,As,true}]}], {make_fun,Line,Name,Cs}; -expr({named_fun,Anno,FName,Cs0,{_,_,Name}}, _Lc) when is_atom(Name) -> +expr({named_fun,Anno,FName,Cs0}, _Lc) -> Cs = fun_clauses(Cs0), + Name = new_fun_name(), {make_named_fun,ln(Anno),Name,FName,Cs}; expr({'fun',Anno,{function,{atom,_,M},{atom,_,F},{integer,_,A}}}, _Lc) when 0 =< A, A =< 255 -> @@ -454,30 +486,10 @@ expr({'try',Anno,Es0,CaseCs0,CatchCs0,As0}, Lc) -> CatchCs = icr_clauses(CatchCs0, Lc), As = expr_list(As0), {'try',ln(Anno),Es,CaseCs,CatchCs,As}; -expr({lc,Anno,E0,Gs0}, _Lc) -> %R8. - Gs = lists:map(fun ({generate,L,P0,Qs}) -> - {generate,L,pattern(P0),expr(Qs, false)}; - ({b_generate,L,P0,Qs}) -> %R12. - {b_generate,L,pattern(P0),expr(Qs, false)}; - (Expr) -> - case erl_lint:is_guard_test(Expr) of - true -> {guard,guard([[Expr]])}; - false -> expr(Expr, false) - end - end, Gs0), - {lc,ln(Anno),expr(E0, false),Gs}; -expr({bc,Anno,E0,Gs0}, _Lc) -> %R12. - Gs = lists:map(fun ({generate,L,P0,Qs}) -> - {generate,L,pattern(P0),expr(Qs, false)}; - ({b_generate,L,P0,Qs}) -> %R12. - {b_generate,L,pattern(P0),expr(Qs, false)}; - (Expr) -> - case erl_lint:is_guard_test(Expr) of - true -> {guard,guard([[Expr]])}; - false -> expr(Expr, false) - end - end, Gs0), - {bc,ln(Anno),expr(E0, false),Gs}; +expr({lc,_,_,_}=Compr, _Lc) -> + expr_lc_bc(Compr); +expr({bc,_,_,_}=Compr, _Lc) -> + expr_lc_bc(Compr); expr({match,Anno,P0,E0}, _Lc) -> E1 = expr(E0, false), P1 = pattern(P0), @@ -506,19 +518,58 @@ expr({op,Anno,Op,L0,R0}, _Lc) -> R1 = expr(R0, false), %They see the same variables {op,ln(Anno),Op,[L1,R1]}; expr({bin,Anno,Grp}, _Lc) -> - Grp1 = expr_list(Grp), + Grp1 = expr_list(bin_expand_strings(Grp)), {bin,ln(Anno),Grp1}; -expr({bin_element,Anno,Expr,Size,Type}, _Lc) -> - Expr1 = expr(Expr, false), - Size1 = expr(Size, false), - {bin_element,ln(Anno),Expr1,Size1,Type}; -expr(Other, _Lc) -> - exit({?MODULE,{unknown_expr,Other}}). +expr({bin_element,Anno,Expr0,Size0,Type0}, _Lc) -> + {Size1,Type} = make_bit_type(Anno, Size0, Type0), + Expr = expr(Expr0, false), + Size = expr(Size1, false), + {bin_element,ln(Anno),Expr,Size,Type}. consify([A|As]) -> {cons,0,A,consify(As)}; consify([]) -> {value,0,[]}. +make_bit_type(Line, default, Type0) -> + case erl_bits:set_bit_type(default, Type0) of + {ok,all,Bt} -> {{atom,Line,all},erl_bits:as_list(Bt)}; + {ok,undefined,Bt} -> {{atom,Line,undefined},erl_bits:as_list(Bt)}; + {ok,Size,Bt} -> {{integer,Line,Size},erl_bits:as_list(Bt)} + end; +make_bit_type(_Line, Size, Type0) -> %Integer or 'all' + {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0), + {Size,erl_bits:as_list(Bt)}. + +expr_lc_bc({Tag,Anno,E0,Gs0}) -> + Gs = lists:map(fun ({generate,L,P0,Qs}) -> + {generate,L,pattern(P0),expr(Qs, false)}; + ({b_generate,L,P0,Qs}) -> %R12. + {b_generate,L,pattern(P0),expr(Qs, false)}; + (Expr) -> + case is_guard_test(Expr) of + true -> {guard,guard([[Expr]])}; + false -> expr(Expr, false) + end + end, Gs0), + {Tag,ln(Anno),expr(E0, false),Gs}. + +is_guard_test(Expr) -> + IsOverridden = fun({_,_}) -> true end, + erl_lint:is_guard_test(Expr, [], IsOverridden). + +%% The debugger converts both strings "abc" and lists [67, 68, 69] +%% into {value, Line, [67, 68, 69]}, making it impossible to later +%% distingish one or the other inside binaries when evaluating. To +%% avoid <<[67, 68, 69]>> from evaluating, we convert strings into +%% chars to avoid the ambiguity. +bin_expand_strings(Es) -> + lists:foldr(fun ({bin_element,Line,{string,_,S},Sz,Ts}, Es1) -> + lists:foldr(fun (C, Es2) -> + [{bin_element,Line,{char,Line,C},Sz,Ts}|Es2] + end, Es1, S); + (E, Es1) -> [E|Es1] + end, [], Es). + %% -type expr_list([Expression]) -> [Expression]. %% These expressions are processed "in parallel" for purposes of variable %% definition etc. @@ -581,6 +632,14 @@ new_vars(N, L, Vs) when N > 0 -> new_vars(N-1, L, [V|Vs]); new_vars(0, _, Vs) -> Vs. +new_fun_name() -> + {F,A} = get(current_function), + I = get(fun_count), + put(fun_count, I+1), + Name = "-" ++ atom_to_list(F) ++ "/" ++ integer_to_list(A) ++ + "-fun-" ++ integer_to_list(I) ++ "-", + list_to_atom(Name). + ln(Anno) -> erl_anno:line(Anno). diff --git a/lib/debugger/src/dbg_iserver.erl b/lib/debugger/src/dbg_iserver.erl index 3561454685..3e959e8e30 100644 --- a/lib/debugger/src/dbg_iserver.erl +++ b/lib/debugger/src/dbg_iserver.erl @@ -214,7 +214,6 @@ handle_call({new_process, Pid, Meta, Function}, _From, State) -> %% Code loading handle_call({load, Mod, Src, Bin}, _From, State) -> - %% Create an ETS table for storing information about the module Db = State#state.db, ModDb = ets:new(Mod, [ordered_set, public]), @@ -285,23 +284,28 @@ handle_call({contents, Mod, Pid}, _From, State) -> {reply, {ok, Bin}, State}; handle_call({raw_contents, Mod, Pid}, _From, State) -> Db = State#state.db, - [{{Mod, refs}, ModDbs}] = ets:lookup(Db, {Mod, refs}), - ModDb = if - Pid =:= any -> hd(ModDbs); - true -> - lists:foldl(fun(T, not_found) -> - [{T, Pids}] = ets:lookup(Db, T), - case lists:member(Pid, Pids) of - true -> T; - false -> not_found - end; - (_T, T) -> T - end, - not_found, - ModDbs) - end, - [{mod_raw, Bin}] = ets:lookup(ModDb, mod_raw), - {reply, {ok, Bin}, State}; + case ets:lookup(Db, {Mod, refs}) of + [{{Mod, refs}, ModDbs}] -> + ModDb = + if + Pid =:= any -> hd(ModDbs); + true -> + lists:foldl(fun(T, not_found) -> + [{T, Pids}] = ets:lookup(Db, T), + case lists:member(Pid, Pids) of + true -> T; + false -> not_found + end; + (_T, T) -> T + end, + not_found, + ModDbs) + end, + [{mod_raw, Bin}] = ets:lookup(ModDb, mod_raw), + {reply, {ok, Bin}, State}; + [] -> % code not interpreted + {reply, not_found, State} + end; handle_call({is_interpreted, Mod, Name, Arity}, _From, State) -> Db = State#state.db, Reply = case ets:lookup(Db, {Mod, refs}) of diff --git a/lib/debugger/src/dbg_wx_code.erl b/lib/debugger/src/dbg_wx_code.erl index 473963500a..bca8a0d241 100644 --- a/lib/debugger/src/dbg_wx_code.erl +++ b/lib/debugger/src/dbg_wx_code.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2016. All Rights Reserved. +%% Copyright Ericsson AB 2008-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. @@ -190,6 +190,6 @@ find(Ed, Str, Case, Next) -> keyWords() -> L = ["after","begin","case","try","cond","catch","andalso","orelse", - "end","fun","if","let","of","query","receive","when","bnot","not", + "end","fun","if","let","of","receive","when","bnot","not", "div","rem","band","and","bor","bxor","bsl","bsr","or","xor"], lists:flatten([K ++ " " || K <- L] ++ [0]). diff --git a/lib/debugger/src/dbg_wx_src_view.erl b/lib/debugger/src/dbg_wx_src_view.erl index 207c407fbc..ee8eb72407 100644 --- a/lib/debugger/src/dbg_wx_src_view.erl +++ b/lib/debugger/src/dbg_wx_src_view.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2016. All Rights Reserved. +%% Copyright Ericsson AB 2008-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. @@ -62,6 +62,6 @@ code_area(Parent, Sizer) -> keyWords() -> L = ["after","begin","case","try","cond","catch","andalso","orelse", - "end","fun","if","let","of","query","receive","when","bnot","not", + "end","fun","if","let","of","receive","when","bnot","not", "div","rem","band","and","bor","bxor","bsl","bsr","or","xor"], lists:flatten([K ++ " " || K <- L] ++ [0]). diff --git a/lib/debugger/src/dbg_wx_trace.erl b/lib/debugger/src/dbg_wx_trace.erl index 6af19af33b..f4ee30618c 100644 --- a/lib/debugger/src/dbg_wx_trace.erl +++ b/lib/debugger/src/dbg_wx_trace.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2016. All Rights Reserved. +%% Copyright Ericsson AB 2008-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. @@ -524,7 +524,8 @@ gui_cmd({edit, {Var, Value}}, State) -> cancel -> State; {Var, Term} -> - Cmd = atom_to_list(Var)++"="++io_lib:format("~w", [Term]), + %% The space after "=" is needed for handling "B= <<1>>". + Cmd = atom_to_list(Var)++"= "++io_lib:format("~w", [Term]), gui_cmd({user_command, lists:flatten(Cmd)}, State) end. @@ -818,11 +819,14 @@ gui_show_module(Win, Mod, Line, _Cm, Pid, How) -> gui_load_module(Win, Mod, _Pid) -> dbg_wx_trace_win:display(Win,{text, "Loading module..."}), - %% Contents = int:contents(Mod, Pid), - {ok, Contents} = dbg_iserver:call({raw_contents, Mod, any}), - Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents), - dbg_wx_trace_win:display(Win,{text, ""}), - Win2. + case dbg_iserver:call({raw_contents, Mod, any}) of + {ok, Contents} -> + Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents), + dbg_wx_trace_win:display(Win,{text, ""}), + Win2; + not_found -> + dbg_wx_trace_win:show_no_code(Win) + end. gui_update_bindings(Win,Meta) -> Bs = int:meta(Meta, bindings, nostack), diff --git a/lib/debugger/src/dbg_wx_view.erl b/lib/debugger/src/dbg_wx_view.erl index 91fc0d08cb..86d009238f 100644 --- a/lib/debugger/src/dbg_wx_view.erl +++ b/lib/debugger/src/dbg_wx_view.erl @@ -263,7 +263,11 @@ shortcut(_) -> false. gui_load_module(Win, Mod) -> dbg_wx_trace_win:display(Win,{text, "Loading module..."}), - {ok, Contents} = dbg_iserver:call({raw_contents, Mod, any}), - Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents), - dbg_wx_trace_win:display(Win,{text, ""}), - Win2. + case dbg_iserver:call({raw_contents, Mod, any}) of + {ok, Contents} -> + Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents), + dbg_wx_trace_win:display(Win,{text, ""}), + Win2; + not_found -> + dbg_wx_trace_win:show_no_code(Win) + end. diff --git a/lib/debugger/src/dbg_wx_win.erl b/lib/debugger/src/dbg_wx_win.erl index 25ffc5054c..f1298154ab 100644 --- a/lib/debugger/src/dbg_wx_win.erl +++ b/lib/debugger/src/dbg_wx_win.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2015. All Rights Reserved. +%% Copyright Ericsson AB 2008-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. @@ -273,10 +273,9 @@ entry(Parent, Title, Prompt, {Type, Value}) -> verify(Type, Str) -> - case erl_scan:string(Str) of + case erl_scan:string(Str, 1, [text]) of {ok, Tokens, _EndLine} when Type==term -> - - case erl_parse:parse_term(Tokens++[{dot, 1}]) of + case lib:extended_parse_term(Tokens++[{dot, erl_anno:new(1)}]) of {ok, Value} -> {edit, Value}; _Error -> ignore diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl index e5bade9abe..fdf5957182 100644 --- a/lib/debugger/src/int.erl +++ b/lib/debugger/src/int.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. @@ -533,7 +533,9 @@ load({Mod, Src, Beam, BeamBin, Exp, Abst}, Dist) -> case erl_prim_loader:get_file(filename:absname(Src)) of {ok, SrcBin, _} -> MD5 = code:module_md5(BeamBin), - Bin = term_to_binary({interpreter_module,Exp,Abst,SrcBin,MD5}), + SrcBin1 = unicode:characters_to_binary(SrcBin, enc(SrcBin)), + true = is_binary(SrcBin1), + Bin = term_to_binary({interpreter_module,Exp,Abst,SrcBin1,MD5}), {module, Mod} = dbg_iserver:safe_call({load, Mod, Src, Bin}), _ = everywhere(Dist, fun() -> diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile index 125abcacda..efb6d9ed8b 100644 --- a/lib/debugger/test/Makefile +++ b/lib/debugger/test/Makefile @@ -46,6 +46,7 @@ MODULES= \ lc_SUITE \ line_number_SUITE \ map_SUITE \ + overridden_bif_SUITE \ record_SUITE \ trycatch_SUITE \ test_lib \ diff --git a/lib/debugger/test/andor_SUITE.erl b/lib/debugger/test/andor_SUITE.erl index d7bbd4fccb..f6e39514af 100644 --- a/lib/debugger/test/andor_SUITE.erl +++ b/lib/debugger/test/andor_SUITE.erl @@ -29,6 +29,8 @@ -include_lib("common_test/include/ct.hrl"). +-warning("Ignore me -- testing that the debugger can handle warnings"). + suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,1}}]. diff --git a/lib/debugger/test/bs_bincomp_SUITE.erl b/lib/debugger/test/bs_bincomp_SUITE.erl index 39e2240f2d..064e9567b3 100644 --- a/lib/debugger/test/bs_bincomp_SUITE.erl +++ b/lib/debugger/test/bs_bincomp_SUITE.erl @@ -66,6 +66,7 @@ end_per_group(_GroupName, Config) -> byte_aligned(Config) when is_list(Config) -> <<"abcdefg">> = << <<(X+32)>> || <<X>> <= <<"ABCDEFG">> >>, + <<"AxyzBxyzCxyz">> = << <<X, "xyz">> || <<X>> <= <<"ABC">> >>, <<1:32/little,2:32/little,3:32/little,4:32/little>> = << <<X:32/little>> || <<X:32>> <= <<1:32,2:32,3:32,4:32>> >>, <<1:32/little,2:32/little,3:32/little,4:32/little>> = diff --git a/lib/debugger/test/int_SUITE.erl b/lib/debugger/test/int_SUITE.erl index f697ace4e5..cb1fcb83f3 100644 --- a/lib/debugger/test/int_SUITE.erl +++ b/lib/debugger/test/int_SUITE.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. @@ -241,7 +241,8 @@ interpretable(Config) when is_list(Config) -> true = code:del_path(PrivDir), %% {error, no_src} - {ok, lists2, Binary} = compile:forms([{attribute,1,module,lists2}], []), + A1 = erl_anno:new(1), + {ok, lists2, Binary} = compile:forms([{attribute,A1,module,lists2}], []), code:load_binary(lists2, "unknown", Binary), {error, no_src} = int:interpretable(lists2), diff --git a/lib/debugger/test/map_SUITE.erl b/lib/debugger/test/map_SUITE.erl index 42484ff723..4d8a86f5a2 100644 --- a/lib/debugger/test/map_SUITE.erl +++ b/lib/debugger/test/map_SUITE.erl @@ -1714,10 +1714,8 @@ t_bif_map_values(Config) when is_list(Config) -> t_erlang_hash(Config) when is_list(Config) -> - ok = t_bif_erlang_phash2(), ok = t_bif_erlang_phash(), - ok = t_bif_erlang_hash(), ok. t_bif_erlang_phash2() -> @@ -1759,26 +1757,6 @@ t_bif_erlang_phash() -> 2620391445 = erlang:phash(M2,Sz), % 3590546636 ok. -t_bif_erlang_hash() -> - Sz = 1 bsl 27 - 1, - 39684169 = erlang:hash(#{},Sz), % 5158 - 33673142 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 71555838 - 95337869 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 5497225 - 108959561 = erlang:hash(#{ 1 => a },Sz), % 126071654 - 59623150 = erlang:hash(#{ a => 1 },Sz), % 126426236 - - 42775386 = erlang:hash(#{{} => <<>>},Sz), % 101655720 - 71692856 = erlang:hash(#{<<>> => {}},Sz), % 101655720 - - M0 = #{ a => 1, "key" => <<"value">> }, - M1 = maps:remove("key",M0), - M2 = M1#{ "key" => <<"value">> }, - - 70254632 = erlang:hash(M0,Sz), % 38260486 - 59623150 = erlang:hash(M1,Sz), % 126426236 - 70254632 = erlang:hash(M2,Sz), % 38260486 - ok. - t_map_encode_decode(Config) when is_list(Config) -> <<131,116,0,0,0,0>> = erlang:term_to_binary(#{}), Pairs = [ diff --git a/lib/debugger/test/overridden_bif_SUITE.erl b/lib/debugger/test/overridden_bif_SUITE.erl new file mode 100644 index 0000000000..04bef3c0a2 --- /dev/null +++ b/lib/debugger/test/overridden_bif_SUITE.erl @@ -0,0 +1,99 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2016. 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. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% +-module(overridden_bif_SUITE). +-compile({no_auto_import,[is_reference/1,size/1]}). + +-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, + init_per_group/2,end_per_group/2, + init_per_testcase/2,end_per_testcase/2, + overridden_bif/1]). + +-include_lib("common_test/include/ct.hrl"). + +%% Used by overridden_bif/1. +-import(gb_sets, [size/1]). +-import(test_lib, [binary/1]). + +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap,{minutes,1}}]. + +all() -> + [overridden_bif]. + +groups() -> + []. + +init_per_suite(Config) -> + test_lib:interpret(?MODULE), + Config. + +end_per_suite(_Config) -> + ok. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + + +init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> + Config. + +end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> + ok. + +overridden_bif(_Config) -> + L = [-3,-2,-1,0,1,2,3,4], + [-3,0,3] = do_overridden_bif_1(L), + [-2,0,2,4] = do_overridden_bif_2(L), + [3] = do_overridden_bif_3(L), + [2,4] = do_overridden_bif_4(L), + + Set = gb_sets:from_list(L), + [Set] = do_overridden_bif_5([gb_sets:singleton(42),Set]), + + [100,0] = do_overridden_bif_6([100|L]), + ok. + +do_overridden_bif_1(L) -> + [E || E <- L, is_reference(E)]. + +do_overridden_bif_2(L) -> + [E || E <- L, port(E)]. + +do_overridden_bif_3(L) -> + [E || E <- L, (is_reference(E) andalso E > 0)]. + +do_overridden_bif_4(L) -> + [E || E <- L, (port(E) andalso E > 0)]. + +do_overridden_bif_5(L) -> + [E || E <- L, size(E) > 1]. + +do_overridden_bif_6(L) -> + [E || E <- L, binary(E)]. + +is_reference(N) -> + N rem 3 =:= 0. + +port(N) -> + N rem 2 =:= 0. diff --git a/lib/debugger/test/test_lib.erl b/lib/debugger/test/test_lib.erl index b9ac486694..7e98d210e8 100644 --- a/lib/debugger/test/test_lib.erl +++ b/lib/debugger/test/test_lib.erl @@ -23,8 +23,15 @@ -export([interpret/1]). +%% Used by test case that override BIFs. +-export([binary/1]). + interpret(Mod) when is_atom(Mod) -> case lists:member(Mod, int:interpreted()) of true -> ok; false -> {module,Mod} = i:ii(Mod) end. + +%% This is for overridden_bif_SUITE. +binary(N) -> + N rem 10 =:= 0. diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk index dd496013cd..3534570ef5 100644 --- a/lib/debugger/vsn.mk +++ b/lib/debugger/vsn.mk @@ -1 +1 @@ -DEBUGGER_VSN = 4.2 +DEBUGGER_VSN = 4.2.2 |