File 0194-erts-Must-have-main-lock-when-flushing-trace-message.patch of Package erlang

From b2f7b51f420a233a41c885d8b44919d88f1e7ba5 Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Wed, 14 Jun 2017 11:57:13 +0200
Subject: [PATCH] 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.
---
 erts/emulator/beam/erl_nif.c     |  4 ++++
 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 4815e5e7b..8ed429b21 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 fc2b34e70..0ff9484da 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:
-- 
2.14.1

openSUSE Build Service is sponsored by