Hello,

This is somewhat of a known issue we have with windows for some time.
Thanks for looking into it.

If I apply your suggestion to the generator file and it does not break existing code (i.e. as defined by our unit tests), would you be willing to test it on your settings ?

Romain

Le 2013-06-13 10:17, QRD a écrit :
Hi,

I've just had some trouble, on Windows with Rtools-3.0, throwing
exceptions from within a standalone function belonging to a module:

- - - - 8< - - - - crash.cpp

#include <stdexcept>
#include <Rcpp.h>

int calculate(int x)
{
    throw std::invalid_argument("x is invalid");
}

RCPP_MODULE(Crash)
{
    Rcpp::function("calculate", &calculate);
}

- - - - 8< - - - - crash.R

require(methods)
require(Rcpp)

dll.info <- dyn.load("crash")
mod <- Module("Crash", dll.info, mustStart = TRUE)

mod$calculate(42)

- - - - 8< - - - - shell prompt

R CMD SHLIB crash.cpp && Rscript crash.R

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'std::invalid_argument'
  what():  x is invalid

- - - - 8< - - - -

This is strange as there is a BEGIN_RCPP / END_RCPP pair in the relevant
function in Module.cpp:

    extern "C" SEXP InternalFunction_invoke( SEXP args ){
    BEGIN_RCPP
            SEXP p = CDR(args) ;
            XP_Function fun( CAR(p) ) ; p = CDR(p) ;
            UNPACK_EXTERNAL_ARGS(cargs,p)
            return fun->operator()( cargs ) ;
    END_RCPP
    }

What seems to be going on is:

Under MinGW, you can only throw/catch exceptions across a DLL boundary
when linking to the 'DLL runtime'.  I'm basing this on quite an old
post (from Jan 2011):



http://mingw-users.1079350.n2.nabble.com/dlls-and-exceptions-using-a-cross-compiler-td5967925.html

This is my situation, because I throw the exception from crash.dll, but it's the above code from Module.cpp in Rcpp.dll which tries to catch it.

The R scripts use a link invocation which includes '-static-libgcc':

    R CMD SHLIB # ...
    g++ -m64 -shared -s -static-libgcc -o crash.dll  # [... etc. ...]

and also Rtools's 'g++ -v' reports that it was configured with
'--disabled-shared':

    Target: i686-w64-mingw32
    Configured with: [...] --disable-shared --enable-static [...]
    Thread model: win32
    gcc version 4.6.3 20111208 (prerelease) (GCC)

This problem doesn't show up with throwing exceptions from class member functions, because in that case, all the work gets done in a template, so
the try/catch is compiled into my module's DLL.

For an only-mildly-ugly workaround, I put a BEGIN_RCPP / END_RCPP pair around the call in the CppFunction1<OUT, U0> template class (c. line 104
in Module_generated_CppFunction.h):

    SEXP operator()(SEXP* args) {

        BEGIN_RCPP    // <<-- ADD THIS

        return Rcpp::module_wrap<OUT>( ptr_fun( /* ... */ ) );

        END_RCPP      // <<-- AND THIS

    }

This is a template, so it gets compiled into my DLL, the exception never
leaves my DLL, and all is well.

Because of the '_generated_' in the filename, I haven't created a patch.

If the above is right, do you think adding BEGIN_RCPP / END_RCPP pairs
in all of the CppFunction-derived classes would be acceptable to work
round this feature of the current build set-up under MinGW?

Thanks,

Ben.
_______________________________________________
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
_______________________________________________
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