From 4bed7ed5f1857a952ba70ad306849f14e4dd8149 Mon Sep 17 00:00:00 2001 From: Nadav Har'El Date: Wed, 1 Jan 2014 16:29:59 +0200 Subject: [PATCH] Sched: fix race start_early_threads() In issue #145 I reported a crash during boot in start_early_threads(). I wasn't actually able to replicate this bug on master, but it happens quite frequently (e.g., on virtually every "make check" run) with some patches of mine that seem unrelated to this bug. The problem is that start_early_threads() (added in 63216e85978ea2f38) iterates on the threads in the thread list, and uses t->remote_thread_local_var() for each thread. This can only work if the thread has its TLS initialized, but unfortunately in thread's constructor we first added the new thread to the list, and only later called setup_tcb() (which allocates and initializes the TLS). If we're unlucky, start_early_threads() can find a thread on the list which still doesn't have its TLS allocated, so remote_thread_local_var() will crash. The simple fix is to switch the order of the construction: First set up the new thread's TLS, and only then add it to the list of threads. Fixes #145. Signed-off-by: Nadav Har'El Signed-off-by: Pekka Enberg --- core/sched.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sched.cc b/core/sched.cc index 5a8cbace95..5159770e57 100644 --- a/core/sched.cc +++ b/core/sched.cc @@ -571,6 +571,7 @@ thread::thread(std::function func, attr attr, bool main) , _cleanup([this] { delete this; }) , _joiner(nullptr) { + setup_tcb(); WITH_LOCK(thread_map_mutex) { if (!main) { auto ttid = _s_idgen; @@ -591,7 +592,6 @@ thread::thread(std::function func, attr attr, bool main) } } } - setup_tcb(); // setup s_current before switching to the thread, so interrupts // can call thread::current() // remote_thread_local_var() doesn't work when there is no current