From hpages at fhcrc.org  Tue Jun  2 10:05:40 2009
From: hpages at fhcrc.org (hpages at fhcrc.org)
Date: Tue, 02 Jun 2009 01:05:40 -0700
Subject: [Rd] formal argument "envir" matched by multiple
	actual	arguments
In-Reply-To: <4A24839C.50403@fhcrc.org>
References: <4A24839C.50403@fhcrc.org>
Message-ID: <20090602010540.k6d93dfdycc884wg@webmail.fhcrc.org>

In fact reg.finalizer() looks like a dangerous feature.

If the finalizer itself triggers (implicitely or
explicitely) garbage collection, then bad things happen.
In the following example, garbage collection is triggered
explicitely (using R-2.9.0):

    setClass("B", representation(bb="environment"))

    newB <- function()
    {
      ans <- new("B", bb=new.env())
      reg.finalizer(ans at bb,
                    function(e)
                    {
                        gc()
                        cat("cleaning", class(ans), "object...\n")
                    }
      )
      return(ans)
    }

    > for (i in 1:500) {cat(i, "\n"); b1 <- newB()}
    1
    2
    3
    4
    5
    6
    ...
    13
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    14
    ...
    169
    170
    171
    Error: not a weak reference
    Error: not a weak reference
    [repeat the above line thousands of times]
    ...
    Error: not a weak reference
    Error: not a weak reference
    cleaning B object...
    Error: SET_VECTOR_ELT() can only be applied to a 'list', not a 'integer'
    Error: SET_VECTOR_ELT() can only be applied to a 'list', not a 'integer'
    [repeat the above line thousands of times]
    ...
    Error: SET_VECTOR_ELT() can only be applied to a 'list', not a 'integer'
    Error: SET_VECTOR_ELT() can only be applied to a 'list', not a 'integer'
    172
    ...
    246
    247
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...
    cleaning B object...

     *** caught segfault ***
    address 0x41, cause 'memory not mapped'

    Traceback:
     1: gc()
     2: function (e) {    gc()    cat("cleaning", class(ans),  
"object...\n")}(<environment>)

    Possible actions:
    1: abort (with core dump, if enabled)
    2: normal R exit
    3: exit R without saving workspace
    4: exit R saving workspace
    Selection: 2
    Save workspace image? [y/n/c]: n
    Segmentation fault

So apparently, if the finalizer triggers garbage collection,
then we can end up with a corrupted session. Then anything can
happen, from the strange 'formal argument "envir" matched by
multiple actual arguments' error I reported in the previous post,
to a segfault. In the worse case, nothing apparently happens but
the output produced by the code is wrong.

Maybe garbage collection requests should be ignored during the
execution of the finalizer? (and more generally during garbbage
collection itself)

Cheers,
H.



[Rd] formal argument "envir" matched by multiple actual arguments
hpages at fhcrc.org