Subject: bug#28590: Weak tables in 2.2.2 grow indefinitely

From: [email-masked] (Ludovic Courtès)
Date: Tue, 26 Sep 2017 11:57:54 +0200

[email-masked] (Ludovic Courtès) skribis:

> Consider this program:
>
> (use-modules (ice-9 format))
>
> (define loops 3000000)
>
> (define table
>   (make-weak-key-hash-table))
>
> (let loop ((i loops))
>   (unless #f ;(zero? i)
>     (when (zero? (modulo i 100000))
>       (format #t "heap-size: ~,2h MiB  table: ~s~%"
>               (/ (assoc-ref (gc-stats) 'heap-size) (expt 2. 20))
>               table))
>
>     (hashq-set! table (cons 1 2) #t)
>     (loop (1- i))))

I’ve changed it to do:

    (hashq-set! table (cons 1 2) (make-vector 10000))

Then if we build Guile with -DGC_DEBUG=1, link it against libgc built
with -DKEEP_BACK_PTRS=1, and run with “GC_BACKTRACES=1”, we see that the
heap is full of those 10,000-element vectors:

  0x54ae9030 (../libguile/gc.h:232, sz=80008, NORMAL)
  Reference could not be found
  0x1bee5030 (../libguile/gc.h:232, sz=80008, NORMAL)
  Reference could not be found
  0x60491030 (../libguile/gc.h:232, sz=80008, NORMAL)
  Reference could not be found

Problem is that “Reference could not be found” corresponds to
GC_UNREFERENCED in <gc_backptr.h>, meaning that there’s no reference
holding this object.  Interesting no?

(Though it could also be a bug in the back-pointer code, or pretty much
anything!)

Ludo’.