unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Latest guile 1.9 segfault in GC
@ 2010-08-17  9:09 Cedric Cellier
  2010-08-17 13:08 ` Cedric Cellier
  2010-08-17 14:08 ` Cedric Cellier
  0 siblings, 2 replies; 9+ messages in thread
From: Cedric Cellier @ 2010-08-17  9:09 UTC (permalink / raw)
  To: guile-user

% cat main.c 

#include <stdlib.h>
#include <pthread.h>
#include <libguile.h>

pthread_t dumper;

static void *call_gc(void *null)
{
    scm_gc();
    return NULL;
}
    
void *thread_dumper(void *null)
{
    scm_with_guile(call_gc, NULL);
    return NULL;
}

int main(void)
{
    while (1) {
        pthread_create(&dumper, NULL, thread_dumper, NULL);
        for (;;) sleep(1);
    }

    return EXIT_SUCCESS;
}

% make
gcc -O0 -g3 -ggdb3 -I/usr/local/include/guile/2.0 -I/usr/local/include      main.c  -L/usr/local/lib -lguile-2.0 -lgc -lunistring -lcrypt -lm -lltdl   -lpthread -o main
% ./main 
zsh: segmentation fault (core dumped)  ./main
% gdb main core
...
(gdb) bt
#0  0x00007f184630b698 in GC_is_black_listed (h=0x24ea000, len=4096) at blacklst.c:233
#1  0x00007f1846308c15 in GC_allochblk_nth (sz=512, kind=1, flags=0, n=14, may_split=1) at allchblk.c:690
#2  0x00007f1846308989 in GC_allochblk (sz=512, kind=1, flags=0) at allchblk.c:625
#3  0x00007f18463185f2 in GC_new_hblk (gran=32, kind=1) at new_hblk.c:191
#4  0x00007f184630b090 in GC_allocobj (gran=32, kind=1) at alloc.c:1290
#5  0x00007f1846311010 in GC_generic_malloc_inner (lb=496, k=1) at malloc.c:126
#6  0x00007f1846310fd9 in GC_generic_malloc_inner (lb=496, k=1) at malloc.c:121
#7  0x00007f18463111b4 in GC_generic_malloc (lb=496, k=1) at malloc.c:166
#8  0x00007f1846311644 in GC_core_malloc (lb=496) at malloc.c:276
#9  0x00007f184631d19f in GC_malloc (bytes=496) at thread_local_alloc.c:161
#10 0x00007f18465f6d6e in scm_gc_malloc (size=496, what=0x7f18466d8cd0 "thread") at gc-malloc.c:189
#11 0x00007f184666f0b3 in guilify_self_1 (base=0x7f1844af9d88) at threads.c:325
#12 0x00007f1846671a3e in scm_threads_prehistory (base=0x7f1844af9d88) at threads.c:1924
#13 0x00007f184660b9a5 in scm_i_init_guile (base=0x7f1844af9d88) at init.c:442
#14 0x00007f184666f718 in scm_i_init_thread_for_guile (base=0x7f1844af9d88, parent=0x0) at threads.c:582
#15 0x00007f184666f8c7 in scm_i_with_guile_and_parent (func=0x4007f4 <call_gc>, data=0x0, parent=0x0) at threads.c:730
#16 0x00007f184666f866 in scm_with_guile (func=0x4007f4 <call_gc>, data=0x0) at threads.c:713
#17 0x0000000000400827 in thread_dumper (null=0x0) at main.c:15
#18 0x00007f184631e66e in GC_inner_start_routine (sb=0x7f1844af9e80, arg=0x24e8fc0) at pthread_support.c:1216
#19 0x00007f1846317d97 in GC_call_with_stack_base (fn=0x7f184631e572 <GC_inner_start_routine>, arg=0x24e8fc0) at misc.c:1361
#20 0x00007f184631e6df in GC_start_routine (arg=0x24e8fc0) at pthread_support.c:1247
#21 0x00007f18457079ca in start_thread (arg=<value optimized out>) at pthread_create.c:300
#22 0x00007f18454646fd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#23 0x0000000000000000 in ?? ()

% guile
GNU Guile 1.9.11.259-252f

Which I just compiled from commit 252f9f187ac8608ebcbf513bbbda49fc085f3a52

Any idea welcome.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-17  9:09 Latest guile 1.9 segfault in GC Cedric Cellier
@ 2010-08-17 13:08 ` Cedric Cellier
  2010-08-18 14:07   ` Ludovic Courtès
  2010-08-17 14:08 ` Cedric Cellier
  1 sibling, 1 reply; 9+ messages in thread
From: Cedric Cellier @ 2010-08-17 13:08 UTC (permalink / raw)
  To: guile-user

I'm using libgc v 7.2alpha4.

Apparently the value of GC_all_interior_pointers is 1 when initializing
the GC (so GC_old_normal_bl is not initialized) and suddenly is set to 1
so that the next call to GC_is_black_listed dereference it and thus
crash.

It's set to 0 by scm_storage_prehistory in liguile.

I do not understand how this GC works, but find it strange that this global
variable is changed like this, especially since the libgc gc.h reads :
"GC_all_interior_pointers (...) May not be changed after GC initialization."

How come the libgc GC_init function was already called when
scm_storage_prehistory is called ? Apparently, the libgc overload
pthread_create with its GC_pthread_create().

So, guile must be inited before starting any thread.

Let's try...

OK, it works.

:-)



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-17  9:09 Latest guile 1.9 segfault in GC Cedric Cellier
  2010-08-17 13:08 ` Cedric Cellier
@ 2010-08-17 14:08 ` Cedric Cellier
  2010-08-18 14:12   ` Ludovic Courtès
  2010-08-18 16:16   ` Andy Wingo
  1 sibling, 2 replies; 9+ messages in thread
From: Cedric Cellier @ 2010-08-17 14:08 UTC (permalink / raw)
  To: guile-user

Ok, this bug was fixed but not the actual bug I was after.

But finaly, thanks to libgc's debug message, I got it.
Actually, libgc overwrite pthread_create (and pthread_sigmask,
and a few more) to know when a new thread is started.
But this overloading is done "softly", ie. by a define in a
C header file.

The program I'm working on was composed of many compilation unit,
of which only a few include libguile (which then include gc.h).
Some of these compilation unit were calling pthread_create without
including libguile, and then when these threads were garbage
collecting libgc crashed.

So, in conclusion : always include libguile.h in the compilation
units calling pthread functions.

I would have prefered another solution, but I think we can live with
that, _if_ it's documented somewhere.

As a side note, I find libguile 1.9 slower than libguile 1.8.7.
I suppose, being an unstable version, it's compiled by default
with many debug options on. Is there an easy way to configure it
for fast execution, for benchmarking reason ?




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-17 13:08 ` Cedric Cellier
@ 2010-08-18 14:07   ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2010-08-18 14:07 UTC (permalink / raw)
  To: guile-user

Hi!

Cedric Cellier <rixed@happyleptic.org> writes:

> I do not understand how this GC works, but find it strange that this global
> variable is changed like this, especially since the libgc gc.h reads :
> "GC_all_interior_pointers (...) May not be changed after GC initialization."

‘scm_storage_prehistory’ does that in the right order:

  void
  scm_storage_prehistory ()
  {
    GC_all_interior_pointers = 0;
    GC_set_free_space_divisor (scm_getenv_int ("GC_FREE_SPACE_DIVISOR", 3));

    GC_INIT ();

> How come the libgc GC_init function was already called when
> scm_storage_prehistory is called ? Apparently, the libgc overload
> pthread_create with its GC_pthread_create().
>
> So, guile must be inited before starting any thread.
>
> Let's try...
>
> OK, it works.

Cool.  :-)

Thanks,
Ludo




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-17 14:08 ` Cedric Cellier
@ 2010-08-18 14:12   ` Ludovic Courtès
  2010-08-18 16:16   ` Andy Wingo
  1 sibling, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2010-08-18 14:12 UTC (permalink / raw)
  To: guile-user

Hi,

Cedric Cellier <rixed@happyleptic.org> writes:

> But finaly, thanks to libgc's debug message, I got it.
> Actually, libgc overwrite pthread_create (and pthread_sigmask,
> and a few more) to know when a new thread is started.
> But this overloading is done "softly", ie. by a define in a
> C header file.

[...]

> So, in conclusion : always include libguile.h in the compilation
> units calling pthread functions.

That’s not entirely true, see Section “Thread Support” at
<http://www.hpl.hp.com/personal/Hans_Boehm/gc/gcdescr.html>:

  All  implementations must intercept  thread creation  and a  few other
  thread-specific calls to allow  enumeration of threads and location of
  thread stacks.  This is current  accomplished with # define's  in gc.h
  (really gc_pthread_redirects.h), or  optionally by using ld's function
  call wrapping mechanism under Linux.

Indeed, here’s what I have on GNU/Linux:

  $ objdump -T ~/soft/lib/libgc.so|grep pthread_create
  000000000001ef80 g    DF .text  000000000000028e  Base        GC_pthread_create
  0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 pthread_create

What OS do you use?

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-17 14:08 ` Cedric Cellier
  2010-08-18 14:12   ` Ludovic Courtès
@ 2010-08-18 16:16   ` Andy Wingo
  2010-08-21  1:42     ` rixed
  2010-08-23 12:47     ` Cedric Cellier
  1 sibling, 2 replies; 9+ messages in thread
From: Andy Wingo @ 2010-08-18 16:16 UTC (permalink / raw)
  To: Cedric Cellier; +Cc: guile-user

Hi Cedric,

On Tue 17 Aug 2010 07:08, Cedric Cellier <rixed@happyleptic.org> writes:

> As a side note, I find libguile 1.9 slower than libguile 1.8.7.
> I suppose, being an unstable version, it's compiled by default
> with many debug options on. Is there an easy way to configure it
> for fast execution, for benchmarking reason ?

Guile 1.9's interpreter is slower than 1.8's interpreter, but 1.9 has a
compiler, and compiled Scheme runs much faster than 1.8.

You're probably not hitting the compiler for some reason. I think that
scm_primitive_load doesn't support autocompilation, where it probably
should. Is that the function you're using to load your Scheme code?

To work around it for now, call `load' from scheme. I know it's ugly but
at least you get the speed that way. Use scm_primitive_eval (scm_list_2
(scm_from_locale_string ("load"), path)).

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-18 16:16   ` Andy Wingo
@ 2010-08-21  1:42     ` rixed
  2010-08-23 12:47     ` Cedric Cellier
  1 sibling, 0 replies; 9+ messages in thread
From: rixed @ 2010-08-21  1:42 UTC (permalink / raw)
  To: guile-user

[-- Attachment #1: Type: text/plain, Size: 736 bytes --]

> Guile 1.9's interpreter is slower than 1.8's interpreter, but 1.9 has a
> compiler, and compiled Scheme runs much faster than 1.8.

"much faster" is very nice to hear !

> You're probably not hitting the compiler for some reason. (...)
> To work around it for now, call `load' from scheme. I know it's ugly but
> at least you get the speed that way. Use scm_primitive_eval (scm_list_2
> (scm_from_locale_string ("load"), path)).

Thank you I will give it a try, but I remember having seen messages on stdout dfrom guile pretending that it was compiling my code, and having seen some bytecode in the cache. But maybe everything was not compiled. I will try and report next monday.

Again, thank you all for your good work and support !

[-- Attachment #2: Type: text/html, Size: 1097 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-18 16:16   ` Andy Wingo
  2010-08-21  1:42     ` rixed
@ 2010-08-23 12:47     ` Cedric Cellier
  2010-08-24 16:31       ` Ludovic Courtès
  1 sibling, 1 reply; 9+ messages in thread
From: Cedric Cellier @ 2010-08-23 12:47 UTC (permalink / raw)
  To: guile-user

-[ Wed, Aug 18, 2010 at 09:16:15AM -0700, Andy Wingo ]----
> You're probably not hitting the compiler for some reason. I think that
> scm_primitive_load doesn't support autocompilation, where it probably
> should. Is that the function you're using to load your Scheme code?

Ok, the file I load with scm_primitive_load is not compiled but the files
loaded by it were actually compiled. So I moved the critical functions
from the first one to the others, and now I think all the usefull functions
are compiled.

1.9.11 version still seams a bit slower than 1.8.7, most of the time
being spent in vm_debug_engine, malloc and free.

> To work around it for now, call `load' from scheme. I know it's ugly but
> at least you get the speed that way. Use scm_primitive_eval (scm_list_2
> (scm_from_locale_string ("load"), path)).

I tried but then apparently the load paths were affected in some way,
since the files loaded from the first evaluated file cannot be found.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Latest guile 1.9 segfault in GC
  2010-08-23 12:47     ` Cedric Cellier
@ 2010-08-24 16:31       ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2010-08-24 16:31 UTC (permalink / raw)
  To: guile-user

Hi Cédric,

Cedric Cellier <rixed@happyleptic.org> writes:

> 1.9.11 version still seams a bit slower than 1.8.7,

At doing what?  Is there a minimal test case you could post?

> most of the time being spent in vm_debug_engine,

That’s the bytecode interpreter, so it’s expected.  :-)

> malloc and free.

That’s more surprising.  That could happen, e.g., if your code calls a
lot of C functions that take string arguments, which are converted from
Scheme using scm_to_locale_string, which in turn calls malloc.

Besides, which profiling tool did you use?

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-08-24 16:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-17  9:09 Latest guile 1.9 segfault in GC Cedric Cellier
2010-08-17 13:08 ` Cedric Cellier
2010-08-18 14:07   ` Ludovic Courtès
2010-08-17 14:08 ` Cedric Cellier
2010-08-18 14:12   ` Ludovic Courtès
2010-08-18 16:16   ` Andy Wingo
2010-08-21  1:42     ` rixed
2010-08-23 12:47     ` Cedric Cellier
2010-08-24 16:31       ` Ludovic Courtès

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).