Subject: bug#19180: vacuum_weak_hash_table error

From: [email-masked] (Ludovic Courtès)
Date: Tue, 02 Dec 2014 20:47:22 +0100

Anand Mohanadoss <[email-masked]> skribis:

> #4  0x003b8e96 in __assert_fail () from /lib/libc.so.6
> #5  0x080e93d7 in vacuum_weak_hash_table (table=0x97f8b10) at hashtab.c:137
> #6  0x080e9857 in weak_gc_callback (hook_data=0x0, fn_data=0x6, data=0x0)
> at hashtab.c:437
> #7  weak_gc_hook (hook_data=0x0, fn_data=0x6, data=0x0) at hashtab.c:446
> #8  0x080eaa2d in scm_c_hook_run (hook=0x895acc0, data=0x0) at hooks.c:103
> #9  0x080dfda6 in run_before_gc_c_hook () at gc.c:240
> #10 0x08187719 in GC_notify_full_gc (stop_func=0x81868e0
> <GC_never_stop_func>) at alloc.c:334
> #11 GC_try_to_collect_inner (stop_func=0x81868e0 <GC_never_stop_func>) at
> alloc.c:429
> #12 0x08187d1b in GC_collect_or_expand (needed_blocks=4, ignore_off_page=0,
> retry=0) at alloc.c:1242
> #13 0x0818a64f in GC_alloc_large (lb=14080, k=1, flags=0) at malloc.c:63
> #14 0x0818a9c2 in GC_generic_malloc (lb=14076, k=1) at malloc.c:175
> #15 0x0818ace7 in GC_core_malloc (lb=14076) at malloc.c:263
> #16 0x080df572 in do_gc_malloc (size=0, what=0x6 <Address 0x6 out of
> bounds>) at gc-malloc.c:100
> #17 0x0813a565 in scm_c_make_vector (k=3517, fill=0x304) at vectors.c:408
> #18 0x080e9471 in scm_i_rehash (table=0x97f8b10, hash_fn=0x816c1d0
> <scm_ihashq>, closure=0x0, func_name=0x854f8bd
> "scm_hash_fn_create_handle_x") at hashtab.c:344

Looking at this stack trace, it seems ‘table’ is being concurrently
modified: a GC occurs while it is being rehashed.

Could you apply with attached patch (with “patch -p1 < the-patch” run
from the top of the source tree), and report the lines that are printed
before the assertion failure?

Also, please report the corresponding backtrace, as you did above (just
to make sure this is the same scenario.)

Thanks in advance,
Ludo’.

diff --git a/libguile/hashtab.c b/libguile/hashtab.c
index 44db051..8e7c9bc 100644
--- a/libguile/hashtab.c
+++ b/libguile/hashtab.c
@@ -1,5 +1,5 @@
 /* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2004, 2006,
- *   2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ *   2008, 2009, 2010, 2011, 2012, 2014 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -134,6 +134,7 @@ vacuum_weak_hash_table (SCM table)
       size_t removed;
       SCM alist = SCM_SIMPLE_VECTOR_REF (buckets, k);
       alist = scm_fixup_weak_alist (alist, &removed);
+      printf ("%i %p l=%zi r=%zi\n", __LINE__, table, len, removed);
       assert (removed <= len);
       len -= removed;
       SCM_SIMPLE_VECTOR_SET (buckets, k, alist);
@@ -341,7 +342,9 @@ scm_i_rehash (SCM table,
   SCM_HASHTABLE (table)->upper = 9 * new_size / 10;
   buckets = SCM_HASHTABLE_VECTOR (table);
 
+  printf ("%i %p l=%zi\n", __LINE__, table, SCM_HASHTABLE_N_ITEMS (table));
   new_buckets = scm_c_make_vector (new_size, SCM_EOL);
+  printf ("%i %p l=%zi\n", __LINE__, table, SCM_HASHTABLE_N_ITEMS (table));
 
   /* When this is a weak hashtable, running the GC might change it.
      We need to cope with this while rehashing its elements.  We do