#1586 closed defect (fixed)
Context-switch from GC causes infinite GC loop
| Reported by: | megane | Owned by: | |
|---|---|---|---|
| Priority: | major | Milestone: | 5.2 |
| Component: | compiler | Version: | 5.0.0 |
| Keywords: | garbage collector context-switch threads scheduler | Cc: | |
| Estimated difficulty: | insane |
Description
The following code causes the runtime to enter an infinite GC loop.
With help of Christian and Kon the cause was determined to be a
re-entry to the GC while GC'ing.
In the example below the thread running a finalizer runs out of its
quantum while running spin and does a context switch. The other
thread then starts a new GC which causes the issue.
Using disable-interrupts makes the issue go away. I haven't tested
if disable-interrupts is enough if the finalizer calls something
that was compiled without disable-interrupts.
I'll attach a fuzzer that can be used instead if the example doesn't
work.
;; (declare (disable-interrupts))
(cond-expand (chicken-5 (import (chicken base))
(import (chicken gc))
(import (srfi 18)))
(else (use srfi-18)))
(define (spin count) (let lp2 ([i 0]) (when (< i count) (lp2 (add1 i)))))
(define (add-finalized) (set-finalizer! (list 'foo) (lambda (o) (spin 100))))
(let lp ([i 0])
(while (< i 100)
(print* i " ")
(let ([threads (list (make-thread
(lambda ()
(add-finalized) (add-finalized)
(gc #t)
(add-finalized) (add-finalized) (add-finalized))
"thread-a")
(make-thread (lambda () (gc #t) (add-finalized) (add-finalized))
"thread-b"))])
(for-each thread-start! threads)
(for-each thread-join! threads))
(lp (add1 i))))
(print "dones")
;; Output:
;; $ csc gcloop2.scm && ./gcloop2
;; 0 1 2 3 4 5 6 7 8 9 10 11 12 <hangs here>
Attachments (1)
Change History (4)
Changed 7 years ago by
| Attachment: | finalizer-fuzz.scm added |
|---|
comment:1 Changed 7 years ago by
comment:3 Changed 6 years ago by
| Milestone: | → 5.2 |
|---|
Setting milestone so we can generate a list of fixed tickets in 5.2

The implication of this is that a program will have a greater than zero change of hanging with the gc-loop if these conditions are met:
disable-interrupts(gc #t)call after a finalizer has been installed