From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Jacek Swiergocki Newsgroups: gmane.lisp.guile.bugs Subject: bug#26711: Multithreading segfaults Date: Sat, 29 Apr 2017 13:16:13 +0200 Message-ID: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=94eb2c125580722374054e4c51cf X-Trace: blaine.gmane.org 1493484975 17036 195.159.176.226 (29 Apr 2017 16:56:15 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 29 Apr 2017 16:56:15 +0000 (UTC) To: 26711@debbugs.gnu.org Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Sat Apr 29 18:56:06 2017 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d4VfA-0004Fb-Od for guile-bugs@m.gmane.org; Sat, 29 Apr 2017 18:56:05 +0200 Original-Received: from localhost ([::1]:41763 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d4VfG-0004NN-L5 for guile-bugs@m.gmane.org; Sat, 29 Apr 2017 12:56:10 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:41697) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d4Vf9-0004MB-JW for bug-guile@gnu.org; Sat, 29 Apr 2017 12:56:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d4Vf8-0004pp-7d for bug-guile@gnu.org; Sat, 29 Apr 2017 12:56:03 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:48347) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1d4Vf8-0004pj-2O for bug-guile@gnu.org; Sat, 29 Apr 2017 12:56:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1d4Vf7-000740-SL for bug-guile@gnu.org; Sat, 29 Apr 2017 12:56:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Jacek Swiergocki Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Sat, 29 Apr 2017 16:56:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 26711 X-GNU-PR-Package: guile X-GNU-PR-Keywords: X-Debbugs-Original-To: bug-guile@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.149348491427095 (code B ref -1); Sat, 29 Apr 2017 16:56:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 29 Apr 2017 16:55:14 +0000 Original-Received: from localhost ([127.0.0.1]:46544 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d4VeM-00072x-0H for submit@debbugs.gnu.org; Sat, 29 Apr 2017 12:55:14 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:35767) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d4QMU-0005gi-2g for submit@debbugs.gnu.org; Sat, 29 Apr 2017 07:16:26 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d4QMN-0005px-28 for submit@debbugs.gnu.org; Sat, 29 Apr 2017 07:16:20 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:32887) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d4QMM-0005ps-UL for submit@debbugs.gnu.org; Sat, 29 Apr 2017 07:16:18 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54957) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d4QML-0000wf-5n for bug-guile@gnu.org; Sat, 29 Apr 2017 07:16:18 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d4QMJ-0005oe-HY for bug-guile@gnu.org; Sat, 29 Apr 2017 07:16:17 -0400 Original-Received: from mail-qt0-x22b.google.com ([2607:f8b0:400d:c0d::22b]:35692) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1d4QMJ-0005oN-Cj for bug-guile@gnu.org; Sat, 29 Apr 2017 07:16:15 -0400 Original-Received: by mail-qt0-x22b.google.com with SMTP id y33so66714781qta.2 for ; Sat, 29 Apr 2017 04:16:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=2RSnOsSr1v8OPSHbs8hRuIKG05rn+krg/A6QglI9t6w=; b=unH9EJkVOyW0BtJkX1KAP/AvSK6H29eTnrEjoLJFHp5nGsdBIxFVb+hLulxwk69Dn/ qxtT0jCm9SlqA2f697uIIWUNtBqiSiae1D7n4Eotbfhox3ibUAO7sxulCqm1E/hqSYWm 27wFzB+zSwE80V6FLylj0EhjDhDmdMNvNCCDmmAXmOQJTraWOQpBKRy4BhqdZtWNdLlZ ANPqUBWlBVbmhwR/1W4pbNwOwtFsi7S1IZaVYMH0iwRh1tyTfUYOkRGo/gvppdwKDwV+ aZfWespVJuqKo2x3VTFXlwGxH/tC2cMgPjQGh0CnIlgvR8mYx+riffYFNUbnzwxa2rNw waYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=2RSnOsSr1v8OPSHbs8hRuIKG05rn+krg/A6QglI9t6w=; b=i6DlOQakT4PZnAuoUG165FS6wepZ6tIdjX5RMGFVT4EoWJZYwb4EXPCoT62GB7HG/K Vqf0iBda1DgioC9rM6J53FFJ7iopKApk+Ib+x9sZDamZOlxPAssLYeWkrwIGeV03bxkH ddAoYHsWgZvU/qeNh1vIPKvXw8qI/EvtNcxKFANiCBsI4vmWrJfLcb6VXSUNICmr+8wI Bgx0z26LHgacvJ5uhKZVfOM6YnCdOfDRRCeBolLTG1yYTzD1K/5+wvnQrVW+y86UYF22 OhxukuBknXvL8vfZ510fvv+jWUzvsILql5G58cO//LXFL1yTRXfj4XNaUTkdLJh7wMh0 rWYA== X-Gm-Message-State: AN3rC/7bVVcPaoMxYwza93X2xP/shfOayE5wFsZxnyf90dncJTE408ux oujdg2tOs9teOPYxACquN72Aw3CTkzC6 X-Received: by 10.237.38.135 with SMTP id q7mr13681619qtd.115.1493464574466; Sat, 29 Apr 2017 04:16:14 -0700 (PDT) Original-Received: by 10.12.150.123 with HTTP; Sat, 29 Apr 2017 04:16:13 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Mailman-Approved-At: Sat, 29 Apr 2017 12:55:13 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Original-Sender: "bug-guile" Xref: news.gmane.org gmane.lisp.guile.bugs:8795 Archived-At: --94eb2c125580722374054e4c51cf Content-Type: text/plain; charset=UTF-8 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 --94eb2c125580722374054e4c51cf Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi all,

I have two examples = of multi threading code that crash with segmentation fault. If there is a b= ug in guile please fix it. If there is a problem only in my code please hel= p me how it can be workaround.

I am using Ubuntu 1= 4.04 and guile compiled from the repository. The examples are compiled by:<= /div>
g++ demo.cc -Wall -std=3Dc++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 f= ails instantly.

//////////////////////////////////= //////////////////////////////////////////
// Example 1.

#include <libguile.h>

#incl= ude <thread>
#include <vector>
#include <= ;atomic>
#include <mutex>

stati= c volatile bool hold =3D true;
static std::atomic_int start_cnt(0= );

static std::mutex init_once_mtx;
stat= ic bool start_inited_once =3D false;
static bool is_inited_once = =3D false;

static std::mutex gc_mtx;
class Eval
{
public:
=C2=A0 =C2= =A0 Eval();
=C2=A0 =C2=A0 ~Eval();
};

void* c_wrap_init(void*)
{
=C2=A0 =C2= =A0 return nullptr;
}

Eval::= Eval()
{
=C2=A0 =C2=A0 scm_with_guile(c_wrap_init, = this);
}

Eval::~Eval()
{
=
=C2=A0 =C2=A0 std::lock_guard<std::mutex> lck(gc_mtx);
=C2=A0 =C2=A0 scm_gc();
}

vo= id* c_wrap_init_only_once(void*)
{
=C2=A0 =C2=A0 is_ini= ted_once =3D true;
=C2=A0 =C2=A0 return nullptr;
}

void init_only_once()
{
=C2=A0 =C2= =A0 std::lock_guard<std::mutex> lck(init_once_mtx);
=C2=A0 = =C2=A0 if (!start_inited_once)
=C2=A0 =C2=A0 {
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 start_inited_once =3D true;
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 scm_with_guile(c_wrap_init_only_once, nullptr);
=C2= =A0 =C2=A0 }
=C2=A0 =C2=A0 while (!is_inited_once); // spin;
}

void threadedInit(int thread_id)
{
=C2=A0 =C2=A0 start_cnt ++;
=C2=A0 =C2=A0 while (hol= d) {} // spin

=C2=A0 =C2=A0 init_only_once();
=C2=A0 =C2=A0 Eval* ev =3D new Eval();

=C2= =A0 =C2=A0 delete ev;
}

void test_init_r= ace()
{
=C2=A0 =C2=A0 int n_threads =3D 120;
= =C2=A0 =C2=A0 start_cnt =3D 0;
=C2=A0 =C2=A0 hold =3D true;
=

=C2=A0 =C2=A0 std::vector<std::thread> thread_poo= l;
=C2=A0 =C2=A0 for (int i =3D 0; i < n_threads; i++)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 thread_pool.push_back(std::thread(&threa= dedInit, i));

=C2=A0 =C2=A0 while (start_cnt !=3D = n_threads) {} =C2=A0// spin
=C2=A0 =C2=A0 printf("Done creat= ing %d threads\n", n_threads);
=C2=A0 =C2=A0 hold =3D false;=

=C2=A0 =C2=A0 for (std::thread& t : thread_po= ol) t.join();
=C2=A0 =C2=A0 printf("Done joining %d threads\= n", n_threads);
}

int main()
<= div>{
=C2=A0 =C2=A0 for (int k =3D 0; k < 10000; k++)
=C2=A0 =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 test_init_race();
=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("------------------ done i= teration %d\n", k);
}

The second ex= ample requires much more iterations to crash with segfault. Sometimes hundr= eds, sometimes thousands, it seems to be random. You need to wait over a do= zen 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 <libguile.h>
=
#include <thread>
#include <vector>
#include <atomic>
#include <mutex>
=
static volatile bool hold =3D true;
static std::at= omic_int start_cnt(0);

static std::mutex init_once= _mtx;
static bool start_inited_once =3D false;
static b= ool is_inited_once =3D false;

void* c_wrap_init_on= ly_once(void*)
{
=C2=A0 =C2=A0 is_inited_once =3D true;=
=C2=A0 =C2=A0 return nullptr;
}

void* c_wrap_eval(void*)
{
=C2=A0 =C2=A0 return null= ptr;
}

void init_only_once()
{=
=C2=A0 =C2=A0 std::lock_guard<std::mutex> lck(init_once_mt= x);
=C2=A0 =C2=A0 if (!start_inited_once)
=C2=A0 =C2=A0= {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 start_inited_once =3D true;
<= div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 scm_with_guile(c_wrap_init_only_once, nullp= tr);
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 while (!is_inited_on= ce); // spin;
}

void threadedInit(int th= read_id)
{
=C2=A0 =C2=A0 start_cnt ++;
=C2=A0= =C2=A0 while (hold) {} // spin

=C2=A0 =C2=A0 init= _only_once();
=C2=A0 =C2=A0 for (int i =3D 0; i < 100; ++i)
=C2=A0 =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 scm_with_guil= e(c_wrap_eval, nullptr);
=C2=A0 =C2=A0 }
}
void test_init_race()
{
=C2=A0 =C2=A0 int = n_threads =3D 120;
=C2=A0 =C2=A0 start_cnt =3D 0;
=C2= =A0 =C2=A0 hold =3D true;

=C2=A0 =C2=A0 std::vecto= r<std::thread> thread_pool;
=C2=A0 =C2=A0 for (int i =3D 0;= i < n_threads; i++)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 thread_pool.p= ush_back(std::thread(&threadedInit, i));

=C2= =A0 =C2=A0 while (start_cnt !=3D n_threads) {} =C2=A0// spin
=C2= =A0 =C2=A0 printf("Done creating %d threads\n", n_threads);
=
=C2=A0 =C2=A0 hold =3D false;

=C2=A0 =C2=A0 f= or (std::thread& t : thread_pool) t.join();
=C2=A0 =C2=A0 pri= ntf("Done joining %d threads\n", n_threads);
}

int main()
{
=C2=A0 =C2=A0 for (int k = =3D 0; k < 10000; k++)
=C2=A0 =C2=A0 {
=C2=A0 =C2=A0= =C2=A0 =C2=A0 test_init_race();
=C2=A0 =C2=A0 =C2=A0 =C2=A0 prin= tf("------------------ done iteration %d\n", k);
=C2=A0= =C2=A0 }
}

--
Jacek

--94eb2c125580722374054e4c51cf--