File 1425-Restore-save-pointer-on-bad-timeout-value-in-receive.patch of Package erlang
From 2be04f53570066031c4fc152aa14798dc38c0403 Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Mon, 27 Sep 2021 14:09:04 +0200
Subject: [PATCH] Restore save pointer on bad timeout value in receive
The message queue save pointer was not restored to the beginning of the
message queue when a bad timeout value was encountered in the receive. If
the timeout_value exception was caught, the following receive would not
be searched from the beginning of the message queue. This potentially
caused the process to hang forever even though a matching message was
present in the message queue.
---
erts/emulator/beam/msg_instrs.tab | 2 ++
erts/emulator/test/receive_SUITE.erl | 32 ++++++++++++++++++++++++++--
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/erts/emulator/beam/msg_instrs.tab b/erts/emulator/beam/msg_instrs.tab
index 10fd5ad48d..7056bbc95b 100644
--- a/erts/emulator/beam/msg_instrs.tab
+++ b/erts/emulator/beam/msg_instrs.tab
@@ -305,6 +305,7 @@ timeout() {
TIMEOUT_VALUE() {
c_p->freason = EXC_TIMEOUT_VALUE;
+ JOIN_MESSAGE(c_p);
goto find_func_info;
//| -no_next
}
@@ -372,6 +373,7 @@ wait.src(Src) {
} else { /* Wrong time */
erts_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
c_p->freason = EXC_TIMEOUT_VALUE;
+ JOIN_MESSAGE(c_p);
goto find_func_info;
}
}
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
index 339507c9d8..d42db517c2 100644
--- a/erts/emulator/test/receive_SUITE.erl
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -26,7 +26,8 @@
-export([all/0, suite/0, init_per_testcase/2, end_per_testcase/2,
call_with_huge_message_queue/1,receive_in_between/1,
- receive_opt_exception/1,receive_opt_recursion/1]).
+ receive_opt_exception/1,receive_opt_recursion/1,
+ gh_5235_missing_save_reset/1]).
suite() ->
[{ct_hooks,[ts_install_cth]},
@@ -34,7 +35,9 @@ all() ->
all() ->
[call_with_huge_message_queue, receive_in_between,
- receive_opt_exception, receive_opt_recursion].
+ receive_opt_exception,
+ receive_opt_recursion,
+ gh_5235_missing_save_reset].
init_per_testcase(receive_opt_deferred_save, Config) ->
case erlang:system_info(schedulers_online) of
@@ -183,10 +186,36 @@ erl_1199_flush_blipp() ->
end
end.
+gh_5235_missing_save_reset(Config) when is_list(Config) ->
+ %%
+ %% Used to hang in the second receive due to save
+ %% pointer not being reset on bad timeout value...
+ %%
+ ct:timetrap({seconds, 10}),
+ id(self()) ! init,
+ try
+ receive blipp -> ok after blupp -> ok end
+ catch _:_ ->
+ ok
+ end,
+ receive init -> ok end,
+
+ %% Try with a timeout value not known in compile
+ %% time as well...
+ id(self()) ! init2,
+ try
+ receive blapp -> ok after id(blepp) -> ok end
+ catch _:_ ->
+ ok
+ end,
+ receive init2 -> ok end.
+
%%%
%%% Common helpers.
%%%
+id(X) -> X.
+
echo_loop() ->
receive
{Ref,{Pid,Msg}} ->
--
2.31.1