diff options
author | Erlang/OTP <otp@erlang.org> | 2020-02-27 11:53:59 +0100 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2020-02-27 11:53:59 +0100 |
commit | badc20e46a32f7cdebb421bd0bebd8a05a7309aa (patch) | |
tree | bae6d1e4980b5d09b942ba12c2a3c9765a489c84 | |
parent | 887401f9be4923cf6c23e22802a62f2c8aa799e4 (diff) | |
parent | 765ad4aabb66d53254af0d41abb5d00563d916ce (diff) | |
download | erlang-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.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/dist.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.c | 5 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.h | 1 | ||||
-rw-r--r-- | erts/emulator/test/signal_SUITE.erl | 68 |
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 -------------------------------------------------------- %% |