From 30598c518f793bb7c3893d3996966dca5b858192 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 4 Jun 2018 14:42:38 +0200 Subject: erts: Fix broken signal queue broken on master by 613cde66c25464121f2f6dace99782bad0e07d9b Scenario: proc_queue_signal() fails to send switched pending signal due to state & ERTS_PSFLG_FREE, and then calls erts_proc_sig_send_monitor_down() to enqueue to self followed by sig_enqueue_trace_cleanup() that destroyed 'next' pointer of enqueued signal. Solution: Switch order and do sig_enqueue_trace_cleanup() first. --- erts/emulator/beam/erl_proc_sig_queue.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'erts/emulator/beam') diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index e9b41ad298..dc09efa7d7 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -445,6 +445,8 @@ sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig, ErtsMessage *last case ERTS_SIG_Q_OP_TRACE_CHANGE_STATE: destroy_trace_info((ErtsSigTraceInfo *) tmp_free); break; + case ERTS_SIG_Q_OP_MONITOR: + break; /* ignore flushed pending signal */ default: ERTS_INTERNAL_ERROR("Unexpected signal op"); break; @@ -688,19 +690,15 @@ first_last_done: erts_proc_unlock(rp, ERTS_PROC_LOCK_MSGQ); if (res == 0) { + sig_enqueue_trace_cleanup(first, sig, last); if (pend_sig) { if (sig == pend_sig) { /* We did a switch, callers signal is now pending (still ok) */ ASSERT(esdp->pending_signal.sig); res = 1; } - else { - ASSERT(first == (ErtsMessage*)pend_sig); - first = first->next; - } erts_proc_sig_send_monitor_down((ErtsMonitor*)pend_sig, am_noproc); } - sig_enqueue_trace_cleanup(first, sig, last); } erts_proc_notify_new_sig(rp, state, 0); -- cgit v1.2.3