From luke-tierney at uiowa.edu  Sun Mar  3 19:55:48 2013
From: luke-tierney at uiowa.edu (luke-tierney at uiowa.edu)
Date: Sun, 3 Mar 2013 12:55:48 -0600
Subject: [Rd] Missing PROTECT in mkPRIMSXP ?
In-Reply-To: <51339234.1030109@fhcrc.org>
References: <51339234.1030109@fhcrc.org>
Message-ID: <alpine.DEB.2.02.1303031255340.3068@luke-Latitude>

Thanks -- fixed in R-devel and R_patched.

luke

On Sun, 3 Mar 2013, Martin Morgan wrote:

> The Bioconductor build for a package DirichletMultinomial on
>
>  R Under development (unstable) (2013-02-26 r62077) -- "Unsuffered 
> Consequences"
>
> at
>
>
> http://bioconductor.org/checkResults/devel/bioc-LATEST/DirichletMultinomial/george2-buildsrc.html
>
> shows
>
> * creating vignettes ... ERROR
> ...
>
> Error: processing vignette ?DirichletMultinomial.Rnw? failed with 
> diagnostics:
> chunk 21 (label = ROC-dmngroup)
> Error in mapply(FUN = f, ..., SIMPLIFY = FALSE) :
>  invalid primitive operation given for dispatch
> Execution halted
>
> I have not been able to reproduce this on other systems, but the basic 
> approach to a simpler reproducible example is to install the 
> DirichletMultinomial Bioconductor package and then
>
>> tools::buildVignettes(dir="DirichletMultinomial")
>
> where the 'dir' argument points to the uncompressed tarball. There is C code 
> in the package, but not reached by this code chunk. Attempts to simplify the 
> code generally results in the error disappearing.
>
> R -d valgrind -e "tools::buildVignettes(dir="DirichletMultinomial")"
>
> does not reveal anything. The error does not occur with gctorture(TRUE); 
> tools::buildVignettes(dir="DirichletMultinomial").
>
>
>
> By setting a breakpoint at Rf_error and creating a back-trace
>
> (gdb) bt
> #0  Rf_error (
>    format=0x7ffff7a7cef8 "invalid primitive operation given for dispatch")
>    at /home/biocbuild/src/R-3.0.r62077/src/main/errors.c:741
> #1  0x00007ffff793a7ed in R_possible_dispatch (call=0x164d5c0, op=0x4d772a0,
>    args=0x53325d0, rho=0x5334428, promisedArgs=TRUE)
>    at /home/biocbuild/src/R-3.0.r62077/src/main/objects.c:1414
> #2  0x00007ffff7908463 in Rf_DispatchOrEval (call=0x164d5c0, op=0x4d772a0,
>    generic=0x7ffff7a8b0ef "length", args=0x53325d0, rho=0x5334428,
>    ans=0x7ffffffe45a0, dropmissing=0, argsevald=1)
>    at /home/biocbuild/src/R-3.0.r62077/src/main/eval.c:2413
> #3  0x00007ffff792c318 in do_mapply (call=0x164d5c0, op=<optimized out>,
>    args=<optimized out>, rho=0x5334428)
>    at /home/biocbuild/src/R-3.0.r62077/src/main/mapply.c:49
> ...
>
> we get to
>
> (gdb) l mapply.c:49
> 44                  /* Cache the .Primitive: unclear caching is worthwhile. 
> */
> 45                  static SEXP length_op = NULL;
> 46                  if (length_op == NULL) length_op = R_Primitive("length");
> 47                  // DispatchOrEval() needs 'args' to be a pairlist
> 48                  SEXP ans, tmp2 = PROTECT(list1(tmp1));
> 49                  if (DispatchOrEval(call, length_op, "length", tmp2, rho, 
> &ans, 0, 1))
> 50                      lengths[i] = (R_xlen_t) (TYPEOF(ans) == REALSXP ?
> 51                                               REAL(ans)[0] : 
> asInteger(ans));
> 52                  UNPROTECT(1);
> 53              }
>
> and it seems like length_op is somehow incorrect. Starting again with a 
> breakpoint at mapply.c:46, and watching the memory location of length_op, 
> once assigned, for a write at the address of length_op
>
> (gdb) b mapply.c:46
> (gdb) r
> ...
> (gdb) p length_op
> $11 = (SEXP) 0x4d772a0
> (gdb) watch *0x4d772a0
> (gdb) c
>
> leads to
>
> (gdb) c
> Continuing.
> Hardware watchpoint 4: *0x4d772a0
>
> Old value = 8
> New value = 0
> Rf_allocSExp (t=<optimized out>)
>    at /home/biocbuild/src/R-3.0.r62077/src/main/memory.c:2056
> 2056        TYPEOF(s) = t;
>
> which is R writing a new SEXP to the length_op location, as though this 
> location had been garbage collected.
>
> Asking for R_Primitive("length") in mapply.c gets us to dstruct.c:60, where 
> we end up at
>
>    if (result == R_NilValue) {
> 	result = allocSExp(type);
> 	SET_PRIMOFFSET(result, offset);
>    }
> ...
>    return result;
>
> which looks like the allocated SEXP is not added to the PrimCache vector, and 
> hence available for garbage collection. Perhaps a patch is along the lines of
>
> Index: dstruct.c
> ===================================================================
> --- dstruct.c	(revision 62113)
> +++ dstruct.c	(working copy)
> @@ -59,6 +59,7 @@
>     if (result == R_NilValue) {
> 	result = allocSExp(type);
> 	SET_PRIMOFFSET(result, offset);
> +	SET_VECTOR_ELT(PrimCache, offset, result);
>     }
>     else if (TYPEOF(result) != type)
> 	error("requested primitive type is not consistent with cached 
> value");
>
>
> Martin
>

-- 
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:   luke-tierney at uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu


[Rd] Missing PROTECT in mkPRIMSXP ?
luke-tierney at uiowa.edu