aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/Makefile20
-rw-r--r--erts/doc/src/fascicules.xml18
-rw-r--r--erts/doc/src/notes.xml126
-rw-r--r--erts/doc/src/part_notes.xml38
-rw-r--r--erts/doc/src/part_notes_history.xml36
-rw-r--r--erts/emulator/beam/beam_bp.c85
-rw-r--r--erts/emulator/beam/erl_message.c13
-rw-r--r--erts/emulator/nifs/common/zlib_nif.c127
-rw-r--r--erts/emulator/test/distribution_SUITE.erl67
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl48
-rw-r--r--erts/preloaded/ebin/zlib.beambin19120 -> 19492 bytes
-rw-r--r--erts/preloaded/src/zlib.erl38
-rw-r--r--erts/vsn.mk2
13 files changed, 378 insertions, 240 deletions
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile
index b96cbbce40..1f591a5cff 100644
--- a/erts/doc/src/Makefile
+++ b/erts/doc/src/Makefile
@@ -1,7 +1,7 @@
-#
+#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-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.
@@ -16,7 +16,7 @@
# limitations under the License.
#
# %CopyrightEnd%
-#
+#
SPECS_ESRC = ../../preloaded/src/
@@ -66,9 +66,7 @@ XML_REF3_FILES = \
zlib.xml
XML_PART_FILES = \
- part.xml \
- part_notes.xml \
- part_notes_history.xml
+ part.xml
XML_CHAPTER_FILES = \
tty.xml \
@@ -116,9 +114,9 @@ SPECS_FILES = $(XML_REF3_EFILES:%.xml=$(SPECDIR)/specs_%.xml)
TOP_SPECS_FILE = specs.xml
# ----------------------------------------------------
-# FLAGS
+# FLAGS
# ----------------------------------------------------
-XML_FLAGS +=
+XML_FLAGS +=
KERNEL_SRC=$(ERL_TOP)/lib/kernel/src
KERNEL_INCLUDE=$(ERL_TOP)/lib/kernel/include
@@ -146,7 +144,7 @@ $(INFO_FILE): $(INFO_FILE_SRC) $(ERL_TOP)/make/$(TARGET)/otp.mk
sed -e 's;%RELEASE%;$(SYSTEM_VSN);' $(INFO_FILE_SRC) > $(INFO_FILE)
-debug opt:
+debug opt:
clean:
rm -rf $(HTMLDIR)/*
@@ -154,7 +152,7 @@ clean:
rm -f $(MAN3DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
rm -f $(SPECDIR)/*
- rm -f errs core *~
+ rm -f errs core *~
$(SPECDIR)/specs_%.xml:
escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
@@ -162,7 +160,7 @@ $(SPECDIR)/specs_%.xml:
# ----------------------------------------------------
# Release Target
-# ----------------------------------------------------
+# ----------------------------------------------------
include $(ERL_TOP)/make/otp_release_targets.mk
release_docs_spec: docs
diff --git a/erts/doc/src/fascicules.xml b/erts/doc/src/fascicules.xml
deleted file mode 100644
index 1c371bd9c8..0000000000
--- a/erts/doc/src/fascicules.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
-
-<fascicules>
- <fascicule file="part" href="part_frame.html" entry="no">
- ERTS User's Guide
- </fascicule>
- <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
- ERTS Reference Manual
- </fascicule>
- <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
- Release Notes
- </fascicule>
- <fascicule file="" href="../../../doc/print.html" entry="no">
- Off-Print
- </fascicule>
-</fascicules>
-
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 1a5bea8820..e4cb101a4f 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -31,6 +31,47 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 9.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed bug that could cause a VM crash when a corrupt
+ message is received on distribution channel from other
+ node.</p>
+ <p>
+ Own Id: OTP-14661 Aux Id: ERIERL-80 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 9.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The new zlib module returned a data_error when
+ inflating concatenated streams, which was incompatible
+ with the old module's behavior of returning the
+ uncompressed data up to the end of the first stream.</p>
+ <p>
+ Own Id: OTP-14648</p>
+ </item>
+ <item>
+ <p>zlib:gunzip/1 will no longer stop at the end of the
+ first stream when decompressing concatenated gzip
+ files.</p>
+ <p>
+ Own Id: OTP-14649</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 9.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -959,6 +1000,91 @@
</section>
+<section><title>Erts 8.3.5.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A timer internal bit-field used for storing scheduler id
+ was too small. As a result, VM internal timer data
+ structures could become inconsistent when using 1024
+ schedulers on the system. Note that systems with less
+ than 1024 schedulers are not effected by this bug.</p>
+ <p>
+ This bug was introduced in ERTS version 7.0 (OTP 18.0).</p>
+ <p>
+ Own Id: OTP-14548 Aux Id: OTP-11997, ERL-468 </p>
+ </item>
+ <item>
+ <p>
+ Fixed bug in <c>binary_to_term</c> and
+ <c>binary_to_atom</c> that could cause VM crash.
+ Typically happens when the last character of an UTF8
+ string is in the range 128 to 255, but truncated to only
+ one byte. Bug exists in <c>binary_to_term</c> since ERTS
+ version 5.10.2 (OTP_R16B01) and <c>binary_to_atom</c>
+ since ERTS version 9.0 (OTP-20.0).</p>
+ <p>
+ Own Id: OTP-14590 Aux Id: ERL-474 </p>
+ </item>
+ <item>
+ <p>
+ Fix bug causing VM crash when a module with
+ <c>-on_load</c> directive is loaded while
+ <c>erlang:trace(on_load, ...)</c> is enabled.</p>
+ <p>
+ Own Id: OTP-14612</p>
+ </item>
+ <item>
+ <p>
+ Fixed bug that could cause a VM crash when a corrupt
+ message is received on distribution channel from other
+ node.</p>
+ <p>
+ Own Id: OTP-14661 Aux Id: ERIERL-80 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 8.3.5.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix performance bug in pre-allocators that could cause
+ them to permanently fall back on normal more expensive
+ memory allocation. Pre-allocators are used for quick
+ allocation of short lived meta data used by messages and
+ other scheduled tasks. Bug exists since OTP_R15B02.</p>
+ <p>
+ Own Id: OTP-14491</p>
+ </item>
+ <item>
+ <p>Fixed a bug that prevented TCP sockets from being
+ closed properly on send timeouts.</p>
+ <p>
+ Own Id: OTP-14509</p>
+ </item>
+ <item>
+ <p>
+ Fixed bug in operator <c>bxor</c> causing erroneuos
+ result when one operand is a big <em>negative</em>
+ integer with the lowest <c>N*W</c> bits as zero and the
+ other operand not larger than <c>N*W</c> bits. <c>N</c>
+ is an integer of 1 or larger and <c>W</c> is 32 or 64
+ depending on word size.</p>
+ <p>
+ Own Id: OTP-14514</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 8.3.5.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/erts/doc/src/part_notes.xml b/erts/doc/src/part_notes.xml
deleted file mode 100644
index e579b7635d..0000000000
--- a/erts/doc/src/part_notes.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2004</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- 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.
-
- </legalnotice>
-
- <title>ERTS Release Notes</title>
- <prepared></prepared>
- <docno></docno>
- <date>2004-09-07</date>
- <rev>1.0</rev>
- </header>
- <description>
- <p>The Erlang Runtime System application <em>ERTS</em>.</p>
- <p>For information about older versions, see
- <url href="part_notes_history_frame.html">Release Notes History</url>.</p>
- </description>
- <xi:include href="notes.xml"/>
-</part>
-
diff --git a/erts/doc/src/part_notes_history.xml b/erts/doc/src/part_notes_history.xml
deleted file mode 100644
index 277683a2b5..0000000000
--- a/erts/doc/src/part_notes_history.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2006</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- 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.
-
- </legalnotice>
-
- <title>ERTS Release Notes History</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- </header>
- <description>
- <p>The Erlang Runtime System application <em>ERTS</em>.</p>
- </description>
- <xi:include href="notes_history.xml"/>
-</part>
-
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c
index 950639f7ae..069e7391fd 100644
--- a/erts/emulator/beam/beam_bp.c
+++ b/erts/emulator/beam/beam_bp.c
@@ -642,6 +642,49 @@ erts_clear_export_break(Module* modp, ErtsCodeInfo *ci)
ASSERT(ci->u.gen_bp == NULL);
}
+/*
+ * If c_p->cp is a trace return instruction, we set cp
+ * to be the place where we again start to execute code.
+ *
+ * cp is used by match spec {caller} to get the calling
+ * function, and if we don't do this fixup it will be
+ * 'undefined'. This has the odd side effect of {caller}
+ * not really being which function is the caller, but
+ * rather which function we are about to return to.
+ */
+static void fixup_cp_before_trace(Process *c_p, int *return_to_trace)
+{
+ Eterm *cpp, *E = c_p->stop;
+ BeamInstr w = *c_p->cp;
+ if (w == (BeamInstr) BeamOp(op_return_trace)) {
+ cpp = &E[2];
+ } else if (w == (BeamInstr) BeamOp(op_i_return_to_trace)) {
+ *return_to_trace = 1;
+ cpp = &E[0];
+ } else if (w == (BeamInstr) BeamOp(op_i_return_time_trace)) {
+ cpp = &E[0];
+ } else {
+ cpp = NULL;
+ }
+ if (cpp) {
+ for (;;) {
+ BeamInstr w = *cp_val(*cpp);
+ if (w == (BeamInstr) BeamOp(op_return_trace)) {
+ cpp += 3;
+ } else if (w == (BeamInstr) BeamOp(op_i_return_to_trace)) {
+ *return_to_trace = 1;
+ cpp += 1;
+ } else if (w == (BeamInstr) BeamOp(op_i_return_time_trace)) {
+ cpp += 2;
+ } else {
+ break;
+ }
+ }
+ c_p->cp = (BeamInstr *) cp_val(*cpp);
+ ASSERT(is_CP(*cpp));
+ }
+}
+
BeamInstr
erts_generic_breakpoint(Process* c_p, ErtsCodeInfo *info, Eterm* reg)
{
@@ -752,6 +795,7 @@ erts_bif_trace(int bif_index, Process* p, Eterm* args, BeamInstr* I)
GenericBp* g;
GenericBpData* bp = NULL;
Uint bp_flags = 0;
+ int return_to_trace = 0;
ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
@@ -767,6 +811,8 @@ erts_bif_trace(int bif_index, Process* p, Eterm* args, BeamInstr* I)
*/
if (!applying) {
p->cp = I;
+ } else {
+ fixup_cp_before_trace(p, &return_to_trace);
}
if (bp_flags & (ERTS_BPF_LOCAL_TRACE|ERTS_BPF_GLOBAL_TRACE) &&
IS_TRACED_FL(p, F_TRACE_CALLS)) {
@@ -945,49 +991,20 @@ static ErtsTracer
do_call_trace(Process* c_p, ErtsCodeInfo* info, Eterm* reg,
int local, Binary* ms, ErtsTracer tracer)
{
- Eterm* cpp;
int return_to_trace = 0;
- BeamInstr w;
BeamInstr *cp_save = c_p->cp;
Uint32 flags;
Uint need = 0;
Eterm* E = c_p->stop;
- w = *c_p->cp;
- if (w == (BeamInstr) BeamOp(op_return_trace)) {
- cpp = &E[2];
- } else if (w == (BeamInstr) BeamOp(op_i_return_to_trace)) {
- return_to_trace = 1;
- cpp = &E[0];
- } else if (w == (BeamInstr) BeamOp(op_i_return_time_trace)) {
- cpp = &E[0];
- } else {
- cpp = NULL;
- }
- if (cpp) {
- for (;;) {
- BeamInstr w = *cp_val(*cpp);
- if (w == (BeamInstr) BeamOp(op_return_trace)) {
- cpp += 3;
- } else if (w == (BeamInstr) BeamOp(op_i_return_to_trace)) {
- return_to_trace = 1;
- cpp += 1;
- } else if (w == (BeamInstr) BeamOp(op_i_return_time_trace)) {
- cpp += 2;
- } else {
- break;
- }
- }
- cp_save = c_p->cp;
- c_p->cp = (BeamInstr *) cp_val(*cpp);
- ASSERT(is_CP(*cpp));
- }
+ fixup_cp_before_trace(c_p, &return_to_trace);
+
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
flags = erts_call_trace(c_p, info, ms, reg, local, &tracer);
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
- if (cpp) {
- c_p->cp = cp_save;
- }
+
+ /* restore cp after potential fixup */
+ c_p->cp = cp_save;
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
if ((flags & MATCH_SET_RETURN_TO_TRACE) && !return_to_trace) {
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index c1af70592a..b30c4a49d7 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -568,14 +568,11 @@ erts_msg_attached_data_size_aux(ErtsMessage *msg)
sz = erts_decode_dist_ext_size(msg->data.dist_ext);
if (sz < 0) {
- /* Bad external; remove it */
- if (is_not_nil(ERL_MESSAGE_TOKEN(msg))) {
- ErlHeapFragment *heap_frag;
- heap_frag = erts_dist_ext_trailer(msg->data.dist_ext);
- erts_cleanup_offheap(&heap_frag->off_heap);
- }
- erts_free_dist_ext_copy(msg->data.dist_ext);
- msg->data.dist_ext = NULL;
+ /* Bad external
+ * We leave the message intact in this case as it's not worth the trouble
+ * to make all callers remove it from queue. It will be detected again
+ * and removed from message queue later anyway.
+ */
return 0;
}
diff --git a/erts/emulator/nifs/common/zlib_nif.c b/erts/emulator/nifs/common/zlib_nif.c
index a1a65e1946..a9c5b05e47 100644
--- a/erts/emulator/nifs/common/zlib_nif.c
+++ b/erts/emulator/nifs/common/zlib_nif.c
@@ -69,11 +69,27 @@ typedef enum {
ST_DEFLATE = 1,
ST_INFLATE = 2,
ST_CLOSED = 3
-} zlib_state;
+} zlib_state_t;
+
+/* Controls what to do when the user attempts to decompress more data after
+ * Z_STREAM_END has been returned:
+ *
+ * - 'cut' wipes all further input and returns empty results until reset by
+ * the user. This is the default behavior, matching that of the old driver.
+ * - 'reset' resets the state without discarding any input, making it possible
+ * to decompress blindly concatenated streams.
+ * - 'error' crashes with a data error. */
+typedef enum {
+ EOS_BEHAVIOR_ERROR = 0,
+ EOS_BEHAVIOR_RESET = 1,
+ EOS_BEHAVIOR_CUT = 2
+} zlib_eos_behavior_t;
typedef struct {
z_stream s;
- zlib_state state;
+ zlib_state_t state;
+
+ zlib_eos_behavior_t eos_behavior;
/* These refer to the plaintext CRC, and are only needed for zlib:crc32/1
* which is deprecated. */
@@ -102,7 +118,6 @@ typedef struct {
static ERL_NIF_TERM zlib_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_close(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_deflateInit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM zlib_deflateInit2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_deflateSetDictionary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_deflateReset(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_deflateEnd(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
@@ -110,7 +125,6 @@ static ERL_NIF_TERM zlib_deflateParams(ErlNifEnv *env, int argc, const ERL_NIF_T
static ERL_NIF_TERM zlib_deflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_inflateInit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM zlib_inflateInit2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_inflateSetDictionary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_inflateGetDictionary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM zlib_inflateReset(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
@@ -130,8 +144,7 @@ static ERL_NIF_TERM zlib_enqueue_input(ErlNifEnv *env, int argc, const ERL_NIF_T
static ErlNifFunc nif_funcs[] = {
/* deflate */
- {"deflateInit_nif", 2, zlib_deflateInit},
- {"deflateInit_nif", 6, zlib_deflateInit2},
+ {"deflateInit_nif", 6, zlib_deflateInit},
{"deflateSetDictionary_nif", 2, zlib_deflateSetDictionary},
{"deflateReset_nif", 1, zlib_deflateReset},
{"deflateEnd_nif", 1, zlib_deflateEnd},
@@ -139,8 +152,7 @@ static ErlNifFunc nif_funcs[] = {
{"deflate_nif", 4, zlib_deflate},
/* inflate */
- {"inflateInit_nif", 1, zlib_inflateInit},
- {"inflateInit_nif", 2, zlib_inflateInit2},
+ {"inflateInit_nif", 3, zlib_inflateInit},
{"inflateSetDictionary_nif", 2, zlib_inflateSetDictionary},
{"inflateGetDictionary_nif", 1, zlib_inflateGetDictionary},
{"inflateReset_nif", 1, zlib_inflateReset},
@@ -509,9 +521,11 @@ static ERL_NIF_TERM zlib_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[
d->s.opaque = d;
d->s.data_type = Z_BINARY;
- d->state = ST_NONE;
+ d->eos_behavior = EOS_BEHAVIOR_CUT;
d->eos_seen = 0;
+ d->state = ST_NONE;
+
d->want_output_crc = 0;
d->want_input_crc = 0;
d->is_raw_stream = 0;
@@ -551,42 +565,6 @@ static ERL_NIF_TERM zlib_close(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv
static ERL_NIF_TERM zlib_deflateInit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
zlib_data_t *d;
- int level, res;
-
- if(argc != 2 || !get_zlib_data(env, argv[0], &d) ||
- !enif_get_int(env, argv[1], &level)) {
- return enif_make_badarg(env);
- } else if(!zlib_process_check(env, d)) {
- return enif_raise_exception(env, am_not_on_controlling_process);
- } else if(d->state != ST_NONE) {
- return enif_raise_exception(env, am_already_initialized);
- }
-
- res = deflateInit(&d->s, level);
-
- if(res == Z_OK) {
- d->state = ST_DEFLATE;
- d->eos_seen = 0;
-
- /* FIXME: crc32/1 is documented as returning "the current calculated
- * checksum," but failed to mention that the old implementation only
- * calculated it when WindowBits < 0 (See zlib_deflateInit2).
- *
- * We could fix this behavior by setting d->want_input_crc to 1 here,
- * but we've decided to retain this quirk since the performance hit is
- * quite significant. */
- d->want_output_crc = 0;
- d->want_input_crc = 0;
-
- d->output_crc = crc32(0L, Z_NULL, 0);
- d->input_crc = crc32(0L, Z_NULL, 0);
- }
-
- return zlib_return(env, res);
-}
-
-static ERL_NIF_TERM zlib_deflateInit2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
- zlib_data_t *d;
int level, method, windowBits, memLevel, strategy, res;
if(argc != 6 || !get_zlib_data(env, argv[0], &d)
@@ -741,39 +719,12 @@ static ERL_NIF_TERM zlib_deflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar
static ERL_NIF_TERM zlib_inflateInit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
zlib_data_t *d;
- int res;
- if(argc != 1 || !get_zlib_data(env, argv[0], &d)) {
- return enif_make_badarg(env);
- } else if(!zlib_process_check(env, d)) {
- return enif_raise_exception(env, am_not_on_controlling_process);
- } else if(d->state != ST_NONE) {
- return enif_raise_exception(env, am_already_initialized);
- }
-
- res = inflateInit(&d->s);
-
- if(res == Z_OK) {
- d->state = ST_INFLATE;
- d->eos_seen = 0;
-
- d->want_output_crc = 0;
- d->want_input_crc = 0;
- d->is_raw_stream = 0;
-
- d->output_crc = crc32(0L, Z_NULL, 0);
- d->input_crc = crc32(0L, Z_NULL, 0);
- }
-
- return zlib_return(env, res);
-}
+ int windowBits, eosBehavior, res;
-static ERL_NIF_TERM zlib_inflateInit2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
- zlib_data_t *d;
- int windowBits, res;
-
- if(argc != 2 || !get_zlib_data(env, argv[0], &d)
- || !enif_get_int(env, argv[1], &windowBits)) {
+ if(argc != 3 || !get_zlib_data(env, argv[0], &d)
+ || !enif_get_int(env, argv[1], &windowBits)
+ || !enif_get_int(env, argv[2], &eosBehavior)) {
return enif_make_badarg(env);
} else if(!zlib_process_check(env, d)) {
return enif_raise_exception(env, am_not_on_controlling_process);
@@ -785,6 +736,8 @@ static ERL_NIF_TERM zlib_inflateInit2(ErlNifEnv *env, int argc, const ERL_NIF_TE
if(res == Z_OK) {
d->state = ST_INFLATE;
+
+ d->eos_behavior = eosBehavior;
d->eos_seen = 0;
d->is_raw_stream = (windowBits < 0);
@@ -934,6 +887,28 @@ static ERL_NIF_TERM zlib_inflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar
return enif_raise_exception(env, am_not_initialized);
}
+ if(d->eos_seen) {
+ int res;
+
+ switch(d->eos_behavior) {
+ case EOS_BEHAVIOR_ERROR:
+ return zlib_return(env, Z_DATA_ERROR);
+ case EOS_BEHAVIOR_RESET:
+ res = inflateReset(&d->s);
+
+ if(res != Z_OK) {
+ return zlib_return(env, res);
+ }
+
+ d->eos_seen = 0;
+ break;
+ case EOS_BEHAVIOR_CUT:
+ zlib_reset_input(d);
+
+ return enif_make_tuple2(env, am_finished, enif_make_list(env, 0));
+ }
+ }
+
return zlib_codec(&inflate, env, d, input_chunk_size, output_chunk_size, flush);
}
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index b4ec99f902..4a0b299e03 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -56,6 +56,7 @@
bad_dist_ext_process_info/1,
bad_dist_ext_control/1,
bad_dist_ext_connection_id/1,
+ bad_dist_ext_size/1,
start_epmd_false/1, epmd_module/1]).
%% Internal exports.
@@ -92,6 +93,7 @@ groups() ->
[dist_auto_connect_never, dist_auto_connect_once]},
{bad_dist_ext, [],
[bad_dist_ext_receive, bad_dist_ext_process_info,
+ bad_dist_ext_size,
bad_dist_ext_control, bad_dist_ext_connection_id]}].
%% Tests pinging a node in different ways.
@@ -1672,6 +1674,57 @@ bad_dist_ext_connection_id(Config) when is_list(Config) ->
stop_node(Offender),
stop_node(Victim).
+%% OTP-14661: Bad message is discovered by erts_msg_attached_data_size
+bad_dist_ext_size(Config) when is_list(Config) ->
+ {ok, Offender} = start_node(bad_dist_ext_process_info_offender),
+ %%Prog = "Prog=/home/uabseri/src/otp_new3/bin/cerl -rr -debug",
+ Prog = [],
+ {ok, Victim} = start_node(bad_dist_ext_process_info_victim, [], Prog),
+ start_node_monitors([Offender,Victim]),
+
+ Parent = self(),
+ P = spawn_link(Victim,
+ fun () ->
+ Parent ! {self(), started},
+ receive check_msgs -> ok end, %% DID CRASH HERE
+ bad_dist_ext_check_msgs([one]),
+ Parent ! {self(), messages_checked}
+ end),
+
+ receive {P, started} -> ok end,
+ P ! one,
+
+ Suspended = make_ref(),
+ S = spawn(Victim,
+ fun () ->
+ erlang:suspend_process(P),
+ Parent ! Suspended,
+ receive after infinity -> ok end
+ end),
+
+ receive Suspended -> ok end,
+ pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ verify_up(Offender, Victim),
+ send_bad_msgs(Offender, P, 1, dmsg_bad_tag()),
+
+ %% Make sure bad msgs has reached Victim
+ rpc:call(Offender, rpc, call, [Victim, erlang, node, []]),
+
+ verify_still_up(Offender, Victim),
+
+ rpc:call(Victim, erlang, process_info, [P, total_heap_size]),
+
+ verify_down(Offender, connection_closed, Victim, killed),
+
+ P ! check_msgs,
+ exit(S, bang), % resume Victim
+ receive {P, messages_checked} -> ok end,
+
+ unlink(P),
+ verify_no_down(Offender, Victim),
+ stop_node(Offender),
+ stop_node(Victim).
+
bad_dist_struct_check_msgs([]) ->
receive
@@ -1775,9 +1828,12 @@ send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
send_bad_msg(BadNode, To) ->
send_bad_msgs(BadNode, To, 1).
-send_bad_msgs(BadNode, To, Repeat) when is_atom(BadNode),
- is_pid(To),
- is_integer(Repeat) ->
+send_bad_msgs(BadNode, To, Repeat) ->
+ send_bad_msgs(BadNode, To, Repeat, dmsg_bad_atom_cache_ref()).
+
+send_bad_msgs(BadNode, To, Repeat, BadTerm) when is_atom(BadNode),
+ is_pid(To),
+ is_integer(Repeat) ->
Parent = self(),
Done = make_ref(),
spawn_link(BadNode,
@@ -1787,7 +1843,7 @@ send_bad_msgs(BadNode, To, Repeat) when is_atom(BadNode),
DPrt = dport(Node),
DData = [dmsg_hdr(),
dmsg_ext({?DOP_SEND, ?COOKIE, To}),
- dmsg_bad_atom_cache_ref()],
+ BadTerm],
repeat(fun () -> port_command(DPrt, DData) end, Repeat),
Parent ! Done
end),
@@ -1874,6 +1930,9 @@ dmsg_ext(Term) ->
dmsg_bad_atom_cache_ref() ->
[$R, 137].
+dmsg_bad_tag() -> %% Will fail early at heap size calculation
+ [$?, 66].
+
start_epmd_false(Config) when is_list(Config) ->
%% Start a node with the option -start_epmd false.
{ok, OtherNode} = start_node(start_epmd_false, "-start_epmd false"),
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index 92ddc23592..08a7b4560c 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -21,7 +21,7 @@
-module(match_spec_SUITE).
-export([all/0, suite/0, not_run/1]).
--export([test_1/1, test_2/1, test_3/1, bad_match_spec_bin/1,
+-export([test_1/1, test_2/1, test_3/1, caller_and_return_to/1, bad_match_spec_bin/1,
trace_control_word/1, silent/1, silent_no_ms/1, silent_test/1,
ms_trace2/1, ms_trace3/1, ms_trace_dead/1, boxed_and_small/1,
destructive_in_test_bif/1, guard_exceptions/1,
@@ -47,7 +47,7 @@ suite() ->
all() ->
case test_server:is_native(match_spec_SUITE) of
false ->
- [test_1, test_2, test_3, bad_match_spec_bin,
+ [test_1, test_2, test_3, caller_and_return_to, bad_match_spec_bin,
trace_control_word, silent, silent_no_ms, silent_test, ms_trace2,
ms_trace3, ms_trace_dead, boxed_and_small, destructive_in_test_bif,
guard_exceptions, unary_plus, unary_minus, fpe,
@@ -180,6 +180,50 @@ test_3(Config) when is_list(Config) ->
collect(P1, [{trace, P1, call, {?MODULE, f2, [a, b]}, [true]}]),
ok.
+%% Test that caller and return to work as they should
+%% There was a bug where caller would be undefined when return_to was set
+%% for r the bif erlang:put().
+caller_and_return_to(Config) ->
+ tr(
+ fun do_put_wrapper/0,
+ fun (Tracee) ->
+ MsgCaller = [{'_',[],[{message,{caller}}]}],
+ 1 = erlang:trace(Tracee, true, [call,return_to]),
+ 1 = erlang:trace_pattern( {?MODULE,do_put,1}, MsgCaller, [local]),
+ 1 = erlang:trace_pattern( {?MODULE,do_the_put,1}, MsgCaller, [local]),
+ 1 = erlang:trace_pattern( {erlang,integer_to_list,1}, MsgCaller, [local]),
+ 1 = erlang:trace_pattern( {erlang,put,2}, MsgCaller, [local]),
+
+ [{trace,Tracee,call,{?MODULE,do_put,[test]},{?MODULE,do_put_wrapper,0}},
+ {trace,Tracee,call,{?MODULE,do_the_put,[test]},{?MODULE,do_put,1}},
+ {trace,Tracee,call,{erlang,integer_to_list,[1]},{?MODULE,do_the_put,1}},
+ {trace,Tracee,return_to,{?MODULE,do_the_put,1}},
+ {trace,Tracee,call,{erlang,put,[test,"1"]},{?MODULE,do_put,1}},
+ {trace,Tracee,return_to,{?MODULE,do_put,1}},
+
+ %% These last trace messages are a bit strange...
+ %% if call tracing had been enabled for do_put_wrapper
+ %% then caller and return_to would have been {?MODULE,do_put_wrapper,1}
+ %% but since it is not, they are set to do_put instead, but we still
+ %% get the do_put_wrapper return_to message...
+ {trace,Tracee,call,{erlang,integer_to_list,[2]},{?MODULE,do_put,1}},
+ {trace,Tracee,return_to,{?MODULE,do_put,1}},
+ {trace,Tracee,return_to,{?MODULE,do_put_wrapper,0}}
+ ]
+ end),
+ ok.
+
+do_put_wrapper() ->
+ do_put(test),
+ ok.
+
+do_put(Var) ->
+ do_the_put(Var),
+ erlang:integer_to_list(id(2)).
+do_the_put(Var) ->
+ Lst = erlang:integer_to_list(id(1)),
+ erlang:put(Var, Lst).
+
otp_9422(Config) when is_list(Config) ->
Laps = 10000,
Fun1 = fun() -> otp_9422_tracee() end,
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 267b5cb0a8..5048bdb846 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl
index dca5a42779..3170ab6351 100644
--- a/erts/preloaded/src/zlib.erl
+++ b/erts/preloaded/src/zlib.erl
@@ -23,7 +23,7 @@
-export([open/0,close/1,deflateInit/1,deflateInit/2,deflateInit/6,
deflateSetDictionary/2,deflateReset/1,deflateParams/3,
deflate/2,deflate/3,deflateEnd/1,
- inflateInit/1,inflateInit/2,
+ inflateInit/1,inflateInit/2,inflateInit/3,
inflateSetDictionary/2,inflateGetDictionary/1, inflateReset/1,
inflate/2,inflate/3,inflateEnd/1,
inflateChunk/2,inflateChunk/1,
@@ -68,6 +68,13 @@
-define(MAX_WBITS, 15).
+-define(DEFAULT_MEMLEVEL, 8).
+-define(DEFAULT_WBITS, 15).
+
+-define(EOS_BEHAVIOR_ERROR, 0).
+-define(EOS_BEHAVIOR_RESET, 1).
+-define(EOS_BEHAVIOR_CUT, 2).
+
%% Chunk sizes are hardcoded on account of them screwing with the
%% predictability of the system. zlib is incapable of trapping so we need to
%% ensure that it never operates on any significant amount of data.
@@ -130,10 +137,7 @@ deflateInit(Z) ->
Z :: zstream(),
Level :: zlevel().
deflateInit(Z, Level) ->
- deflateInit_nif(Z, arg_level(Level)).
-
-deflateInit_nif(_Z, _Level) ->
- erlang:nif_error(undef).
+ deflateInit(Z, Level, deflated, ?DEFAULT_WBITS, ?DEFAULT_MEMLEVEL, default).
-spec deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) -> 'ok' when
Z :: zstream(),
@@ -225,16 +229,21 @@ deflateEnd_nif(_Z) ->
-spec inflateInit(Z) -> 'ok' when
Z :: zstream().
inflateInit(Z) ->
- inflateInit_nif(Z).
-inflateInit_nif(_Z) ->
- erlang:nif_error(undef).
+ inflateInit(Z, ?DEFAULT_WBITS).
-spec inflateInit(Z, WindowBits) -> 'ok' when
Z :: zstream(),
WindowBits :: zwindowbits().
inflateInit(Z, WindowBits) ->
- inflateInit_nif(Z, WindowBits).
-inflateInit_nif(_Z, _WindowBits) ->
+ inflateInit(Z, WindowBits, cut).
+
+-spec inflateInit(Z, WindowBits, EoSBehavior) -> 'ok' when
+ Z :: zstream(),
+ WindowBits :: zwindowbits(),
+ EoSBehavior :: error | reset | cut.
+inflateInit(Z, WindowBits, EoSBehavior) ->
+ inflateInit_nif(Z, arg_bitsz(WindowBits), arg_eos_behavior(EoSBehavior)).
+inflateInit_nif(_Z, _WindowBits, _EoSBehavior) ->
erlang:nif_error(undef).
-spec inflateSetDictionary(Z, Dictionary) -> 'ok' when
@@ -532,7 +541,7 @@ gzip(Data) ->
gunzip(Data) ->
Z = open(),
Bs = try
- inflateInit(Z, 16+?MAX_WBITS),
+ inflateInit(Z, 16+?MAX_WBITS, reset),
B = inflate(Z, Data),
inflateEnd(Z),
B
@@ -652,6 +661,11 @@ arg_strategy(_) -> erlang:error(bad_compression_strategy).
arg_method(deflated) -> ?Z_DEFLATED;
arg_method(_) -> erlang:error(bad_compression_method).
+arg_eos_behavior(error) -> ?EOS_BEHAVIOR_ERROR;
+arg_eos_behavior(reset) -> ?EOS_BEHAVIOR_RESET;
+arg_eos_behavior(cut) -> ?EOS_BEHAVIOR_CUT;
+arg_eos_behavior(_) -> erlang:error(bad_eos_behavior).
+
-spec arg_bitsz(zwindowbits()) -> zwindowbits().
arg_bitsz(Bits) when is_integer(Bits) andalso
((8 =< Bits andalso Bits < 48) orelse
@@ -678,4 +692,4 @@ enqueue_input_1(Z, IOVec) ->
end.
enqueue_nif(_Z, _IOVec) ->
- erlang:nif_error(undef). \ No newline at end of file
+ erlang:nif_error(undef).
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 380be1b534..3d7ff2db66 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 9.1
+VSN = 9.1.2
# Port number 4365 in 4.2
# Port number 4366 in 4.3