diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compiler/doc/src/notes.xml | 17 | ||||
-rw-r--r-- | lib/compiler/src/v3_codegen.erl | 5 | ||||
-rw-r--r-- | lib/compiler/test/map_SUITE.erl | 46 | ||||
-rw-r--r-- | lib/compiler/vsn.mk | 2 | ||||
-rw-r--r-- | lib/crypto/c_src/crypto.c | 1 | ||||
-rw-r--r-- | lib/crypto/doc/src/notes.xml | 16 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 105 | ||||
-rw-r--r-- | lib/crypto/vsn.mk | 2 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia.erl | 16 | ||||
-rw-r--r-- | lib/mnesia/test/mnesia_isolation_test.erl | 11 | ||||
-rw-r--r-- | lib/ssh/src/ssh.hrl | 25 | ||||
-rw-r--r-- | lib/ssh/src/ssh_dbg.erl | 108 | ||||
-rw-r--r-- | lib/ssh/test/ssh_dbg_SUITE.erl | 68 | ||||
-rw-r--r-- | lib/stdlib/src/erl_internal.erl | 2 | ||||
-rw-r--r-- | lib/syntax_tools/doc/src/notes.xml | 14 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_driver.c | 165 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_driver.h | 2 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_main.cpp | 15 | ||||
-rwxr-xr-x | lib/wx/test/wxt | 4 |
19 files changed, 479 insertions, 145 deletions
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index fbef955ac7..671126b73b 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -32,6 +32,23 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 7.2.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed an issue where files compiled with the + <c>+deterministic</c> option differed if they were + compiled in a different directory but were otherwise + identical.</p> + <p> + Own Id: OTP-15204 Aux Id: ERL-679 </p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 7.2.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl index 6cd114abf7..e9152ba88f 100644 --- a/lib/compiler/src/v3_codegen.erl +++ b/lib/compiler/src/v3_codegen.erl @@ -1621,11 +1621,6 @@ test_cg(is_boolean, [#k_atom{val=Val}], Fail, I, Vdb, Bef, St) -> false -> [{jump,{f,Fail}}] end, {Is,Aft,St}; -test_cg(is_map_key, As, Fail, I, Vdb, Bef, St) -> - [Key,Map] = cg_reg_args(As, Bef), - Aft = clear_dead(Bef, I, Vdb), - F = {f,Fail}, - {[{test,is_map,F,[Map]},{test,has_map_fields,F,Map,{list,[Key]}}],Aft,St}; test_cg(Test, As, Fail, I, Vdb, Bef, St) -> Args = cg_reg_args(As, Bef), Aft = clear_dead(Bef, I, Vdb), diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl index 9182c1b5ed..c004dca834 100644 --- a/lib/compiler/test/map_SUITE.erl +++ b/lib/compiler/test/map_SUITE.erl @@ -1212,10 +1212,25 @@ t_guard_bifs(Config) when is_list(Config) -> true = map_guard_empty_2(), true = map_guard_head(#{a=>1}), false = map_guard_head([]), + true = map_get_head(#{a=>1}), + false = map_get_head(#{}), + false = map_get_head([]), + + true = map_get_head_not(#{a=>false}), + false = map_get_head_not(#{a=>true}), + false = map_get_head(#{}), false = map_get_head([]), + true = map_is_key_head(#{a=>1}), false = map_is_key_head(#{}), + false = map_is_key_head(not_a_map), + + false = map_is_key_head_not(#{a=>1}), + true = map_is_key_head_not(#{b=>1}), + true = map_is_key_head_not(#{}), + false = map_is_key_head_not(not_a_map), + true = map_guard_body(#{a=>1}), false = map_guard_body({}), true = map_guard_pattern(#{a=>1, <<"hi">> => "hi" }), @@ -1224,6 +1239,25 @@ t_guard_bifs(Config) when is_list(Config) -> true = map_guard_ill_map_size(), true = map_field_check_sequence(#{a=>1}), false = map_field_check_sequence(#{}), + + %% The guard BIFs used in a body. + + v = map_get(a, id(#{a=>v})), + {'EXIT',{{badkey,a},_}} = + (catch map_get(a, id(#{}))), + {'EXIT',{{badmap,not_a_map},_}} = + (catch map_get(a, id(not_a_map))), + + true = is_map_key(a, id(#{a=>1})), + false = is_map_key(b, id(#{a=>1})), + false = is_map_key(b, id(#{})), + {'EXIT',{{badmap,not_a_map},_}} = + (catch is_map_key(b, id(not_a_map))), + + {true,v} = erl_699(#{k=>v}), + {'EXIT',{{badkey,k},_}} = (catch erl_699(#{})), + {'EXIT',{{badmap,not_a_map},_}} = (catch erl_699(not_a_map)), + ok. map_guard_empty() when is_map(#{}); false -> true. @@ -1236,8 +1270,14 @@ map_guard_head(_) -> false. map_get_head(M) when map_get(a, M) =:= 1 -> true; map_get_head(_) -> false. +map_get_head_not(M) when not map_get(a, M) -> true; +map_get_head_not(_) -> false. + map_is_key_head(M) when is_map_key(a, M) -> true; -map_is_key_head(M) -> false. +map_is_key_head(_) -> false. + +map_is_key_head_not(M) when not is_map_key(a, M) -> true; +map_is_key_head_not(_) -> false. map_guard_body(M) -> is_map(M). @@ -1254,6 +1294,10 @@ map_field_check_sequence(M) map_field_check_sequence(_) -> false. +erl_699(M) -> + %% Used to cause an internal consistency failure. + {is_map_key(k, M),maps:get(k, M)}. + t_guard_sequence(Config) when is_list(Config) -> {1, "a"} = map_guard_sequence_1(#{seq=>1,val=>id("a")}), {2, "b"} = map_guard_sequence_1(#{seq=>2,val=>id("b")}), diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index f99b6721e2..355113a94d 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 7.2.2 +COMPILER_VSN = 7.2.3 diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index f8d1778bb9..a9fef65e03 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -179,6 +179,7 @@ #if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,0) # ifndef HAS_LIBRESSL # define HAVE_CHACHA20_POLY1305 +# define HAVE_RSA_OAEP_MD # endif #endif diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 54842e907e..5e0851f6b8 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -31,6 +31,22 @@ </header> <p>This document describes the changes made to the Crypto application.</p> +<section><title>Crypto 4.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a node crash in <c>crypto:compute_key(ecdh, + ...)</c> when passing a wrongly typed Others + argument.</p> + <p> + Own Id: OTP-15194 Aux Id: ERL-673 </p> + </item> + </list> + </section> + +</section> + <section><title>Crypto 4.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 943062f56f..aa2278dbdd 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -840,26 +840,69 @@ negative_verify(Type, Hash, Msg, Signature, Public, Options) -> ok end. +-define(PUB_PRIV_ENC_DEC_CATCH(Type,Padding), + CC:EE -> + ct:log("~p:~p in ~p:~p/~p, line ~p.~n" + "Type = ~p~nPadding = ~p", + [CC,EE,?MODULE,?FUNCTION_NAME,?FUNCTION_ARITY,?LINE,(Type),(Padding)]), + MaybeUnsupported = + case crypto:info_lib() of + [{<<"OpenSSL">>,_,_}] -> + is_list(Padding) andalso + lists:any(fun(P) -> lists:member(P,(Padding)) end, + [{rsa_padding, rsa_pkcs1_oaep_padding}, + {rsa_padding, rsa_sslv23_padding}, + {rsa_padding, rsa_x931_padding}]); + _ -> + false + end, + case CC of + error when MaybeUnsupported -> + ct:comment("Padding unsupported?",[]); + _ -> + ct:fail({?FUNCTION_NAME,CC,EE,(Type),(Padding)}) + end + ). + do_public_encrypt({Type, Public, Private, Msg, Padding}) -> - PublicEcn = (catch crypto:public_encrypt(Type, Msg, Public, Padding)), - case crypto:private_decrypt(Type, PublicEcn, Private, Padding) of - Msg -> - ok; - Other -> - ct:fail({{crypto, private_decrypt, [Type, PublicEcn, Private, Padding]}, {expected, Msg}, {got, Other}}) + try + crypto:public_encrypt(Type, Msg, Public, Padding) + of + PublicEcn -> + try + crypto:private_decrypt(Type, PublicEcn, Private, Padding) + of + Msg -> + ok; + Other -> + ct:fail({{crypto, private_decrypt, [Type, PublicEcn, Private, Padding]}, {expected, Msg}, {got, Other}}) + catch + ?PUB_PRIV_ENC_DEC_CATCH(Type, Padding) + end + catch + ?PUB_PRIV_ENC_DEC_CATCH(Type, Padding) end. -do_private_encrypt({_Type, _Public, _Private, _Msg, rsa_pkcs1_oaep_padding}) -> - ok; %% Not supported by openssl + do_private_encrypt({Type, Public, Private, Msg, Padding}) -> - PrivEcn = (catch crypto:private_encrypt(Type, Msg, Private, Padding)), - case crypto:public_decrypt(Type, PrivEcn, Public, Padding) of - Msg -> - ok; - Other -> - ct:fail({{crypto, public_decrypt, [Type, PrivEcn, Public, Padding]}, {expected, Msg}, {got, Other}}) + try + crypto:private_encrypt(Type, Msg, Private, Padding) + of + PrivEcn -> + try + crypto:public_decrypt(Type, PrivEcn, Public, Padding) + of + Msg -> + ok; + Other -> + ct:fail({{crypto, public_decrypt, [Type, PrivEcn, Public, Padding]}, {expected, Msg}, {got, Other}}) + catch + ?PUB_PRIV_ENC_DEC_CATCH(Type, Padding) + end + catch + ?PUB_PRIV_ENC_DEC_CATCH(Type, Padding) end. - + do_generate_compute({srp = Type, UserPrivate, UserGenParams, UserComParams, HostPublic, HostPrivate, HostGenParams, HostComParam, SessionKey}) -> {UserPublic, UserPrivate} = crypto:generate_key(Type, UserGenParams, UserPrivate), @@ -1245,7 +1288,12 @@ group_config(rsa = Type, Config) -> end, MsgPubEnc = <<"7896345786348 Asldi">>, PubPrivEnc = [{rsa, PublicS, PrivateS, MsgPubEnc, rsa_pkcs1_padding}, + {rsa, PublicS, PrivateS, MsgPubEnc, [{rsa_padding, rsa_pkcs1_padding}]}, + {rsa, PublicS, PrivateS, MsgPubEnc, [{rsa_padding, rsa_sslv23_padding}]}, + {rsa, PublicS, PrivateS, MsgPubEnc, [{rsa_padding, rsa_x931_padding}]}, rsa_oaep(), + rsa_oaep_label(), + rsa_oaep256(), no_padding() ], Generate = [{rsa, 1024, 3}, {rsa, 2048, 17}, {rsa, 3072, 65537}], @@ -2338,7 +2386,32 @@ rsa_oaep() -> hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")], %%Msg = hexstr2bin("6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34"), Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"), - {rsa, Public, Private, Msg, rsa_pkcs1_oaep_padding}. + {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}]}. + +rsa_oaep_label() -> + Public = [hexstr2bin("010001"), + hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")], + Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"), + hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"), + hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"), + hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"), + hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"), + hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")], + Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"), + Lbl = hexstr2bin("1332a67ca7088f75c9b8fb5e3d072882"), + {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}, {rsa_oaep_label, Lbl}]}. + +rsa_oaep256() -> + Public = [hexstr2bin("010001"), + hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")], + Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"), + hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"), + hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"), + hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"), + hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"), + hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")], + Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"), + {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}, {rsa_oaep_md, sha256}]}. ecc() -> %% http://point-at-infinity.org/ecc/nisttv diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index cc34c20ac6..0d7b0e5575 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 4.3 +CRYPTO_VSN = 4.3.1 diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl index 62202401ed..223dba3f90 100644 --- a/lib/mnesia/src/mnesia.erl +++ b/lib/mnesia/src/mnesia.erl @@ -783,12 +783,16 @@ do_delete_object(Tid, Ts, Tab, Val, LockKind) -> ?ets_insert(Store, {Oid, Val, delete_object}); _ -> case ?ets_match_object(Store, {Oid, '_', write}) of - [] -> - ?ets_match_delete(Store, {Oid, Val, '_'}), - ?ets_insert(Store, {Oid, Val, delete_object}); - _ -> - ?ets_delete(Store, Oid), - ?ets_insert(Store, {Oid, Oid, delete}) + [] -> + ?ets_match_delete(Store, {Oid, Val, '_'}), + ?ets_insert(Store, {Oid, Val, delete_object}); + Ops -> + case lists:member({Oid, Val, write}, Ops) of + true -> + ?ets_delete(Store, Oid), + ?ets_insert(Store, {Oid, Oid, delete}); + false -> ok + end end end, ok; diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl index b2eea2390b..49bcec14af 100644 --- a/lib/mnesia/test/mnesia_isolation_test.erl +++ b/lib/mnesia/test/mnesia_isolation_test.erl @@ -1563,7 +1563,8 @@ trans_update_visible_inside_trans(Config) when is_list(Config) -> ?match({atomic, ok}, mnesia:create_table([{name, Tab}, {ram_copies, [Node1]}])), ValPos = 3, - RecA = {Tab, a, 1}, + RecA = {Tab, a, 1}, + RecA2 = {Tab, a, 2}, PatA = {Tab, '$1', 1}, RecB = {Tab, b, 3}, PatB = {Tab, '$1', 3}, @@ -1598,6 +1599,14 @@ trans_update_visible_inside_trans(Config) when is_list(Config) -> ?match([], mnesia:index_read(Tab, 3, ValPos)), %% delete_object + ?match(ok, mnesia:delete_object(RecA2)), + ?match([RecA], mnesia:read({Tab, a})), + ?match([RecA], mnesia:wread({Tab, a})), + ?match([RecA], mnesia:match_object(PatA)), + ?match([a], mnesia:all_keys(Tab)), + ?match([RecA], mnesia:index_match_object(PatA, ValPos)), + ?match([RecA], mnesia:index_read(Tab, 1, ValPos)), + ?match(ok, mnesia:delete_object(RecA)), ?match([], mnesia:read({Tab, a})), ?match([], mnesia:wread({Tab, a})), diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl index 9631427749..01c44cb371 100644 --- a/lib/ssh/src/ssh.hrl +++ b/lib/ssh/src/ssh.hrl @@ -492,4 +492,29 @@ -define(wr_record(N), ?wr_record(N, [])). +%% Circular trace buffer macros + +-record(circ_buf_entry, + { + module, + line, + function, + pid = self(), + value + }). + +-define(CIRC_BUF_IN(VALUE), + ssh_dbg:cbuf_in( + #circ_buf_entry{module = ?MODULE, + line = ?LINE, + function = {?FUNCTION_NAME,?FUNCTION_ARITY}, + pid = self(), + value = (VALUE) + }) + ). + +-define(CIRC_BUF_IN_ONCE(VALUE), + ((fun(V) -> ?CIRC_BUF_IN(V), V end)(VALUE)) + ). + -endif. % SSH_HRL defined diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl index b53c09b17d..3681e03cc2 100644 --- a/lib/ssh/src/ssh_dbg.erl +++ b/lib/ssh/src/ssh_dbg.erl @@ -54,7 +54,13 @@ start_tracer/0, start_tracer/1, on/1, on/0, off/1, off/0, - go_on/0 + go_on/0, + %% Circular buffer + cbuf_start/0, cbuf_start/1, + cbuf_stop_clear/0, + cbuf_in/1, + cbuf_list/0, + fmt_cbuf_items/0, fmt_cbuf_item/1 ]). -export([shrink_bin/1, @@ -331,3 +337,103 @@ ts({_,_,Usec}=Now) when is_integer(Usec) -> io_lib:format("~.2.0w:~.2.0w:~.2.0w.~.6.0w",[HH,MM,SS,Usec]); ts(_) -> "-". + +%%%================================================================ +-define(CIRC_BUF, circ_buf). + +cbuf_start() -> + cbuf_start(20). + +cbuf_start(CbufMaxLen) -> + put(?CIRC_BUF, {CbufMaxLen,queue:new()}), + ok. + + +cbuf_stop_clear() -> + case erase(?CIRC_BUF) of + undefined -> + []; + {_CbufMaxLen,Queue} -> + queue:to_list(Queue) + end. + + +cbuf_in(Value) -> + case get(?CIRC_BUF) of + undefined -> + disabled; + {CbufMaxLen,Queue} -> + UpdatedQueue = + try queue:head(Queue) of + {Value, TS0, Cnt0} -> + %% Same Value as last saved in the queue + queue:in_r({Value, TS0, Cnt0+1}, + queue:drop(Queue) + ); + _ -> + queue:in_r({Value, erlang:timestamp(), 1}, + truncate_cbuf(Queue, CbufMaxLen) + ) + catch + error:empty -> + queue:in_r({Value, erlang:timestamp(), 1}, Queue) + end, + put(?CIRC_BUF, {CbufMaxLen,UpdatedQueue}), + ok + end. + + +cbuf_list() -> + case get(?CIRC_BUF) of + undefined -> + []; + {_CbufMaxLen,Queue} -> + queue:to_list(Queue) + end. + + +truncate_cbuf(Q, CbufMaxLen) -> + case queue:len(Q) of + N when N>=CbufMaxLen -> + truncate_cbuf(element(2,queue:out_r(Q)), CbufMaxLen); + _ -> + Q + end. + +fmt_cbuf_items() -> + lists:flatten( + io_lib:format("Circular trace buffer. Latest item first.~n~s~n", + [case get(?CIRC_BUF) of + {Max,_} -> + L = cbuf_list(), + [io_lib:format("==== ~.*w: ~s~n",[num_digits(Max),N,fmt_cbuf_item(X)]) || + {N,X} <- lists:zip(lists:seq(1,length(L)), L) + ]; + _ -> + io_lib:format("Not started.~n",[]) + end])). + + +num_digits(0) -> 1; +num_digits(N) when N>0 -> 1+trunc(math:log10(N)). + + +fmt_cbuf_item({Value, TimeStamp, N}) -> + io_lib:format("~s~s~n~s~n", + [fmt_ts(TimeStamp), + [io_lib:format(" (Repeated ~p times)",[N]) || N>1], + fmt_value(Value)]). + + +fmt_ts(TS = {_,_,Us}) -> + {{YY,MM,DD},{H,M,S}} = calendar:now_to_universal_time(TS), + io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w.~.6.0w UTC",[YY,MM,DD,H,M,S,Us]). + +fmt_value(#circ_buf_entry{module = M, + line = L, + function = {F,A}, + pid = Pid, + value = V}) -> + io_lib:format("~p:~p ~p/~p ~p~n~s",[M,L,F,A,Pid,fmt_value(V)]); +fmt_value(Value) -> + io_lib:format("~p",[Value]). diff --git a/lib/ssh/test/ssh_dbg_SUITE.erl b/lib/ssh/test/ssh_dbg_SUITE.erl index 5439817d10..ab7918fa90 100644 --- a/lib/ssh/test/ssh_dbg_SUITE.erl +++ b/lib/ssh/test/ssh_dbg_SUITE.erl @@ -38,11 +38,20 @@ suite() -> {timetrap,{seconds,60}}]. all() -> - [basic, - dbg_alg_terminate, - dbg_ssh_messages, - dbg_connections, - dbg_channels + [{group, dbg}, + {group, circ_buf} + ]. + +groups() -> + [{dbg, [], [dbg_basic, + dbg_alg_terminate, + dbg_ssh_messages, + dbg_connections, + dbg_channels]}, + {circ_buf, [], [cb_basic, + cb_print, + cb_macros_print + ]} ]. %%-------------------------------------------------------------------- @@ -82,7 +91,7 @@ end_per_testcase(_TC, Config) -> %% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- -basic(_Config) -> +dbg_basic(_Config) -> L0 = ssh_dbg:start(), true = is_pid(whereis(ssh_dbg)), true = is_list(L0), @@ -342,6 +351,53 @@ dbg_channels(Config) -> stop_and_fail_if_unhandled_dbg_msgs(Ref, [C,D], Pid). %%-------------------------------------------------------------------- +cb_basic(_Config) -> + %% Check that the circular buffer is disabled at start: + [] = ssh_dbg:cbuf_list(), + disabled = ssh_dbg:cbuf_in(anything), + [] = ssh_dbg:cbuf_list(), + %% Start it and enter three values, first is duplicated; + ok = ssh_dbg:cbuf_start(3), + ok = ssh_dbg:cbuf_in(v1), + ok = ssh_dbg:cbuf_in(v1), + ok = ssh_dbg:cbuf_in(v2), + ok = ssh_dbg:cbuf_in(v3), + [{v3,_,1}, {v2,_,1}, {v1,_,2}] = ssh_dbg:cbuf_list(), + %% Check that a fourth value erase the first entered: + ok = ssh_dbg:cbuf_in(v4), + [{v4,_,1}, {v3,_,1}, {v2,_,1}] = ssh_dbg:cbuf_list(), + %% Check that entering a value that is in the tail but not in the head is treated as a new value: + ok = ssh_dbg:cbuf_in(v2), + [{v2,_,1}, {v4,_,1}, {v3,_,1}] = ssh_dbg:cbuf_list(), + %% Stop and check that the buffer is returned: + [{v2,_,1}, {v4,_,1}, {v3,_,1}] = ssh_dbg:cbuf_stop_clear(), + %% Stopping a stopped buffer returns empty: + [] = ssh_dbg:cbuf_stop_clear(), + %% Check that a value can't be entered in a stopped buffer: + disabled = ssh_dbg:cbuf_in(v2). + +%%-------------------------------------------------------------------- +cb_print(_Config) -> + ssh_dbg:cbuf_start(), + [begin + ssh_dbg:cbuf_in(V), + ct:log("Enter ~p",[V]) + end || V <- lists:seq(1,10)], + ct:log("~s",[ssh_dbg:fmt_cbuf_items()]), + ssh_dbg:cbuf_stop_clear(). + +%%-------------------------------------------------------------------- +cb_macros_print(_Config) -> + ssh_dbg:cbuf_start(), + [begin + V = {test,V0}, + ?CIRC_BUF_IN(V), + ct:log("Enter ~p",[V]) + end || V0 <- lists:seq(1,5)], + ct:log("~s",[ssh_dbg:fmt_cbuf_items()]), + ssh_dbg:cbuf_stop_clear(). + +%%-------------------------------------------------------------------- %%-------------------------------------------------------------------- %%-------------------------------------------------------------------- diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl index b311a843c2..939abaff00 100644 --- a/lib/stdlib/src/erl_internal.erl +++ b/lib/stdlib/src/erl_internal.erl @@ -74,6 +74,7 @@ guard_bif(element, 2) -> true; guard_bif(float, 1) -> true; guard_bif(floor, 1) -> true; guard_bif(hd, 1) -> true; +guard_bif(is_map_key, 2) -> true; guard_bif(length, 1) -> true; guard_bif(map_size, 1) -> true; guard_bif(map_get, 2) -> true; @@ -109,7 +110,6 @@ new_type_test(is_function, 2) -> true; new_type_test(is_integer, 1) -> true; new_type_test(is_list, 1) -> true; new_type_test(is_map, 1) -> true; -new_type_test(is_map_key, 2) -> true; new_type_test(is_number, 1) -> true; new_type_test(is_pid, 1) -> true; new_type_test(is_port, 1) -> true; diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index 76c2d6ecbd..44944e57c3 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -108,6 +108,20 @@ </section> +<section><title>Syntax_Tools 2.1.1.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Fix a bug regarding reverting map types. </p> + <p> + Own Id: OTP-15098 Aux Id: ERIERL-177 </p> + </item> + </list> + </section> + +</section> + <section><title>Syntax_Tools 2.1.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c index 8b8c625971..c9d299e0df 100644 --- a/lib/wx/c_src/wxe_driver.c +++ b/lib/wx/c_src/wxe_driver.c @@ -38,10 +38,8 @@ #define TEMP_BINARY_SIZE 512 -static ErlDrvData wxe_driver_start(ErlDrvPort port, char *buff); -static int wxe_driver_load(void); +static ErlDrvData wxe_driver_start(ErlDrvPort port, char *command); static void wxe_driver_stop(ErlDrvData handle); -static void wxe_driver_unload(void); static ErlDrvSSizeT wxe_driver_control(ErlDrvData handle, unsigned int command, char* buf, ErlDrvSizeT count, @@ -63,30 +61,30 @@ char * erl_wx_privdir; ** The driver struct */ static ErlDrvEntry wxe_driver_entry = { - wxe_driver_load, /* F_PTR init, called at loading */ - wxe_driver_start, /* L_PTR start, called when port is opened */ - wxe_driver_stop, /* F_PTR stop, called when port is closed */ - NULL, /* F_PTR output, called when erlang has sent */ - NULL, /* F_PTR ready_input, called when input descriptor - ready */ - NULL, /* F_PTR ready_output, called when output - descriptor ready */ - "wxe_driver", /* char *driver_name, the argument to open_port */ - wxe_driver_unload, /* F_PTR finish, called when unloaded */ - NULL, /* void * that is not used (BC) */ - wxe_driver_control, /* F_PTR control, port_control callback */ - NULL, /* F_PTR timeout, reserved */ - standard_outputv, /* F_PTR outputv, reserved */ - NULL, /* async */ - NULL, /* flush */ - wxe_driver_call, /* call */ - NULL, /* Event */ + NULL, /* F_PTR init, called at loading */ + wxe_driver_start, /* L_PTR start, called when port is opened */ + wxe_driver_stop, /* F_PTR stop, called when port is closed */ + NULL, /* F_PTR output, called when erlang has sent */ + NULL, /* F_PTR ready_input, called when + input descriptor ready */ + NULL, /* F_PTR ready_output, called when + output descriptor ready */ + "wxe_driver", /* char *driver_name, the argument to open_port */ + NULL, /* F_PTR finish, called when unloaded */ + NULL, /* void * that is not used (BC) */ + wxe_driver_control, /* F_PTR control, port_control callback */ + NULL, /* F_PTR timeout, reserved */ + standard_outputv, /* F_PTR outputv, reserved */ + NULL, /* async */ + NULL, /* flush */ + wxe_driver_call, /* call */ + NULL, /* Event */ ERL_DRV_EXTENDED_MARKER, ERL_DRV_EXTENDED_MAJOR_VERSION, ERL_DRV_EXTENDED_MINOR_VERSION, - ERL_DRV_FLAG_USE_PORT_LOCKING, /* Port lock */ - NULL, /* Reserved Handle */ - wxe_process_died, /* Process Exited */ + ERL_DRV_FLAG_USE_PORT_LOCKING, /* Port lock */ + NULL, /* Reserved Handle */ + wxe_process_died, /* Process Exited */ }; DRIVER_INIT(wxe_driver) @@ -94,60 +92,56 @@ DRIVER_INIT(wxe_driver) return &wxe_driver_entry; } -int wxe_driver_load() -{ - if(load_native_gui()) - return 0; - else - return -1; -} - ErlDrvPort WXE_DRV_PORT_HANDLE = 0; ErlDrvTermData WXE_DRV_PORT = 0; static ErlDrvData -wxe_driver_start(ErlDrvPort port, char *buff) -{ - wxe_data *data; - - data = (wxe_data *) malloc(sizeof(wxe_data)); - wxe_debug = 0; - - if (data == NULL) { - fprintf(stderr, " Couldn't alloc mem\r\n"); - return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */ - } else { - ErlDrvTermData term_port = driver_mk_port(port); - set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); - data->driver_data = NULL; - data->bin = (WXEBinRef*) driver_alloc(sizeof(WXEBinRef)*DEF_BINS); - data->bin[0].from = 0; - data->bin[1].from = 0; - data->bin[2].from = 0; - data->max_bins = DEF_BINS; - data->port_handle = port; - data->port = term_port; - data->pdl = driver_pdl_create(port); - if(WXE_DRV_PORT_HANDLE == 0) { - for(; *buff != 32; buff++); - buff++; - erl_wx_privdir = strdup(buff); - - WXE_DRV_PORT_HANDLE = port; - WXE_DRV_PORT = term_port; - wxe_master = data; - if(!(start_native_gui(data) == 1)) - return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */ - } else { - meta_command(CREATE_PORT,data); - } - return (ErlDrvData) data; - } +wxe_driver_start(ErlDrvPort port, char *command) +{ + wxe_data *data; + + data = (wxe_data *) malloc(sizeof(wxe_data)); + wxe_debug = 0; + + if (data == NULL) { + fprintf(stderr, " Couldn't alloc mem\r\n"); + return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */ + } else { + ErlDrvTermData term_port = driver_mk_port(port); + set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); + data->driver_data = NULL; + data->bin = (WXEBinRef*) driver_alloc(sizeof(WXEBinRef)*DEF_BINS); + data->bin[0].from = 0; + data->bin[1].from = 0; + data->bin[2].from = 0; + data->max_bins = DEF_BINS; + data->port_handle = port; + data->port = term_port; + data->pdl = driver_pdl_create(port); + if(WXE_DRV_PORT_HANDLE == 0) { + char *first_space = strchr(command, ' '); + if (first_space) { + char *priv_dir = first_space + 1; + erl_wx_privdir = strdup(priv_dir); + + WXE_DRV_PORT_HANDLE = port; + WXE_DRV_PORT = term_port; + wxe_master = data; + if(start_native_gui(data) != 1) + return ERL_DRV_ERROR_GENERAL; /* ENOMEM */ + } else { + return ERL_DRV_ERROR_BADARG; + } + } else { + meta_command(CREATE_PORT, data); + } + return (ErlDrvData) data; + } } static void wxe_driver_stop(ErlDrvData handle) -{ +{ wxe_data *sd = ((wxe_data *)handle); if(sd->port_handle != WXE_DRV_PORT_HANDLE) { // fprintf(stderr, "%s:%d: STOP \r\n", __FILE__,__LINE__); @@ -155,18 +149,11 @@ wxe_driver_stop(ErlDrvData handle) } else { // fprintf(stderr, "%s:%d: STOP \r\n", __FILE__,__LINE__); stop_native_gui(wxe_master); - unload_native_gui(); free(wxe_master); wxe_master = NULL; } } -static void -wxe_driver_unload(void) -{ - // fprintf(stderr, "%s:%d: UNLOAD \r\n", __FILE__,__LINE__); -} - static ErlDrvSSizeT wxe_driver_control(ErlDrvData handle, unsigned op, char* buf, ErlDrvSizeT count, @@ -194,7 +181,7 @@ wxe_driver_call(ErlDrvData handle, unsigned int command, if (len > rlen) *res = driver_alloc(len); memcpy((void *) *res, (void *) buf, len); - return len; + return len; } @@ -219,20 +206,20 @@ standard_outputv(ErlDrvData drv_data, ErlIOVec* ev) int i, max; for(i = 0; i < sd->max_bins; i++) { - if(sd->bin[i].from == 0) { - binref = &sd->bin[i]; - break; - } + if(sd->bin[i].from == 0) { + binref = &sd->bin[i]; + break; + } } if(binref == NULL) { /* realloc */ - max = sd->max_bins + DEF_BINS; - driver_realloc(sd->bin, sizeof(WXEBinRef)*max); - for(i=sd->max_bins; i < max; i++) { - sd->bin[i].from = 0; - } - binref = &sd->bin[sd->max_bins]; - sd->max_bins = max; + max = sd->max_bins + DEF_BINS; + driver_realloc(sd->bin, sizeof(WXEBinRef)*max); + for(i=sd->max_bins; i < max; i++) { + sd->bin[i].from = 0; + } + binref = &sd->bin[sd->max_bins]; + sd->max_bins = max; } if(ev->size > 0) { diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h index f9bca049c8..8b4ce2b804 100644 --- a/lib/wx/c_src/wxe_driver.h +++ b/lib/wx/c_src/wxe_driver.h @@ -56,10 +56,8 @@ typedef struct wxe_data_def { void init_glexts(wxe_data*); -int load_native_gui(); int start_native_gui(wxe_data *sd); void stop_native_gui(wxe_data *sd); -void unload_native_gui(); #define FUNC_CALL 13 #define CREATE_PORT 14 diff --git a/lib/wx/c_src/wxe_main.cpp b/lib/wx/c_src/wxe_main.cpp index c7565e33bd..5b65d8a59b 100644 --- a/lib/wx/c_src/wxe_main.cpp +++ b/lib/wx/c_src/wxe_main.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2014-2016. All Rights Reserved. + * Copyright Ericsson AB 2014-2018. 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. @@ -59,15 +59,9 @@ void *wxe_main_loop(void * ); * START AND STOP of driver thread * ************************************************************/ -int load_native_gui() -{ - return 1; -} - int start_native_gui(wxe_data *sd) { int res; - ErlDrvThreadOpts *opts = NULL; wxe_status_m = erl_drv_mutex_create((char *) "wxe_status_m"); wxe_status_c = erl_drv_cond_create((char *)"wxe_status_c"); @@ -79,7 +73,7 @@ int start_native_gui(wxe_data *sd) res = erl_drv_steal_main_thread((char *)"wxwidgets", &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL); #else - opts = erl_drv_thread_opts_create((char *)"wx thread"); + ErlDrvThreadOpts *opts = erl_drv_thread_opts_create((char *)"wx thread"); opts->suggested_stack_size = 8192; res = erl_drv_thread_create((char *)"wxwidgets", &wxe_thread,wxe_main_loop,(void *) sd->pdl,opts); @@ -116,11 +110,6 @@ void stop_native_gui(wxe_data *sd) erl_drv_cond_destroy(wxe_batch_locker_c); } -void unload_native_gui() -{ - -} - /* ************************************************************ * wxWidgets Thread * ************************************************************/ diff --git a/lib/wx/test/wxt b/lib/wx/test/wxt index e720ed94f4..1343542366 100755 --- a/lib/wx/test/wxt +++ b/lib/wx/test/wxt @@ -18,7 +18,7 @@ # # %CopyrightEnd% # -# Usage: mt <args to erlang startup script> +# Usage: wxt <args to erlang startup script> log=test_log_$$ latest=test_log_latest @@ -27,7 +27,7 @@ erlcmd="erl -sname test_server -smp -pa ../ebin $p $args -wx_test_verbose true - echo "Give the following command in order to see the outcome:" echo "" -echo " less test_log$$" +echo " less $log" rm "$latest" 2>/dev/null ln -s "$log" "$latest" |