diff options
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 3 | ||||
-rw-r--r-- | erts/emulator/beam/io.c | 10 | ||||
-rw-r--r-- | erts/emulator/test/Makefile | 1 | ||||
-rw-r--r-- | erts/emulator/test/prim_eval_SUITE.erl | 78 |
4 files changed, 91 insertions, 1 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 49f932a1c2..8be0f58227 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1324,6 +1324,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) goto do_schedule1; do_schedule: + ASSERT(c_p->arity < 6); ASSERT(c_p->debug_reds_in == REDS_IN(c_p)); if (!ERTS_PROC_GET_SAVED_CALLS_BUF(c_p)) reds_used = REDS_IN(c_p) - FCALLS; @@ -1924,6 +1925,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE); SWAPOUT; c_p->flags &= ~F_DELAY_GC; + c_p->arity = 0; goto do_schedule; /* Will be rescheduled for exit */ } ERTS_SMP_MSGQ_MV_INQ2PRIVQ(c_p); @@ -2166,6 +2168,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) * in limbo forever. */ SWAPOUT; + c_p->arity = 0; goto do_schedule; } #endif diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index ebff564421..ddff862607 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -4887,10 +4887,18 @@ erts_port_control(Process* c_p, copy = 1; else { ProcBin *pb = (ProcBin *) ebinp; + int offset = bufp - pb->val->orig_bytes; - if (pb->flags) + ASSERT(pb->val->orig_bytes <= bufp + && bufp + size <= pb->val->orig_bytes + pb->val->orig_size); + + if (pb->flags) { erts_emasculate_writable_binary(pb); + /* The procbin may have been reallocated, so update bufp */ + bufp = pb->val->orig_bytes + offset; + } + binp = pb->val; ASSERT(bufp <= bufp + size); ASSERT(binp->orig_bytes <= bufp diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index 6f9827002a..5478932b13 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -89,6 +89,7 @@ MODULES= \ os_signal_SUITE \ port_SUITE \ port_bif_SUITE \ + prim_eval_SUITE \ process_SUITE \ pseudoknot_SUITE \ receive_SUITE \ diff --git a/erts/emulator/test/prim_eval_SUITE.erl b/erts/emulator/test/prim_eval_SUITE.erl new file mode 100644 index 0000000000..3f4965f96d --- /dev/null +++ b/erts/emulator/test/prim_eval_SUITE.erl @@ -0,0 +1,78 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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. +%% 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(prim_eval_SUITE). +-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, + init_per_testcase/2, end_per_testcase/2, + init_per_group/2, end_per_group/2]). + +-export(['ERL-365'/1]). + +init_per_testcase(_Case, Config) -> + Config. + +end_per_testcase(_Case, _Config) -> + ok. + +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap,{minutes,1}}]. + +groups() -> + []. + +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +all() -> + ['ERL-365']. + +'ERL-365'(Config) when is_list(Config) -> + %% def_arg_reg[0] is used for storage of timeout instruction + %% when a 'receive after' is executed. When a process was + %% scheduled out inside prim_eval:'receive'/0 due to a function + %% call, def_arg_reg[0] was overwritten due to storage of live + %% registers. + P = spawn_link(fun () -> + prim_eval:'receive'(fun (_M) -> + erlang:bump_reductions((1 bsl 27)-1), + id(true), + nomatch + end, + 200) + end), + receive after 100 -> ok end, + P ! {wont, match}, + receive after 200 -> ok end, + ok. + + + +id(X) -> + X. |