From 8a126b9088185ecaef39a28dd6d464c46aa68071 Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Wed, 28 Jan 2015 15:10:44 +0100 Subject: [PATCH] core: Fix use-after-free error on _threads When smp::configure() is called from non-main thread, then the global state which it allocates will be destroyed after reactor is destroyed, because it will be destroyed from the main thread and the reactor will be destroyed together with the thread which called smp::configure(). This will result in SIGSEGV when allocator tries to free _threads vector across CPU threads because the target CPU was alrady freed. See issue #10. To fix this, I introduced smp::cleanup() method which should cleanup all global state and should be called in the same thread in which smp::configure() was called. I need to call smp::configure() from non-main thread for integration with boost unit testing framework. --- core/app-template.cc | 4 +++- core/reactor.cc | 4 ++++ core/reactor.hh | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/app-template.cc b/core/app-template.cc index 2669e71ac8..eac2adb160 100644 --- a/core/app-template.cc +++ b/core/app-template.cc @@ -70,7 +70,9 @@ app_template::run(int ac, char ** av, std::function&& func) { engine().exit(1); } }); - return engine().run(); + auto exit_code = engine().run(); + smp::cleanup(); + return exit_code; } diff --git a/core/reactor.cc b/core/reactor.cc index 8014d227c4..c968a076bf 100644 --- a/core/reactor.cc +++ b/core/reactor.cc @@ -1266,6 +1266,10 @@ void smp::allocate_reactor() { reactor_holder.reset(local_engine); } +void smp::cleanup() { + smp::_threads = std::vector(); +} + void smp::configure(boost::program_options::variables_map configuration) { smp::count = 1; diff --git a/core/reactor.hh b/core/reactor.hh index 855add3a58..2ff3a97768 100644 --- a/core/reactor.hh +++ b/core/reactor.hh @@ -837,6 +837,7 @@ class smp { public: static boost::program_options::options_description get_options_description(); static void configure(boost::program_options::variables_map vm); + static void cleanup(); static void join_all(); static bool main_thread() { return std::this_thread::get_id() == _tmain; }