diff options
author | Sverker Eriksson <[email protected]> | 2015-07-10 16:56:15 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2015-08-10 15:22:00 +0200 |
commit | 79b504ca9134121a63c049292d8636d3cd0d99b4 (patch) | |
tree | 8843b3995ee7c64f0d67d365f6b24a2c2ef52759 /erts/emulator/beam | |
parent | 12002949e5435d19c750fe2cd8e897b4059f875a (diff) | |
download | otp-79b504ca9134121a63c049292d8636d3cd0d99b4.tar.gz otp-79b504ca9134121a63c049292d8636d3cd0d99b4.tar.bz2 otp-79b504ca9134121a63c049292d8636d3cd0d99b4.zip |
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.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_process.c | 29 |
1 files 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... */ |