diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/doc/src/notes.xml | 23 | ||||
-rw-r--r-- | erts/emulator/beam/erl_debug.c | 3 | ||||
-rw-r--r-- | erts/emulator/beam/erl_map.c | 5 | ||||
-rw-r--r-- | erts/emulator/beam/erl_printf_term.c | 8 | ||||
-rw-r--r-- | erts/emulator/beam/erl_term.c | 1 | ||||
-rw-r--r-- | erts/emulator/beam/erl_term.h | 3 | ||||
-rw-r--r-- | erts/emulator/beam/utils.c | 1 | ||||
-rw-r--r-- | erts/emulator/drivers/unix/ttsl_drv.c | 2 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif0.c | 2 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif_list.m4 | 32 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_mkliterals.c | 10 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys.c | 16 | ||||
-rw-r--r-- | erts/emulator/test/match_spec_SUITE.erl | 60 | ||||
-rw-r--r-- | erts/vsn.mk | 2 |
14 files changed, 117 insertions, 51 deletions
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index ab6291614c..bed1ac463d 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,6 +31,29 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 7.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a binary memory leak when printing to shell using + the tty driver (i.e. not -oldshell).</p> + <p> + Own Id: OTP-12941</p> + </item> + <item> + <p> + Fix a bug where the standard error port sometimes crashes + with eagain as the reason.</p> + <p> + Own Id: OTP-12942</p> + </item> + </list> + </section> + +</section> + <section><title>Erts 7.0.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c index 77a1e3d7cb..2dcfb79f00 100644 --- a/erts/emulator/beam/erl_debug.c +++ b/erts/emulator/beam/erl_debug.c @@ -189,6 +189,9 @@ pdisplay1(int to, void *to_arg, Process* p, Eterm obj) case BINARY_DEF: erts_print(to, to_arg, "#Bin"); break; + case MATCHSTATE_DEF: + erts_print(to, to_arg, "#Matchstate"); + break; default: erts_print(to, to_arg, "unknown object %x", obj); } diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index a91e36e3c5..ff2a355309 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -32,7 +32,9 @@ #include "global.h" #include "erl_process.h" #include "error.h" +#define ERL_WANT_HIPE_BIF_WRAPPER__ #include "bif.h" +#undef ERL_WANT_HIPE_BIF_WRAPPER__ #include "erl_binary.h" #include "erl_map.h" @@ -952,8 +954,11 @@ BIF_RETTYPE maps_keys_1(BIF_ALIST_1) { BIF_P->fvalue = BIF_ARG_1; BIF_ERROR(BIF_P, BADMAP); } + /* maps:merge/2 */ +HIPE_WRAPPER_BIF_DISABLE_GC(maps_merge, 2) + BIF_RETTYPE maps_merge_2(BIF_ALIST_2) { if (is_flatmap(BIF_ARG_1)) { if (is_flatmap(BIF_ARG_2)) { diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c index 267c0b3ff4..2917d58932 100644 --- a/erts/emulator/beam/erl_printf_term.c +++ b/erts/emulator/beam/erl_printf_term.c @@ -467,10 +467,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount, } break; case BINARY_DEF: - if (header_is_bin_matchstate(*boxed_val(wobj))) { - PRINT_STRING(res, fn, arg, "#MatchState"); - } - else { + { byte* bytep; Uint bytesize = binary_size_rel(obj,obj_base); Uint bitoffs; @@ -633,6 +630,9 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount, } } break; + case MATCHSTATE_DEF: + PRINT_STRING(res, fn, arg, "#MatchState"); + break; default: PRINT_STRING(res, fn, arg, "<unknown:"); PRINT_POINTER(res, fn, arg, wobj); diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c index 89459fb278..e5050bfaa5 100644 --- a/erts/emulator/beam/erl_term.c +++ b/erts/emulator/beam/erl_term.c @@ -91,6 +91,7 @@ unsigned tag_val_def(Wterm x) case (_TAG_HEADER_REFC_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF; case (_TAG_HEADER_HEAP_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF; case (_TAG_HEADER_SUB_BIN >> _TAG_PRIMARY_SIZE): return BINARY_DEF; + case (_TAG_HEADER_BIN_MATCHSTATE >> _TAG_PRIMARY_SIZE): return MATCHSTATE_DEF; } break; diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index 90e35151b0..d5e91d80d9 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -1136,8 +1136,9 @@ _ET_DECLARE_CHECKED(Uint,y_reg_index,Uint) #define FLOAT_DEF 0xe #define BIG_DEF 0xf #define SMALL_DEF 0x10 +#define MATCHSTATE_DEF 0x11 /* not a "real" term */ -#define FIRST_VACANT_TAG_DEF 0x11 +#define FIRST_VACANT_TAG_DEF 0x12 #if ET_DEBUG extern unsigned tag_val_def_debug(Wterm, const char*, unsigned); diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 342e91e983..e9d7c91ac9 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -844,7 +844,6 @@ Uint32 make_hash(Eterm term_arg) Eterm hash = 0; unsigned op; - /* Must not collide with the real tag_val_def's: */ #define MAKE_HASH_TUPLE_OP (FIRST_VACANT_TAG_DEF) #define MAKE_HASH_TERM_ARRAY_OP (FIRST_VACANT_TAG_DEF+1) #define MAKE_HASH_CDR_PRE_OP (FIRST_VACANT_TAG_DEF+2) diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c index 0f773b69fb..53146e71f0 100644 --- a/erts/emulator/drivers/unix/ttsl_drv.c +++ b/erts/emulator/drivers/unix/ttsl_drv.c @@ -720,6 +720,7 @@ static void ttysl_from_erlang(ErlDrvData ttysl_data, char* buf, ErlDrvSizeT coun } driver_enq_bin(ttysl_port,putcbuf,0,putcpos); + driver_free_binary(putcbuf); if (sz == 0) { for (;;) { @@ -1207,6 +1208,7 @@ static int outc(int c) putcbuf->orig_bytes[putcpos++] = c; if (putcpos == putclen) { driver_enq_bin(ttysl_port,putcbuf,0,putclen); + driver_free_binary(putcbuf); putcpos = 0; putclen = TTY_BUFFSIZE; putcbuf = driver_alloc_binary(BUFSIZ); diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index efbe951ce5..cc68e1f74d 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -1741,7 +1741,7 @@ BIF_RETTYPE hipe_bifs_check_crc_1(BIF_ALIST_1) if (!term_to_Uint(BIF_ARG_1, &crc)) BIF_ERROR(BIF_P, BADARG); - if (crc == HIPE_SYSTEM_CRC) + if (crc == HIPE_ERTS_CHECKSUM) BIF_RET(am_true); BIF_RET(am_false); } diff --git a/erts/emulator/hipe/hipe_bif_list.m4 b/erts/emulator/hipe/hipe_bif_list.m4 index b3bd5e4357..6aa0c9a32e 100644 --- a/erts/emulator/hipe/hipe_bif_list.m4 +++ b/erts/emulator/hipe/hipe_bif_list.m4 @@ -269,21 +269,23 @@ noproc_primop_interface_1(nbif_atomic_inc, hipe_atomic_inc) /* BIFs that disable GC while trapping are called via a wrapper * to reserve stack space for the "trap frame". */ -define(CFUN,`ifelse($1,term_to_binary_1,hipe_wrapper_term_to_binary_1, -ifelse($1,term_to_binary_2,hipe_wrapper_term_to_binary_2, -ifelse($1,binary_to_term_1,hipe_wrapper_binary_to_term_1, -ifelse($1,binary_to_term_2,hipe_wrapper_binary_to_term_2, -ifelse($1,binary_to_list_1,hipe_wrapper_binary_to_list_1, -ifelse($1,binary_to_list_3,hipe_wrapper_binary_to_list_3, -ifelse($1,bitstring_to_list_1,hipe_wrapper_bitstring_to_list_1, -ifelse($1,list_to_binary_1,hipe_wrapper_list_to_binary_1, -ifelse($1,iolist_to_binary_1,hipe_wrapper_iolist_to_binary_1, -ifelse($1,binary_list_to_bin_1,hipe_wrapper_binary_list_to_bin_1, -ifelse($1,list_to_bitstring_1,hipe_wrapper_list_to_bitstring_1, -ifelse($1,send_2,hipe_wrapper_send_2, -ifelse($1,send_3,hipe_wrapper_send_3, -ifelse($1,ebif_bang_2,hipe_wrapper_ebif_bang_2, -$1))))))))))))))') +define(CFUN,`ifelse( +$1, term_to_binary_1, hipe_wrapper_$1, +$1, term_to_binary_2, hipe_wrapper_$1, +$1, binary_to_term_1, hipe_wrapper_$1, +$1, binary_to_term_2, hipe_wrapper_$1, +$1, binary_to_list_1, hipe_wrapper_$1, +$1, binary_to_list_3, hipe_wrapper_$1, +$1, bitstring_to_list_1, hipe_wrapper_$1, +$1, list_to_binary_1, hipe_wrapper_$1, +$1, iolist_to_binary_1, hipe_wrapper_$1, +$1, binary_list_to_bin_1, hipe_wrapper_$1, +$1, list_to_bitstring_1, hipe_wrapper_$1, +$1, send_2, hipe_wrapper_$1, +$1, send_3, hipe_wrapper_$1, +$1, ebif_bang_2, hipe_wrapper_$1, +$1, maps_merge_2, hipe_wrapper_$1, +$1)') define(BIF_LIST,`standard_bif_interface_$3(nbif_$4, CFUN($4))') include(TARGET/`erl_bif_list.h') diff --git a/erts/emulator/hipe/hipe_mkliterals.c b/erts/emulator/hipe/hipe_mkliterals.c index aa12df2932..dfa5313739 100644 --- a/erts/emulator/hipe/hipe_mkliterals.c +++ b/erts/emulator/hipe/hipe_mkliterals.c @@ -269,9 +269,6 @@ static const struct literal { /* freason codes */ { "FREASON_TRAP", TRAP }, - /* special Erlang constants */ - { "THE_NON_VALUE", (int)THE_NON_VALUE }, - /* funs */ #ifdef HIPE { "EFE_NATIVE_ADDRESS", offsetof(struct erl_fun_entry, native_address) }, @@ -526,6 +523,8 @@ static const struct rts_param rts_params[] = { { 49, "P_MSG_FIRST", 1, offsetof(struct process, msg.first) }, { 50, "P_MSG_SAVE", 1, offsetof(struct process, msg.save) }, { 51, "P_CALLEE_EXP", 1, offsetof(struct process, hipe.u.callee_exp) }, + + { 52, "THE_NON_VALUE", 1, (int)THE_NON_VALUE }, }; #define NR_PARAMS ARRAY_SIZE(rts_params) @@ -543,6 +542,8 @@ static void compute_crc(void) crc_value = crc_update_int(crc_value, &literals[i].value); crc_value &= 0x07FFFFFF; literals_crc = crc_value; + + crc_value = crc_init(); for (i = 0; i < NR_PARAMS; ++i) if (rts_params[i].is_defined) crc_value = crc_update_int(crc_value, &rts_params[i].value); @@ -628,6 +629,7 @@ static int do_c(FILE *fp, const char* this_exe) print_params(fp, c_define_param); fprintf(fp, "#define HIPE_LITERALS_CRC %uU\n", literals_crc); fprintf(fp, "#define HIPE_SYSTEM_CRC %uU\n", system_crc); + fprintf(fp, "#define HIPE_ERTS_CHECKSUM (HIPE_LITERALS_CRC ^ HIPE_SYSTEM_CRC)\n"); fprintf(fp, "\n"); fprintf(fp, "#define RTS_PARAMS_CASES"); print_params(fp, c_case_param); @@ -645,12 +647,14 @@ static int do_e(FILE *fp, const char* this_exe) fprintf(fp, "\n"); print_params(fp, e_define_param); fprintf(fp, "\n"); + fprintf(fp, "-define(HIPE_LITERALS_CRC, %u).\n", literals_crc); if (is_xcomp) { fprintf(fp, "-define(HIPE_SYSTEM_CRC, %u).\n", system_crc); } else { fprintf(fp, "-define(HIPE_SYSTEM_CRC, hipe_bifs:system_crc()).\n"); } + fprintf(fp, "-define(HIPE_ERTS_CHECKSUM, (?HIPE_LITERALS_CRC bxor ?HIPE_SYSTEM_CRC)).\n"); return 0; } diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index b036b20b7b..8d7da3e47e 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -2527,7 +2527,7 @@ fd_async(void *async_data) SysIOVec *iov0; SysIOVec *iov; int iovlen; - int err; + int err = 0; /* much of this code is stolen from efile_drv:invoke_writev */ driver_pdl_lock(dd->blocking->pdl); iov0 = driver_peekq(dd->port_num, &iovlen); @@ -2542,8 +2542,11 @@ fd_async(void *async_data) memcpy(iov,iov0,iovlen*sizeof(SysIOVec)); driver_pdl_unlock(dd->blocking->pdl); - res = writev(dd->ofd, iov, iovlen); - err = errno; + do { + res = writev(dd->ofd, iov, iovlen); + } while (res < 0 && errno == EINTR); + if (res < 0) + err = errno; erts_free(ERTS_ALC_T_SYS_WRITE_BUF, iov); } @@ -2582,7 +2585,12 @@ void fd_ready_async(ErlDrvData drv_data, return /* 0; */; } } else if (dd->blocking->res < 0) { - driver_failure_posix(port_num, dd->blocking->err); + if (dd->blocking->err == ERRNO_BLOCK) { + set_busy_port(port_num, 1); + /* still data left to write in queue */ + driver_async(port_num, &dd->blocking->pkey, fd_async, dd, NULL); + } else + driver_failure_posix(port_num, dd->blocking->err); return; /* -1; */ } return; /* 0; */ diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index c6cc414bba..3f986ca2ed 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -170,12 +170,11 @@ test_1(Config) when is_list(Config) -> [{['$1','$1'],[{is_atom, '$1'}],[kakalorum]}], [{call, {?MODULE, f2, [a, a]}}]), -% case tr0(fun() -> ?MODULE:f2(a, a) end, -% {?MODULE, f2, 2}, -% [{['$1','$1'],[{is_atom, '$1'}],[{message, {process_dump}}]}]) of -% [{trace, _, call, {?MODULE, f2, [a, a]}, Bin}] -> -% erlang:display(binary_to_list(Bin)) -% end, + %% Verify that 'process_dump' can handle a matchstate on the stack. + tr(fun() -> fbinmatch(<<0>>, 0) end, + {?MODULE, f1, 1}, + [{['_'],[],[{message, {process_dump}}]}], + [fun({trace, _, call, {?MODULE, f1, [0]}, _Bin}) -> true end]), % Error cases ?line errchk([{['$1','$1'],[{is_atom, '$1'}],[{banka, kanin}]}]), @@ -999,14 +998,14 @@ tr(Fun, MFA, TraceFlags, Pat, PatFlags, Expected0) -> erlang:trace(P, true, TraceFlags), erlang:trace_pattern(MFA, Pat, PatFlags), lists:map( - fun(X) -> - list_to_tuple([trace, P | tuple_to_list(X)]) + fun(X) when is_function(X,1) -> X; + (X) -> list_to_tuple([trace, P | tuple_to_list(X)]) end, Expected0) end). tr(RunFun, ControlFun) -> - P = spawn(?MODULE, runner, [self(), RunFun]), + P = spawn_link(?MODULE, runner, [self(), RunFun]), collect(P, ControlFun(P)). collect(P, TMs) -> @@ -1025,18 +1024,33 @@ collect([]) -> collect([TM | TMs]) -> ?t:format( "Expecting: ~p~n", [TM]), receive - M -> - case if element(1, M) == trace_ts -> - list_to_tuple(lists:reverse( - tl(lists:reverse(tuple_to_list(M))))); - true -> M - end of - TM -> - ?t:format("Got: ~p~n", [M]), - collect(TMs); - _ -> - ?t:format("Got unexpected: ~p~n", [M]), - flush({got_unexpected,M}) + M0 -> + M = case element(1, M0) of + trace_ts -> + list_to_tuple(lists:reverse( + tl(lists:reverse(tuple_to_list(M0))))); + _ -> M0 + end, + case is_function(TM,1) of + true -> + case (catch TM(M)) of + true -> + ?t:format("Got: ~p~n", [M]), + collect(TMs); + _ -> + ?t:format("Got unexpected: ~p~n", [M]), + flush({got_unexpected,M}) + end; + + false -> + case M of + TM -> + ?t:format("Got: ~p~n", [M]), + collect(TMs); + _ -> + ?t:format("Got unexpected: ~p~n", [M]), + flush({got_unexpected,M}) + end end end. @@ -1116,6 +1130,10 @@ fn(X, Y) -> fn(X, Y, Z) -> [X, Y, Z]. +fbinmatch(<<Int, Rest/binary>>, Acc) -> + fbinmatch(Rest, [?MODULE:f1(Int) | Acc]); +fbinmatch(<<>>, Acc) -> Acc. + id(X) -> X. diff --git a/erts/vsn.mk b/erts/vsn.mk index 478f581f13..38b9a13e63 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 7.0.2 +VSN = 7.0.3 # Port number 4365 in 4.2 # Port number 4366 in 4.3 |