From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.bugs,gmane.comp.programming.garbage-collection.boehmgc Subject: pthreads and libgc Date: Fri, 18 Mar 2011 21:56:04 +0100 Message-ID: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1300481776 10842 80.91.229.12 (18 Mar 2011 20:56:16 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Fri, 18 Mar 2011 20:56:16 +0000 (UTC) Cc: bug-guile To: gc@linux.hpl.hp.com Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Fri Mar 18 21:56:10 2011 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Q0giL-0006mt-2I for guile-bugs@m.gmane.org; Fri, 18 Mar 2011 21:56:05 +0100 Original-Received: from localhost ([127.0.0.1]:55287 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q0giK-00069b-MO for guile-bugs@m.gmane.org; Fri, 18 Mar 2011 16:56:04 -0400 Original-Received: from [140.186.70.92] (port=39933 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q0giF-00067V-0e for bug-guile@gnu.org; Fri, 18 Mar 2011 16:56:00 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q0giD-0003rU-9u for bug-guile@gnu.org; Fri, 18 Mar 2011 16:55:58 -0400 Original-Received: from a-pb-sasl-sd.pobox.com ([64.74.157.62]:40546 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q0giD-0003rQ-5T for bug-guile@gnu.org; Fri, 18 Mar 2011 16:55:57 -0400 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-sd.pobox.com (Postfix) with ESMTP id D562440CC; Fri, 18 Mar 2011 16:57:30 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:date:message-id:mime-version:content-type; s=sasl; bh=e +1PSxkJ8/pVppSCha7BrOIxCiw=; b=VtR5m4/XMm6+MIH2nst2XhiarRzIyclXp 1omcSKf92cQt17yLWEFVHvRcEOrS7Q7Avcj8+nj8bREuZlWD4niyyT/mnIDxAHhc eCziOMBaNX0bd/0J3yBexih7hJreLmCVyG3tSV7f2wiNRH6lHd+oQTednHTgrI6b uZ0kDJNAJU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:date:message-id:mime-version:content-type; q=dns; s= sasl; b=bRe32W69HgnVeed767Fk1ETz65Oc+46jDx0gGmbSXVToeYNV2qws0rev p6pVUSVBC4KF6yOKx9uz9B8yQ6VY7m32tXGRFIDisk0ZoM29tghizOeJAC/WLGBi hD/AB4ff3N4kzxgx2+VFOUM6JaKfdp+IyLWzQZcJn4ZVYNbUjow= Original-Received: from a-pb-sasl-sd.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-sd.pobox.com (Postfix) with ESMTP id C211D40CB; Fri, 18 Mar 2011 16:57:28 -0400 (EDT) Original-Received: from unquote.localdomain (unknown [90.164.198.39]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-pb-sasl-sd.pobox.com (Postfix) with ESMTPSA id 025FC40CA; Fri, 18 Mar 2011 16:57:26 -0400 (EDT) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) X-Pobox-Relay-ID: 55CBCA16-51A2-11E0-A37D-E8AB60295C12-02397024!a-pb-sasl-sd.pobox.com X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-Received-From: 64.74.157.62 X-BeenThere: bug-guile@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.bugs:5340 gmane.comp.programming.garbage-collection.boehmgc:4426 Archived-At: Hello list, I was tracking down a bug in Guile, got to a sticky situation, and could use some input. Let me first show you the code. #include #include #include #include static void *thread_with_guile(void *null) { return NULL; } static void *the_thread(void *args) { scm_with_guile (thread_with_guile, NULL); return NULL; } int main(void) { int n; for (n = 0; n < 10000; n++) { pthread_t ptid; fprintf (stderr, "%d: create", n); pthread_create(&ptid, NULL, the_thread, NULL); void *ret; fprintf (stderr, " join"); pthread_join(ptid, &ret); fprintf (stderr, " finished.\n"); } return 0; } I don't presume that you will compile it, but if you do, you can do so with "gcc -o test test.c `pkg-config --cflags --libs guile-2.0`". As you see, it creates a bunch of threads, and does something within "guile mode" on each of them. The use case is obviously for some big threaded application with plugins, and you don't know what thread will see Guile first. The first scm_with_guile call will initialize Guile, which does a GC_INIT, which basically goes like this: GC_all_interior_pointers = 0; GC_INIT (); However, libgc appears already to have been initialized when this happens, automagically, because of pthreads. If I run the program under GDB, it happens here: Breakpoint 1, GC_init () at misc.c:634 634 { (gdb) thr apply all bt Thread 1 (Thread 0x7ffff78df700 (LWP 14166)): #0 GC_init () at misc.c:634 #1 0x0000003fc8e1455e in GC_generic_malloc_inner (lb=56, k=1) at malloc.c:119 #2 0x0000003fc8e1f4ce in GC_pthread_create (new_thread=0x7fffffffe020, attr=0x0, start_routine=0x4007e3 , arg=0x0) at pthread_support.c:1469 #3 0x0000000000400853 in main () Unhappily though, the initialization is done with GC_all_interior_pointers == 1. So later after Guile initializes, it gets a segfault: Program received signal SIGSEGV, Segmentation fault. 0x0000003fc8e0f6e3 in GC_is_black_listed (h=0x655000, len=) at blacklst.c:233 233 if (get_pht_entry_from_index(GC_old_normal_bl, index) (gdb) thr apply all bt Thread 2 (Thread 0x7ffff78dd700 (LWP 14169)): #0 0x0000003fc8e0f6e3 in GC_is_black_listed (h=0x655000, len=) at blacklst.c:233 #1 0x0000003fc8e0d3db in GC_allochblk_nth (sz=16, kind=1, flags=0, n=29, may_split=) at allchblk.c:694 #2 0x0000003fc8e0d7dc in GC_allochblk (sz=16, kind=1, flags=0) at allchblk.c:629 #3 0x0000003fc8e1a2fb in GC_new_hblk (gran=1, kind=1) at new_hblk.c:191 #4 0x0000003fc8e0f593 in GC_allocobj (gran=1, kind=1) at alloc.c:1312 #5 0x0000003fc8e1458a in GC_generic_malloc_inner (lb=8, k=1) at malloc.c:126 #6 0x0000003fc8e12405 in GC_grow_table (table=0x3fc90394c0, log_size_ptr=0x3fc9028b70) at finalize.c:109 #7 0x0000003fc8e126eb in GC_register_finalizer_inner (obj=0x654ff0, fn=0x7ffff7ca1841 , cd=0x0, ofn=0x0, ocd=0x0, mp=0x3fc8e11400 ) at finalize.c:318 #8 0x00007ffff7ca183a in scm_c_register_gc_callback (key=0x654ff0, func=0x7ffff7ca1841 , data=0x0) at gc.c:554 #9 0x00007ffff7ca19dc in scm_storage_prehistory () at gc.c:620 #10 0x00007ffff7cb5e13 in scm_i_init_guile (base=0x7ffff78dcd80) at init.c:397 #11 0x00007ffff7d27c48 in scm_i_init_thread_for_guile (base=0x7ffff78dcd80, parent=0x0) at threads.c:661 #12 0x00007ffff7d27da8 in scm_i_with_guile_and_parent (func=0x4007d4 , data=0x0, parent=0x0) at threads.c:798 #13 0x00007ffff7d27d26 in scm_with_guile (func=0x4007d4 , data=0x0) at threads.c:766 #14 0x00000000004007fe in the_thread () #15 0x0000003fc8e1e435 in GC_inner_start_routine (sb=, arg=) at pthread_start.c:61 #16 0x0000003fc8e18525 in GC_call_with_stack_base (fn=, arg=) at misc.c:1491 #17 0x0000003fc8607761 in start_thread (arg=0x7ffff78dd700) at pthread_create.c:301 #18 0x0000003fc7ee098d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115 Thread 1 (Thread 0x7ffff78df700 (LWP 14166)): #0 0x0000003fc8607fbd in pthread_join (threadid=140737346656000, thread_return=0x7fffffffe018) at pthread_join.c:89 #1 0x0000003fc8e1edd7 in GC_pthread_join (thread=140737346656000, retval=0x7fffffffe018) at pthread_support.c:1214 #2 0x000000000040088a in main () In this case `GC_old_normal_bl' is NULL, as it is only initialized to a valid value if GC_all_interior_pointers is zero, which was not the case when libgc was automatically initialized. What should we do here? Thanks, Andy -- http://wingolog.org/