[Rcpp-devel] Problem with exceptions from standalone functions (Windows only)
Romain Francois
romain at r-enthusiasts.com
Tue Jun 18 19:10:45 CEST 2013
Hi,
I have commited adding BEGIN_RCPP and END_RCPP.
Could you have a go at testing it on Windows.
Romain
Le 13/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.
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
R Graph Gallery: http://gallery.r-enthusiasts.com
blog: http://blog.r-enthusiasts.com
|- http://bit.ly/Zs97qg : highlight 0.4.1
`- http://bit.ly/10X94UM : Mobile version of the graph gallery
More information about the Rcpp-devel
mailing list