[Rcpp-devel] tracking volatile bug
Sokol Serguei
serguei.sokol at gmail.com
Fri Nov 21 23:50:21 CET 2014
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.
More information about the Rcpp-devel
mailing list