<br><br><div class="gmail_quote">On Sun, Jan 9, 2011 at 1:07 PM, Dirk Eddelbuettel <span dir="ltr">&lt;<a href="mailto:edd@debian.org">edd@debian.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im"><br>
On 9 January 2011 at 12:12, Dominick Samperi wrote:<br>
| Actually, the problem seems to be pretty transparent, and the<br>
| solution is the same (see below). This gets you through Evaluator,<br>
| but you fail in SlotProxy in the call to &quot;$&lt;-&quot;. The fact that these<br>
| problems only appear when gctorture() is turned on suggests<br>
| that they all of the same explanation: unprotected SEXP&#39;s.<br>
|<br>
| same:<br>
| //#define UNSAFE_CODE<br>
| #ifdef UNSAFE_CODE<br>
|     int error = LOGICAL( Rf_eval( Rf_lang1( Rf_install(&quot;errorOccured&quot;) ),<br>
| RCPP ) )[0];<br>
| #else<br>
|     SEXP cmd = PROTECT(Rf_lang1( Rf_install(&quot;errorOccured&quot;)));<br>
|     int error = LOGICAL(Rf_eval( cmd, RCPP ))[0];<br>
|     UNPROTECT(1);<br>
| #endif<br>
|     Rprintf(&quot;Got error = %d\n&quot;, error);<br>
|  <br>
<br>
</div>There may be an impedance mismatch going on.  &#39;Writing R Extension&#39; says<br>
<br>
    4.3.1 Using gctorture<br>
    ---------------------<br>
<br>
    We can help to detect memory problems earlier by running garbage<br>
    collection as often as possible.  This is achieved by<br>
    `gctorture(TRUE)&#39;, which as described on its help page<br>
<br>
         Provokes garbage collection on (nearly) every memory allocation.<br>
         Intended to ferret out memory protection bugs.  Also makes R run<br>
         _very_ slowly, unfortunately.<br>
<br>
    The reference to `memory protection&#39; is to missing C-level calls to<br>
    `PROTECT&#39;/`UNPROTECT&#39; (*note Garbage Collection::) which if missing<br>
    allow R objects to be garbage-collected when they are still in use.<br>
    But it can also help with other memory-related errors.<br>
<br>
       Normally running under `gctorture(TRUE)&#39; will just produce a crash<br>
    earlier in the R program, hopefully close to the actual cause. See the<br>
    next section for how to decipher such crashes.<br>
<br>
       It is possible to run all the examples, tests and vignettes covered<br>
    by `R CMD check&#39; under `gctorture(TRUE)&#39; by using the option<br>
    `--use-gct&#39;.<br>
<br>
I do not see this as compatible with the C++ Design principle we use whereby<br>
protection / unprotection occurs relative to the end of scope -- and not<br>
after every single assignment or allocation.<br></blockquote><div><br>Thanks, but note that Doug&#39;s original report was not about gctorture(). We<br>are using this tool to try to fix the memory corruption problems, and this<br>
tool seems to be pretty helpful for this purpose, even if it might be too<br>demanding in some situations.<br><br>Dominick<br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<br>
In other words, gctorture() may well be a fine test for the C API and its<br>
PROTECT and UNPROTECT at every step but possibly not quite as much for Rcpp.<br>
<br>
Dirk<br>
<br>
PS Here is slight generalization of your examples. Cases 2 and 3 do not bomb,<br>
and Case 3 is using almost all Rcpp idioms (but for the final Rf_eval call).<br>
<br>
-----------------------------------------------------------------------------<br>
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-<br>
<br>
#include &quot;Rcpp.h&quot;<br>
<br>
RcppExport SEXP testfft(SEXP vec, SEXP env, SEXP choiceS) {<br>
<br>
    int choice = Rcpp::as&lt;int&gt;(choiceS);<br>
    SEXP res = R_NilValue;<br>
<br>
    if (choice == 1) {<br>
        Rprintf(&quot;In case 1\n&quot;);<br>
        // may not survive gctorture(), sometimes!<br>
        SEXP call = ::Rf_lcons(Rf_install(&quot;fft&quot;),<br>
                               Rf_cons(vec , R_NilValue));<br>
        res = PROTECT(Rf_eval(call, env));<br>
        UNPROTECT(1);<br>
<br>
    } else if (choice == 2) {<br>
        Rprintf(&quot;In case 2\n&quot;);<br>
        // always survives gctorture()<br>
        SEXP call = PROTECT(::Rf_lcons(Rf_install(&quot;fft&quot;),<br>
                                       Rf_cons(vec , R_NilValue)));<br>
        res = PROTECT(Rf_eval(call, env));<br>
        UNPROTECT(2);<br>
<br>
    } else if (choice == 3) {<br>
        Rprintf(&quot;In case 3\n&quot;);<br>
        Rcpp::Function fft(&quot;fft&quot;);<br>
        Rcpp::Environment env_(env);<br>
        Rcpp::Language call(fft);<br>
        call.push_back(vec);<br>
        res = Rf_eval(call, env_);<br>
    }<br>
    return res;<br>
}<br>
-----------------------------------------------------------------------------<br>
<br>
and<br>
<br>
-----------------------------------------------------------------------------<br>
# Tests Rcpp Evaluator code with PROTECTION fix and gctorture ON.<br>
# Should get a complex vector of zeros.<br>
library(Rcpp)<br>
gctorture()<br>
dyn.load(&quot;testfft.so&quot;)<br>
for (i in 2:3) {  # bombs on 1 but not 2 or 3<br>
    print(.Call(&#39;testfft&#39;, 1:20, getNamespace(&quot;stats&quot;), i) - fft(1:20))<br>
}<br>
cat(&quot;still here\n&quot;)<br>
-----------------------------------------------------------------------------<br>
<br>
<br>
edd@max:/tmp/samperi-gc$ r -lRcpp -e&#39;Rcpp:::SHLIB(&quot;testfft.cpp&quot;)&#39;<br>
ccache g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include     -fpic  -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c testfft.cpp -o testfft.o<br>
g++ -shared -o testfft.so testfft.o -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib -L/usr/lib64/R/lib -lR<br>
edd@max:/tmp/samperi-gc$ r torture.R<br>
Loading required package: methods<br>
In case 2<br>
 [1] 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i<br>
In case 3<br>
 [1] 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i<br>
still here<br>
edd@max:/tmp/samperi-gc$<br>
<font color="#888888"><br>
--<br>
</font><div><div></div><div class="h5">Dirk Eddelbuettel | <a href="mailto:edd@debian.org">edd@debian.org</a> | <a href="http://dirk.eddelbuettel.com" target="_blank">http://dirk.eddelbuettel.com</a><br>
</div></div></blockquote></div><br>