[Rd] Missing PROTECT in mkPRIMSXP ?

peter dalgaard pdalgd at gmail.com
Mon Mar 4 07:25:37 CET 2013


On Mar 3, 2013, at 19:55 , <luke-tierney at uiowa.edu> <luke-tierney at uiowa.edu> wrote:

> Thanks -- fixed in R-devel and R_patched.

However, notice that the change in R-patched is not likely to make it into a public release since 2.15.3 is officially final and we branch for 3.0.x on Wednesday. (It will be present in the 3.x.y series, of course.)

If this bug bites someone who for whatever reason wants to stay on 2.15.3, they'll have to dig the patch out from SVN.

Peter 

> 
> 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______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Peter Dalgaard, Professor,
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com



More information about the R-devel mailing list