summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErlang/OTP <otp@erlang.org>2020-02-27 11:53:59 +0100
committerErlang/OTP <otp@erlang.org>2020-02-27 11:53:59 +0100
commitbadc20e46a32f7cdebb421bd0bebd8a05a7309aa (patch)
treebae6d1e4980b5d09b942ba12c2a3c9765a489c84
parent887401f9be4923cf6c23e22802a62f2c8aa799e4 (diff)
parent765ad4aabb66d53254af0d41abb5d00563d916ce (diff)
downloaderlang-badc20e46a32f7cdebb421bd0bebd8a05a7309aa.tar.gz
Merge branch 'rickard/kill2killed-fix/ERL-1165/OTP-16465' into maint-20
* rickard/kill2killed-fix/ERL-1165/OTP-16465: Fix erroneous mapping of kill exit reason to killed Activate test Test case verifying exit signal kill to killed mapping
-rw-r--r--erts/emulator/beam/bif.c4
-rw-r--r--erts/emulator/beam/dist.c2
-rw-r--r--erts/emulator/beam/erl_process.c5
-rw-r--r--erts/emulator/beam/erl_process.h1
-rw-r--r--erts/emulator/test/signal_SUITE.erl68
5 files changed, 75 insertions, 5 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index e5854d6002..13b25ab88d 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -1631,11 +1631,13 @@ BIF_RETTYPE exit_2(BIF_ALIST_2)
* The pid is internal. Verify that it refers to an existing process.
*/
ErtsProcLocks rp_locks;
+ Uint32 flags = ERTS_XSIG_FLG_EXIT2;
if (BIF_ARG_1 == BIF_P->common.id) {
rp_locks = ERTS_PROC_LOCKS_ALL;
rp = BIF_P;
erts_smp_proc_lock(rp, ERTS_PROC_LOCKS_ALL_MINOR);
+ flags |= ERTS_XSIG_FLG_NO_IGN_NORMAL;
}
else {
rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
@@ -1656,7 +1658,7 @@ BIF_RETTYPE exit_2(BIF_ALIST_2)
BIF_ARG_2,
NIL,
NULL,
- BIF_P == rp ? ERTS_XSIG_FLG_NO_IGN_NORMAL : 0);
+ flags);
#ifdef ERTS_SMP
if (rp == BIF_P)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 26352e5534..cbff969757 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -1688,7 +1688,7 @@ int erts_net_message(Port *prt,
reason,
token,
NULL,
- 0);
+ ERTS_XSIG_FLG_EXIT2);
erts_smp_proc_unlock(rp, rp_locks);
}
break;
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 521159d95e..cfc06d9703 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -13404,7 +13404,10 @@ send_exit_signal(Process *c_p, /* current process if and only
)
{
erts_aint32_t state = erts_smp_atomic32_read_nob(&rp->state);
- Eterm rsn = reason == am_kill ? am_killed : reason;
+ Eterm rsn = reason;
+
+ if ((flags & ERTS_XSIG_FLG_EXIT2) && reason == am_kill)
+ rsn = am_killed;
ERTS_SMP_LC_ASSERT(*rp_locks == erts_proc_lc_my_proc_locks(rp));
ERTS_SMP_LC_ASSERT((*rp_locks & ERTS_PROC_LOCKS_XSIG_SEND)
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index b3385b780f..a154b90c3a 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -1530,6 +1530,7 @@ extern int erts_system_profile_ts_type;
/* Option flags to erts_send_exit_signal() */
#define ERTS_XSIG_FLG_IGN_KILL (((Uint32) 1) << 0)
#define ERTS_XSIG_FLG_NO_IGN_NORMAL (((Uint32) 1) << 1)
+#define ERTS_XSIG_FLG_EXIT2 (((Uint32) 1) << 2)
#define CANCEL_TIMER(P) \
do { \
diff --git a/erts/emulator/test/signal_SUITE.erl b/erts/emulator/test/signal_SUITE.erl
index f1d11d1814..2219eea66b 100644
--- a/erts/emulator/test/signal_SUITE.erl
+++ b/erts/emulator/test/signal_SUITE.erl
@@ -47,7 +47,8 @@
pending_exit_process_info_1/1,
pending_exit_process_info_2/1,
pending_exit_group_leader/1,
- exit_before_pending_exit/1]).
+ exit_before_pending_exit/1,
+ kill2killed/1]).
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
available_internal_state(true),
@@ -77,7 +78,8 @@ all() ->
pending_exit_process_display,
pending_exit_process_info_1,
pending_exit_process_info_2, pending_exit_group_leader,
- exit_before_pending_exit].
+ exit_before_pending_exit,
+ kill2killed].
%% Test that exit signals and messages are received in correct order
@@ -366,6 +368,68 @@ pending_exit_group_leader(Config) when is_list(Config) ->
verify_pending_exit_success(S),
comment().
+kill2killed(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ kill2killed_test(node()),
+ {ok, Node} = start_node(Config),
+ kill2killed_test(Node),
+ stop_node(Node),
+ ok.
+
+kill2killed_test(Node) ->
+ if Node == node() ->
+ io:format("Testing against local node", []);
+ true ->
+ io:format("Testing against remote node ~p", [Node])
+ end,
+ check_exit(Node, other_exit2, 1),
+ check_exit(Node, other_exit2, 2),
+ check_exit(Node, other_exit2, 9),
+ check_exit(Node, other_exit2, 10),
+ check_exit(Node, exit2, 1),
+ check_exit(Node, exit2, 2),
+ check_exit(Node, exit2, 9),
+ check_exit(Node, exit2, 10),
+ check_exit(Node, exit1, 1),
+ check_exit(Node, exit1, 2),
+ check_exit(Node, exit1, 9),
+ check_exit(Node, exit1, 10),
+ ok.
+
+check_exit(Node, Type, N) ->
+ io:format("Testing ~p length ~p~n", [Type, N]),
+ P = spawn_link_line(Node, node(), Type, N, self()),
+ if Type == other_exit2 ->
+ receive
+ {end_of_line, EOL} ->
+ exit(EOL, kill)
+ end;
+ true -> ok
+ end,
+ receive
+ {'EXIT', P, Reason} ->
+ if Type == exit1 ->
+ kill = Reason;
+ true ->
+ killed = Reason
+ end
+ end.
+
+spawn_link_line(_NodeA, _NodeB, other_exit2, 0, Tester) ->
+ Tester ! {end_of_line, self()},
+ receive after infinity -> ok end;
+spawn_link_line(_NodeA, _NodeB, exit1, 0, _Tester) ->
+ exit(kill);
+spawn_link_line(_NodeA, _NodeB, exit2, 0, _Tester) ->
+ exit(self(), kill);
+spawn_link_line(NodeA, NodeB, Type, N, Tester) ->
+ spawn_link(NodeA,
+ fun () ->
+ spawn_link_line(NodeB, NodeA, Type, N-1, Tester),
+ receive after infinity -> ok end
+ end).
+
+
%%
%% -- Internal utils --------------------------------------------------------
%%