diff options
author | Sverker Eriksson <[email protected]> | 2018-06-11 15:56:59 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2018-06-11 15:56:59 +0200 |
commit | c5a6b03c9ee71bb13723f6ca6ff0e8f6cd16fe24 (patch) | |
tree | 13299509de8753b723a20139b102039d7e914659 | |
parent | 463c8e7fa08388f138fd9f07995d7c7a7580507e (diff) | |
download | otp-c5a6b03c9ee71bb13723f6ca6ff0e8f6cd16fe24.tar.gz otp-c5a6b03c9ee71bb13723f6ca6ff0e8f6cd16fe24.tar.bz2 otp-c5a6b03c9ee71bb13723f6ca6ff0e8f6cd16fe24.zip |
erts: Fix incoming signal handling for exiting process
Seen symptom:
handle_process_info() called with is_alive=1 on exiting process,
reading broken Process.u.initial.module atom
overwritten by Process.u.terminate pointer.
Solution:
Let erts_proc_sig_handle_incoming() do nothing if process is
already exiting.
-rw-r--r-- | erts/emulator/beam/erl_proc_sig_queue.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index 1aa390d94d..d6d22677e7 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -2723,6 +2723,9 @@ handle_process_info(Process *c_p, ErtsSigRecvTracing *tracing, Uint reds = 0; Process *rp; + ASSERT(!!is_alive == !(erts_atomic32_read_nob(&c_p->state) + & ERTS_PSFLG_EXITING)); + if (pisig->msgq_len_offset != ERTS_PROC_SIG_PI_MSGQ_LEN_IGNORE) { /* * Request requires message queue data to be updated @@ -3007,10 +3010,8 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep, ERTS_HDBG_CHECK_SIGNAL_PRIV_QUEUE(c_p, 0); ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN == erts_proc_lc_my_proc_locks(c_p)); - if (local_only) - state = -1; /* can never be a valid state... */ - else { - state = erts_atomic32_read_nob(&c_p->state); + state = erts_atomic32_read_nob(&c_p->state); + if (!local_only) { if (ERTS_PSFLG_SIG_IN_Q & state) { erts_proc_lock(c_p, ERTS_PROC_LOCK_MSGQ); erts_proc_sig_fetch(c_p); @@ -3023,13 +3024,15 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep, yield = 0; if (!c_p->sig_qs.cont) { - if (state == -1) - *statep = erts_atomic32_read_nob(&c_p->state); - else - *statep = state; + *statep = state; return !0; } + if (state & ERTS_PSFLG_EXITING) { + *statep = state; + return 0; + } + next_nm_sig = &c_p->sig_qs.nmsigs.next; setup_tracing_state(c_p, &tracing); |