Hi all, I have two examples of multi threading code that crash with segmentation fault. If there is a bug in guile please fix it. If there is a problem only in my code please help me how it can be workaround. I am using Ubuntu 14.04 and guile compiled from the repository. The examples are compiled by: g++ demo.cc -Wall -std=c++11 -pthread -I/usr/local/test/include/guile/2.2 -L/usr/local/test/lib -lguile-2.2 -lgc The first example has started to segfault since guile tagged v2.1.7. I have not encountered problems for v2.1.6 and older versions. However for recent version v2.2.2 it requires much more iterations to fail than v2.1.7 that fails instantly. //////////////////////////////////////////////////////////////////////////// // Example 1. #include #include #include #include #include static volatile bool hold = true; static std::atomic_int start_cnt(0); static std::mutex init_once_mtx; static bool start_inited_once = false; static bool is_inited_once = false; static std::mutex gc_mtx; class Eval { public: Eval(); ~Eval(); }; void* c_wrap_init(void*) { return nullptr; } Eval::Eval() { scm_with_guile(c_wrap_init, this); } Eval::~Eval() { std::lock_guard lck(gc_mtx); scm_gc(); } void* c_wrap_init_only_once(void*) { is_inited_once = true; return nullptr; } void init_only_once() { std::lock_guard lck(init_once_mtx); if (!start_inited_once) { start_inited_once = true; scm_with_guile(c_wrap_init_only_once, nullptr); } while (!is_inited_once); // spin; } void threadedInit(int thread_id) { start_cnt ++; while (hold) {} // spin init_only_once(); Eval* ev = new Eval(); delete ev; } void test_init_race() { int n_threads = 120; start_cnt = 0; hold = true; std::vector thread_pool; for (int i = 0; i < n_threads; i++) thread_pool.push_back(std::thread(&threadedInit, i)); while (start_cnt != n_threads) {} // spin printf("Done creating %d threads\n", n_threads); hold = false; for (std::thread& t : thread_pool) t.join(); printf("Done joining %d threads\n", n_threads); } int main() { for (int k = 0; k < 10000; k++) { test_init_race(); printf("------------------ done iteration %d\n", k); } The second example requires much more iterations to crash with segfault. Sometimes hundreds, sometimes thousands, it seems to be random. You need to wait over a dozen of minutes, sometimes you need try again and restart. I have found this problem for old versions e.g. v2.0.11 as well as for recent version v2.2.2, so it seems to be an old problem. //////////////////////////////////////////////////////////////////////////// // Example 2. #include #include #include #include #include static volatile bool hold = true; static std::atomic_int start_cnt(0); static std::mutex init_once_mtx; static bool start_inited_once = false; static bool is_inited_once = false; void* c_wrap_init_only_once(void*) { is_inited_once = true; return nullptr; } void* c_wrap_eval(void*) { return nullptr; } void init_only_once() { std::lock_guard lck(init_once_mtx); if (!start_inited_once) { start_inited_once = true; scm_with_guile(c_wrap_init_only_once, nullptr); } while (!is_inited_once); // spin; } void threadedInit(int thread_id) { start_cnt ++; while (hold) {} // spin init_only_once(); for (int i = 0; i < 100; ++i) { scm_with_guile(c_wrap_eval, nullptr); } } void test_init_race() { int n_threads = 120; start_cnt = 0; hold = true; std::vector thread_pool; for (int i = 0; i < n_threads; i++) thread_pool.push_back(std::thread(&threadedInit, i)); while (start_cnt != n_threads) {} // spin printf("Done creating %d threads\n", n_threads); hold = false; for (std::thread& t : thread_pool) t.join(); printf("Done joining %d threads\n", n_threads); } int main() { for (int k = 0; k < 10000; k++) { test_init_race(); printf("------------------ done iteration %d\n", k); } } -- Jacek