calling R API functions after engine shutdown

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

calling R API functions after engine shutdown

Lukas Stadler
Hi!

We’ve recently come across an example where a package (minqa) creates an Rcpp Function object in a static variable.
This causes R_ReleaseObject to be called by the destructor at a very late point in time - as part of the system exit function:

static Function cf("c");

I’m wondering if that is considered to be “safe”?
Is the R engine supposed to stay in a state where calls to API functions are valid, even after it has shut down?
It probably only ever happens with the ReleaseObject function, but even that could cause problems, e.g., with more elaborate refcounting schemes.

- Lukas
______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: calling R API functions after engine shutdown

Tomas Kalibera

Calling R_ReleaseObject in a C++ destructor is not reliable - it can be
bypassed by a non-local return, such as an error. Generally in R one
cannot use C++ destructors reliably for anything that the R runtime
wouldn't do on its own in case of a non-local return.

A destructor that calls just UNPROTECT, in a way that balances out the
protection stack (e.g. Rcpp Shield), is safe because R runtime balances
the protection stack on non-local return. Destructors used in code that
will never call into any R API (such as in a third party library) are
safe, because the R runtime could not do non-local return. All other
destructors are a problem.

UNPROTECT will work even during R shutdown.

In some cases cleanup code that would be put in C++ destructors, if they
were safe with R, can instead be put into R finalizers.

Tomas



On 09/21/2017 04:41 PM, Lukas Stadler wrote:

> Hi!
>
> We’ve recently come across an example where a package (minqa) creates an Rcpp Function object in a static variable.
> This causes R_ReleaseObject to be called by the destructor at a very late point in time - as part of the system exit function:
>
> static Function cf("c");
>
> I’m wondering if that is considered to be “safe”?
> Is the R engine supposed to stay in a state where calls to API functions are valid, even after it has shut down?
> It probably only ever happens with the ReleaseObject function, but even that could cause problems, e.g., with more elaborate refcounting schemes.
>
> - Lukas
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: calling R API functions after engine shutdown

Lukas Stadler
If this is not considered to be safe, then I guess my message can be seen as a heads-up:
If R_ReleaseObject ever does something that is not safe after the R engine has shut down, you will start to see crashes from packages like “minqa”.
In FastR, we ended up adding a global flag that disables parts of the native API because of this.

- Lukas

> On 21 Sep 2017, at 17:53, Tomas Kalibera <[hidden email]> wrote:
>
>
> Calling R_ReleaseObject in a C++ destructor is not reliable - it can be bypassed by a non-local return, such as an error. Generally in R one cannot use C++ destructors reliably for anything that the R runtime wouldn't do on its own in case of a non-local return.
>
> A destructor that calls just UNPROTECT, in a way that balances out the protection stack (e.g. Rcpp Shield), is safe because R runtime balances the protection stack on non-local return. Destructors used in code that will never call into any R API (such as in a third party library) are safe, because the R runtime could not do non-local return. All other destructors are a problem.
>
> UNPROTECT will work even during R shutdown.
>
> In some cases cleanup code that would be put in C++ destructors, if they were safe with R, can instead be put into R finalizers.
>
> Tomas
>
>
>
> On 09/21/2017 04:41 PM, Lukas Stadler wrote:
>> Hi!
>>
>> We’ve recently come across an example where a package (minqa) creates an Rcpp Function object in a static variable.
>> This causes R_ReleaseObject to be called by the destructor at a very late point in time - as part of the system exit function:
>>
>> static Function cf("c");
>>
>> I’m wondering if that is considered to be “safe”?
>> Is the R engine supposed to stay in a state where calls to API functions are valid, even after it has shut down?
>> It probably only ever happens with the ReleaseObject function, but even that could cause problems, e.g., with more elaborate refcounting schemes.
>>
>> - Lukas
>> ______________________________________________
>> [hidden email] mailing list
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel&d=DwIDaQ&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10&r=6DzVcyWX6yyD2r4eAolUQDWVUN_xc9UW6UdTto2_bao&m=YltTQ4tUmVFt23AnHzDGTPVCXmlUiOq1ayKJzhavePU&s=qibOCsqERij4Ymssp_hIfB78JDOA8v0jSYJ7ZTnCNO4&e= 
>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel