chicken-users
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]