From: Eli Zaretskii <eliz@gnu.org>
To: Mark H Weaver <mhw@netris.org>
Cc: guile-user@gnu.org
Subject: Re: guile-2.0 on mingw: the sequel
Date: Mon, 26 Aug 2013 16:28:36 +0300 [thread overview]
Message-ID: <8338pwh98b.fsf@gnu.org> (raw)
In-Reply-To: <87zjs5aeps.fsf@tines.lan>
> From: Mark H Weaver <mhw@netris.org>
> Cc: Panicz Maciej Godek <godek.maciek@gmail.com>, 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=<optimized out>) at threads.c:835
#4 scm_i_init_thread_for_guile (base=0x28fe8c, parent=<optimized out>)
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=<optimized out>,
data=0x28fee0, data@entry=0x28feb0,
func=func@entry=0x412abc <invoke_main_func>) at threads.c:951
#8 scm_with_guile (func=func@entry=0x412abc <invoke_main_func>,
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 <inner_main>,
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=<optimized out>) at threads.c:835
#4 scm_i_init_thread_for_guile (base=0x2deff0c, parent=<optimized out>)
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=<optimized out>) at threads.c:835
#4 scm_i_init_thread_for_guile (base=0x2deff0c, parent=<optimized out>)
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 <stdio.h>
#include <guile/2.0/libguile.h>
#include <gc/gc.h>
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 <symbol_lookup_hash_fn>,
assoc=assoc@entry=0x42c63c <symbol_lookup_assoc_fn>,
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 <symbol_lookup_hash_fn>,
assoc_fn=assoc_fn@entry=0x42c63c <symbol_lookup_assoc_fn>,
closure=closure@entry=0x0) at hashtab.c:698
#3 0x0042c207 in intern_symbol (symbol=<optimized out>) at symbols.c:195
#4 scm_i_str2symbol (str=0x4dd028 <scm_logbit_p__name_string_raw_cell>)
at symbols.c:218
#5 0x0042c440 in scm_string_to_symbol (
string=string@entry=0x4dd028 <scm_logbit_p__name_string_raw_cell>)
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=<optimized out>) at threads.c:835
#9 scm_i_init_thread_for_guile (base=0x2deff0c, parent=<optimized out>)
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?
next prev parent reply other threads:[~2013-08-26 13:28 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-22 20:25 guile-2.0 on mingw: the sequel Panicz Maciej Godek
2013-08-23 6:38 ` Eli Zaretskii
2013-08-23 9:29 ` Panicz Maciej Godek
2013-08-23 10:16 ` Eli Zaretskii
2013-08-23 20:14 ` Panicz Maciej Godek
2013-08-24 6:31 ` Eli Zaretskii
2013-08-24 8:05 ` Panicz Maciej Godek
2013-08-25 15:26 ` Eli Zaretskii
2013-08-25 16:59 ` Mark H Weaver
2013-08-25 17:47 ` Eli Zaretskii
2013-08-25 19:03 ` Ludovic Courtès
2013-08-25 19:34 ` Mark H Weaver
2013-08-27 21:51 ` Panicz Maciej Godek
2013-08-26 13:28 ` Eli Zaretskii [this message]
2013-08-23 15:13 ` Mark H Weaver
2013-08-23 15:34 ` Eli Zaretskii
2013-08-25 18:59 ` Ludovic Courtès
2013-08-25 21:19 ` Mark H Weaver
2013-08-26 2:35 ` Eli Zaretskii
2013-08-25 19:50 ` Mark H Weaver
2013-08-25 19:56 ` Mark H Weaver
2013-08-25 20:33 ` Eli Zaretskii
2013-08-25 20:40 ` Eli Zaretskii
2013-08-25 21:42 ` Mark H Weaver
2013-08-25 23:24 ` dsmich
2013-08-26 2:44 ` Eli Zaretskii
2013-08-26 5:56 ` Mark H Weaver
2013-08-26 6:26 ` Mark H Weaver
2013-08-26 13:10 ` Eli Zaretskii
2013-08-26 2:40 ` Eli Zaretskii
2013-08-25 20:32 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8338pwh98b.fsf@gnu.org \
--to=eliz@gnu.org \
--cc=guile-user@gnu.org \
--cc=mhw@netris.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).