[Rcpp-devel] Rcpp::exception + threads = disaster

Iñaki Ucar iucar at fedoraproject.org
Sat Feb 8 19:55:50 CET 2020


On Fri, 7 Feb 2020 at 14:24, Joshua N Pritikin <jpritikin at pobox.com> wrote:
>
> On Thu, Feb 06, 2020 at 08:40:02PM -0600, Dirk Eddelbuettel wrote:
> > On 6 February 2020 at 20:47, Joshua N Pritikin wrote:
> > | The Rcpp::exception constructor does,
> > |
> > |   rcpp_set_stack_trace(Shield<SEXP>(stack_trace()))
> > |
> > | This can corrupt R if called within an OpenMP block.
> >
> > ... here. In general, we can _never_ call back into R for anything,
> > exceptions or other things.
> >
> > The RcppParallel package documentation is quite good and clear about
> > this; it even has extra data types RMatrix and RVector to stay away
> > from R's memory (which Rcpp is close to for performance and zero
> > copy reasons). The Writing R Extensions manual also as a little, but
> > maybe less clearly.  In short, there is simply "so much going with
> > R" that it stands little chance of every being threadsafe.
> >
> > Which means that your OpenMP (or pthreads or TBB or ..) code has to
> > stay away from R.
>
> Yeah, so I replaced Rcpp::stop with,
>
> template <typename... Args>
> inline void NORET mxThrow(const char* fmt, Args&&... args) {
>     throw std::runtime_error( tfm::format(fmt, std::forward<Args>(args)... ).c_str() );
> }
>
> And now things work great. But why does Rcpp::stop need to get the
> stack_trace? R's stack trace isn't going to change until the control
> flow returns back to R. So why can't you just set a flag to indicate
> that "some C++ exception happened" and grab the stack_trace
> immediately before returning control to R?

Isn't Rcpp::stop's entire purpose to return control to R immediately?

Iñaki


More information about the Rcpp-devel mailing list