From 79b504ca9134121a63c049292d8636d3cd0d99b4 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 10 Jul 2015 16:56:15 +0200 Subject: Teach smp VM how to deal with crash of a linked trace port Problem: The sys-msg-dispather crashes the VM when trying to send exit signals from the links of the terminating trace port. If try-lock of the linked process fails, a pending exit is scheduled and erts_scheduler_data() is then called to find "my" run queue. But sys-msg-dispatcher is not a scheduler and has no scheduler data, hence SEGV. Fix: If not a scheduler and we cannot get process locks, schedule process in its previous run-queue. --- erts/emulator/beam/erl_process.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index b6ad8575cf..26ef96ea74 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -11195,10 +11195,14 @@ save_pending_exiter(Process *p) { ErtsProcList *plp; ErtsRunQueue *rq; + ErtsSchedulerData *esdp = erts_get_scheduler_data(); ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_STATUS & erts_proc_lc_my_proc_locks(p)); - rq = erts_get_runq_current(NULL); + if (!esdp) + rq = RUNQ_READ_RQ(&p->run_queue); + else + rq = esdp->run_queue; plp = proclist_create(p); @@ -11215,6 +11219,7 @@ save_pending_exiter(Process *p) else #endif wake_scheduler(rq); + } #endif @@ -11411,23 +11416,21 @@ send_exit_signal(Process *c_p, /* current process if and only if (need_locks && erts_smp_proc_trylock(rp, need_locks) == EBUSY) { /* ... but we havn't got all locks on it ... */ - save_pending_exiter(rp); + save_pending_exiter(rp); /* * The pending exit will be discovered when next * process is scheduled in */ - goto set_pending_exit; - } - else { - /* ...and we have all locks on it... */ - *rp_locks = ERTS_PROC_LOCKS_ALL; - set_proc_exiting(rp, - state, - (is_immed(rsn) - ? rsn - : copy_object(rsn, rp)), - NULL); + goto set_pending_exit; } + /* ...and we have all locks on it... */ + *rp_locks = ERTS_PROC_LOCKS_ALL; + set_proc_exiting(rp, + state, + (is_immed(rsn) + ? rsn + : copy_object(rsn, rp)), + NULL); } else { /* Process running... */ -- cgit v1.2.3