diff options
author | Lukas Larsson <[email protected]> | 2017-06-14 11:57:13 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2017-06-15 10:04:50 +0200 |
commit | b2f7b51f420a233a41c885d8b44919d88f1e7ba5 (patch) | |
tree | 59ef0ec698e310218908759aa9404c6308e525c9 /erts/emulator/beam | |
parent | f7c9c43c08fd46d89f2a5bf1d055f431dd3812dc (diff) | |
download | otp-b2f7b51f420a233a41c885d8b44919d88f1e7ba5.tar.gz otp-b2f7b51f420a233a41c885d8b44919d88f1e7ba5.tar.bz2 otp-b2f7b51f420a233a41c885d8b44919d88f1e7ba5.zip |
erts: Must have main lock when flushing trace messages
If we don't have the main lock, multiple threads may come in and
do the flush at the same time which will lead to all kinds of
strang problems.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.c | 18 |
2 files changed, 13 insertions, 9 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 4815e5e7bb..8ed429b214 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -588,6 +588,10 @@ int erts_flush_trace_messages(Process *c_p, ErtsProcLocks c_p_locks) ErlTraceMessageQueue *msgq, **last_msgq; int reds = 0; + /* Only one thread at a time is allowed to flush trace messages, + so we require the main lock to be held when doing the flush */ + ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p); + erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_TRACE); msgq = c_p->trace_msg_q; diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index fc2b34e70f..0ff9484daf 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -11768,9 +11768,11 @@ flush_dirty_trace_messages(void *vpid) erts_free(ERTS_ALC_T_DIRTY_SL, vpid); #endif - proc = erts_proc_lookup(pid); - if (proc) - (void) erts_flush_trace_messages(proc, 0); + proc = erts_pid2proc_opt(NULL, 0, pid, ERTS_PROC_LOCK_MAIN, 0); + if (proc) { + (void) erts_flush_trace_messages(proc, ERTS_PROC_LOCK_MAIN); + erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_MAIN); + } } #endif /* ERTS_DIRTY_SCHEDULERS */ @@ -14102,8 +14104,11 @@ erts_continue_exit_process(Process *p) have none here */ } + erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN); + ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p); + #ifdef ERTS_SMP - erts_flush_trace_messages(p, 0); + erts_flush_trace_messages(p, ERTS_PROC_LOCK_MAIN); #endif ERTS_TRACER_CLEAR(&ERTS_TRACER(p)); @@ -14111,11 +14116,6 @@ erts_continue_exit_process(Process *p) if (!delay_del_proc) delete_process(p); -#ifdef ERTS_SMP - erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN); - ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p); -#endif - return; yield: |