From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.lisp.guile.user Subject: Re: guile-2.0 on mingw: the sequel Date: Mon, 26 Aug 2013 16:28:36 +0300 Message-ID: <8338pwh98b.fsf@gnu.org> References: <83vc2wj4hz.fsf@gnu.org> <83li3siues.fsf@gnu.org> <838uzrioqr.fsf@gnu.org> <83mwo5hjut.fsf@gnu.org> <87zjs5aeps.fsf@tines.lan> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1377523737 23166 80.91.229.3 (26 Aug 2013 13:28:57 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 26 Aug 2013 13:28:57 +0000 (UTC) Cc: guile-user@gnu.org To: Mark H Weaver Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Mon Aug 26 15:28:59 2013 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VDwqn-0006jJ-LU for guile-user@m.gmane.org; Mon, 26 Aug 2013 15:28:57 +0200 Original-Received: from localhost ([::1]:51459 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VDwqn-0001eM-9F for guile-user@m.gmane.org; Mon, 26 Aug 2013 09:28:57 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39421) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VDwqX-0001XO-PN for guile-user@gnu.org; Mon, 26 Aug 2013 09:28:47 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VDwqR-0001qW-Io for guile-user@gnu.org; Mon, 26 Aug 2013 09:28:41 -0400 Original-Received: from mtaout23.012.net.il ([80.179.55.175]:50676) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VDwqR-0001ok-5w for guile-user@gnu.org; Mon, 26 Aug 2013 09:28:35 -0400 Original-Received: from conversion-daemon.a-mtaout23.012.net.il by a-mtaout23.012.net.il (HyperSendmail v2007.08) id <0MS5001003S31U00@a-mtaout23.012.net.il> for guile-user@gnu.org; Mon, 26 Aug 2013 16:28:33 +0300 (IDT) Original-Received: from HOME-C4E4A596F7 ([87.69.4.28]) by a-mtaout23.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0MS50001K43CZ660@a-mtaout23.012.net.il>; Mon, 26 Aug 2013 16:28:25 +0300 (IDT) In-reply-to: <87zjs5aeps.fsf@tines.lan> X-012-Sender: halo1@inter.net.il X-detected-operating-system: by eggs.gnu.org: Solaris 10 X-Received-From: 80.179.55.175 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:10719 Archived-At: > From: Mark H Weaver > Cc: Panicz Maciej Godek , guile-user@gnu.org > Date: Sun, 25 Aug 2013 12:59:43 -0400 > > > Anyway, I looked into this a bit. I can confirm that the simple > > program you mentioned the first time aborts due to "stack overflow" > [...] > > [...] it turns out that GC_get_stack_base, which > > is implemented in libgc, returns zero as the stack base. > > Thanks for looking into this, Eli! > > This raises the question: what's the relevant difference between > Panicz's simple 'main' and Guile's 'main' (in libguile/guile.c) that > causes one to (apparently) initialize the stack base properly, where the > other fails? It would be worthwhile to find out. Thanks for the suggestion, here's some follow-up: Comparison between libguile/guile.exe and the test program shows that the former goes through a different initialization process, calling libgc as part of it. Here's the call stack from guilify_self_1, when called from libguile/guile.exe: Breakpoint 1, guilify_self_1 (base=base@entry=0x28fe8c) at threads.c:533 533 { (gdb) n 541 t.pthread = scm_i_pthread_self (); (gdb) n 542 t.handle = SCM_BOOL_F; (gdb) p t.pthread $1 = 0 (gdb) bt #0 guilify_self_1 (base=base@entry=0x28fe8c) at threads.c:542 #1 0x004330b7 in scm_threads_prehistory (base=base@entry=0x28fe8c) at threads.c:2176 #2 0x00412c2d in scm_i_init_guile (base=base@entry=0x28fe8c) at init.c:386 #3 0x0043249c in scm_i_init_thread_for_guile (base=0x28fe8c, parent=) at threads.c:835 #4 scm_i_init_thread_for_guile (base=0x28fe8c, parent=) at threads.c:814 #5 0x004324c4 in with_guile_and_parent (base=0x28fe8c, data=0x28feb4) at threads.c:901 #6 0x709cae6f in ?? () from D:\usr\bin\libgc-1.dll #7 0x004326cc in scm_i_with_guile_and_parent (parent=, data=0x28fee0, data@entry=0x28feb0, func=func@entry=0x412abc ) at threads.c:951 #8 scm_with_guile (func=func@entry=0x412abc , data=data@entry=0x28fee0) at threads.c:957 #9 0x00412beb in scm_boot_guile (argc=argc@entry=1, argv=argv@entry=0x28c6970, main_func=main_func@entry=0x4013d4 , closure=closure@entry=0x0) at init.c:320 #10 0x004c5eab in main (argc=1, argv=0x28c6970) at guile.c:108 (gdb) p t.base $2 = (SCM_STACKITEM *) 0x28fe8c while the latter does not go through libgc: Breakpoint 1, guilify_self_1 (base=base@entry=0x2deff0c) at threads.c:533 533 { (gdb) bt #0 guilify_self_1 (base=base@entry=0x2deff0c) at threads.c:533 #1 0x00402f5f in scm_threads_prehistory (base=base@entry=0x2deff0c) at threads.c:2176 #2 0x00404b89 in scm_i_init_guile (base=base@entry=0x2deff0c) at init.c:386 #3 0x00402344 in scm_i_init_thread_for_guile (base=0x2deff0c, parent=) at threads.c:835 #4 scm_i_init_thread_for_guile (base=0x2deff0c, parent=) at threads.c:814 #5 0x00402519 in scm_init_guile () at threads.c:869 #6 0x004013c0 in main () at guile-hello.c:13 (gdb) p base->mem_base $1 = (void *) 0x0 In the former case, scm_i_with_guile_and_parent does this: static void * scm_i_with_guile_and_parent (void *(*func)(void *), void *data, SCM parent) { struct with_guile_args args; args.func = func; args.data = data; args.parent = parent; return GC_call_with_stack_base (with_guile_and_parent, &args); } ^^^^^^^^^^^^^^^^^^^^^^^ and the call to GC_call_with_stack_base correctly initializes the stack base: GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func fn, void *arg) { struct GC_stack_base base; void *result; base.mem_base = (void *)&base; <<<<<<<<<<<<<<<<<<<<<<<<<< I have verified in the debugger that base.mem_base gets a good value here. By contrast, in the test program, GC_call_with_stack_base is never called. Instead, GC_get_stack_base is called, which returns zero. The reason for that seems to be that GC_get_stack_base is called _before_ GC_init: (gdb) break GC_get_stack_base Breakpoint 1 at 0x4bbed8 (gdb) break GC_init Breakpoint 2 at 0x4bbfa8 (gdb) r Starting program: D:\usr\eli\utils\guile-2.0.9\guile-hello.exe [New Thread 11200.0x39ac] Breakpoint 1, 0x004bbed8 in GC_get_stack_base () (gdb) bt #0 0x004bbed8 in GC_get_stack_base () #1 0x00402508 in scm_init_guile () at threads.c:868 #2 0x004013c0 in main () at guile-hello.c:13 (gdb) c Continuing. Breakpoint 2, 0x004bbfa8 in GC_init () (gdb) bt #0 0x004bbfa8 in GC_init () #1 0x0043d53b in scm_storage_prehistory () at gc.c:653 #2 0x00404b81 in scm_i_init_guile (base=base@entry=0x2deff0c) at init.c:385 #3 0x00402344 in scm_i_init_thread_for_guile (base=0x2deff0c, parent=) at threads.c:835 #4 scm_i_init_thread_for_guile (base=0x2deff0c, parent=) at threads.c:814 #5 0x00402519 in scm_init_guile () at threads.c:869 #6 0x004013c0 in main () at guile-hello.c:13 (gdb) (Stepping through GC_init shows that GC_setpagesize is called and returns the correct value: 0x1000. But it is called too late.) This happens because scm_init_guile calls GC_get_stack_base without verifying that libgc was initialized. Changing the test program to call GC_init at the beginning, like this: #include #include #include int main (void) { GC_init (); scm_init_guile (); return 0; } passes the stack overflow test, but crashes further down the Guile initialization path: Program received signal SIGSEGV, Segmentation fault. 0x0042c66d in symbol_lookup_assoc_fn (obj=0x2f5870, alist=0x1e4d50, closure=0x0) at symbols.c:176 176 SCM sym = SCM_CAAR (alist); (gdb) bt #0 0x0042c66d in symbol_lookup_assoc_fn (obj=0x2f5870, alist=0x1e4d50, closure=0x0) at symbols.c:176 #1 0x0046a045 in weak_bucket_assoc (table=table@entry=0x2d8fd8, buckets=buckets@entry=0x2d4000, bucket_index=bucket_index@entry=2165, hash_fn=hash_fn@entry=0x42c110 , assoc=assoc@entry=0x42c63c , object=object@entry=0x2f5870, closure=closure@entry=0x0) at hashtab.c:214 #2 0x0046a80e in scm_hash_fn_create_handle_x (table=0x2d8fd8, obj=0x2f5870, init=init@entry=0x904, hash_fn=hash_fn@entry=0x42c110 , assoc_fn=assoc_fn@entry=0x42c63c , closure=closure@entry=0x0) at hashtab.c:698 #3 0x0042c207 in intern_symbol (symbol=) at symbols.c:195 #4 scm_i_str2symbol (str=0x4dd028 ) at symbols.c:218 #5 0x0042c440 in scm_string_to_symbol ( string=string@entry=0x4dd028 ) at symbols.c:323 #6 0x0041d0b5 in scm_init_numbers () at ../libguile/numbers.x:48 #7 0x00404cb9 in scm_i_init_guile (base=base@entry=0x2deff0c) at init.c:453 #8 0x00402348 in scm_i_init_thread_for_guile (base=0x2deff0c, parent=) at threads.c:835 #9 scm_i_init_thread_for_guile (base=0x2deff0c, parent=) at threads.c:814 #10 0x0040251d in scm_init_guile () at threads.c:869 #11 0x004013c5 in main () at guile-hello.c:15 (gdb) Any further ideas?