Thanks Martin,

Your PROTECT did the job :)

Martin Morgan has written at  Fri, 21 Nov 2014 13:33:47 -0800
On 11/21/2014 09:23 AM, Serguei Sokol wrote:
Well, I could narrow the issue but not yet resolve it.

Le 18/11/2014 20:46, William Dunlap a écrit :
I will try "gctorture(TRUE)" suggested by Martin.
I'll start with this easy part. Unfortunately valgrind
didn't detect any wrong access to memory.

Now, the difficult part.
The most reduced code in cpp producing an error under
gctorture(TRUE) is the following:
8<------------file matrix_norm.cpp
//[[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
SEXP nmat(mat A) {
    Function Matrix_norm_r_=Environment("package:Matrix")["norm"];
    SEXP s=wrap("1");

the reduced example is great. s is not PROTECT()ed, Rf_PrintValue(s) almost certainly decides that it needs memory, and re-uses the SEXP occupied by s for its own internal purposes. So simply

  SEXP s = PROTECT(wrap("1"));
  // ...
  UNPROTECT(1)
  return res;

If I did not use the protection in my Rcpp code it's because
I did not see it in any example of quick ref guide:
http://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-quickref.pdf
I didn't see any mention of PROTECT necessity neither in
http://dirk.eddelbuettel.com/code/rcpp/Rcpp-introduction.pdf
especially in the part dedicated to the use of wrap().

You _could_ figure out where Rf_PrintValue over-writes the unprotected s SEXP,
It turns out that the memory is getting corrupted well before Rf_PrintValue. It was here just to witness the devastation. The corruption occurred inside Rf_mkString()
as shown in the debug session.

but that wouldn't be helpful in any way; R in general and Rf_PrintValue in particular is allowed to write to unprotected SEXPs. It's also not relevant in some ways what the error is -- invalid 'type' or anything else -- just that the error occurs. Also, while not strictly true, it is much more likely that protection errors are in user code (as here), then in package code, and finally in R code itself.

For what it's worth...

    Rf_PrintValue(s);
    SEXP res=Matrix_norm_r_(wrap(A), s);

I think wrap(A) needs (in principle) to be PROTECT()ed, too.
For the sake of safety, I'll do it.


Sometimes in simplifying the problem we introduce new errors; I think your wrap()'s in the original code were immediately returned to the user, so not in need of protection.
In the original code, there were not wraping at all for R function call.
I supposed (very naively, it is clear now) that necessary wrapping and
protection was automagicaly added behind the stage by Rcpp.

I would set a breakpoint on Rf_error, then trigger the error under gctorture(TRUE), then in gdb backtrace to localize which specific line in your code triggers the error, and simplify around that.
That was I have done to find out that Rf_mkString() call was the last part
of Rcpp where corruption occurred.

Thank again.
Serguei.
_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to