[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] Help with problem involving GC mixing C/Scheme
From: |
felix winkelmann |
Subject: |
Re: [Chicken-users] Help with problem involving GC mixing C/Scheme |
Date: |
Mon, 9 May 2005 07:56:51 +0200 |
On 5/7/05, Alejandro Forero Cuervo <address@hidden> wrote:
>
> Hello.
>
> Some of my code that involved calling Scheme code from C recently
> started crashing (probably because the input it handles grew
> significantly). After investigation, I managed to isolate the error;
> the following program reproduces it:
>
> ;--- begin ---
>
> (use format)
>
> (define-external (funccall (scheme-object func)) void (func))
>
> (define run
> (foreign-callback-lambda* void ((long n) (scheme-object func))
> "while (n--) funccall(func);"))
>
> (run 1000000 (lambda () format #t "~%"))
>
> ;--- end ---
>
> When I use Chicken 1.935 to build this program and run it, I get:
>
> > Error: call of non-procedure: error in error
>
> Interestingly, if I (set-gc-report! #t), a garbage collection is shown
> right before the error.
>
> Could anybody please point out what am I doing wrong? Or is this a
> problem in Chicken?
>
Since funccall may trigger a garbage collection, the value func
in your run procedure may not be valid, once a GC occurred.
Chicken uses a moving garbage collector, so after a GC, func
still points to the old (dead) version in the previous heap-space.
Errors like this mostly result in random crashes or very strange
behaviour (like the "error in error" message above).
Here is an alternative version:
(use format)
(define-external (funccall (scheme-object func)) void (func))
(define run
(foreign-callback-lambda* void ((long n) (scheme-object func))
"void *r = CHICKEN_new_gc_root();"
"CHICKEN_gc_root_set(r, func);"
"while (n--) funccall(CHICKEN_gc_root_ref(r));"
"CHICKEN_delete_gc_root(r);") )
(run 1000000 (lambda () (format #t "~%")))
cheers,
felix