-
-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
segfault: terminate called after throwing an instance of 'Rcpp::eval_error' #861
Comments
Well if it works without the new We do have other pending patches for |
My understanding is that conflicted will work around this, but there's nothing like fixing the problem at the source. Here's the Rcpp-only error
|
I will look into it. |
And thanks for the reprex @mtmorgan! |
I don't see where the reprex qualifies as an Rcpp issue after you deliberate muck with the evaluation model. You break, get to keep the pieces. edd@rob:/tmp$ cat worksforme.R
library(Rcpp)
fun <- cppFunction("
NumericVector fun(Function fun1) {
return fun1();
}")
fun(sqrt)
cat("works for me\n")
edd@rob:/tmp$ Rscript worksforme.R
Error in fun(sqrt) :
Evaluation error: 0 arguments passed to 'sqrt' which requires 1.
Calls: fun -> .Call
Execution halted
edd@rob:/tmp$ We supply matches. If you play with fire and burn yourself, is that really our fault? |
The correct assessment is that Rcpp is currently broken. It should be properly encapsulated just like any namespaced code but it isn't right now. |
If as a user I were to write
I'd get burned. I'd then revise my function to
and be able to play with matches (but maybe If I were writing a package, I wouldn't have to How are these use cases different from what Rcpp does, but at the C level? Rcpp intends to use I think I'm not putting words in your mouth to say that we all strive to minimize unexpected terminations, viewing these as serious bugs even in the face of user error (e.g., we'd be really disappointed if Note that we also have other issues with the Rcpp implementation of
I'm only persisting here because I'd like to see Lionel's patch / efforts realized; if we're just talking amongst friends then I'll carry on over drinks with you sometime in the future. |
Sorry, but now you bring the pending patch in. Did you try this problem under it? Is it resolved there? If so, nobody told me yet. |
Sorry bad communication on my part. I meant to convey that I was anticipating that Lionel would address the issue, if not discouraged by you. I don't know of any existing solution, the above is from
installed from github master. |
Well we have been trying to get exceptions, and Everything else we brought up here so far seems like a somewhat marginal corner case to me. Nice to have. not the core functionality we fixed. I would not want to risk to the latter for the former. But well written patches and pull requests are always welcome. I would also welcome solid tests on those, preferably those that are complementary to what I do (near-full rev.dep checks on Linux). So I suggested to Lionel to maybe looking into using Docker / Rocker to test on older R versions. I have not yet heard back from him on that. |
You can see the current (not yet @lionel- version of unwind-protect) version of Rcpp_eval here: Rcpp/inst/include/Rcpp/api/meat/Rcpp_eval.h Lines 100 to 113 in 6886a43
Note that the intention here is effectively to construct a call of the form: tryCatch(evalq(<expr>), error = identity, interrupt = identity) and evaluate that in the requested environment. If you provide alternate definitions for I think we would accept a PR that modified this to instead appear as: base::tryCatch(base::evalq(<expr>), condition = base::identity) Note that this would imply needing to recompile any packages using Rcpp as well to ensure they pick up the new definition of |
That said, the easiest solution here is just "don't load |
I'm not in a position (i.e., I do not have enough experience with the Rcpp internals or indeed C++, especially not at the level of sophistication of Rcpp) to write Rcpp code, so hopefully the pull request will come from elsewhere in the community. I really don't understand the 'don't load |
Same story as with |
You do still need to do something 'strange' -- I think it's relatively uncommon that users might define their own versions of I agree that the issue is real, but it's ultimately rare and is only triggered by packages or users doing funky things. |
@kevinushey I think the fix is just to evaluate the |
s/namespace/package since the former inherits from the search path (just to be on the safe side). |
@lionel- not sure about that. Make sure you test with Bioconductor as well. Many packages there depend on Rcpp and on the redefined eval and evalq in BiocGenerics. I expect more issues with Bioconductor given how conflicted uses a very odd way of messing with the search path (and silently masking library and require). |
Would we ever want |
@JoFAM We definitely should use |
I'll just report that @kevinushey 's patch fixes both my simpler examples and the original segfault in r-lib/conflicted#8 ; this did require recompilation of all packages using Rcpp. Thanks! |
@mtmorgan Cool, thanks for reporting back! To be plain, when you say "patch" you are referring to the new branch that is not yet a PR? |
Yes, this branch
|
@lionel- using Notified bioc-devel : https://www.mail-archive.com/bioc-devel@r-project.org/msg09813.html |
There is no possibility of things going awry. This is private Rcpp code that should be namespaced. This is exactly the same situation as any package code except we have to evaluate R code manually from C++ and doing it in the global env rather than in Rcpp's namespace (or equivalently the base env since we only use base functions here) is a bug. |
On second thought you're right this could have consequences for bioc packages under a particular set of circumstances:
Sorry for unduly dismissing your remarks. Edit: Such packages would only work correctly if they are attached with a |
This sounds (from outside the Rcpp universe) almost like using an internal Rcpp function rather than the public Rcpp interface. If there is some breakage (there are no calls to Rcpp_eval() directly in the Bioc code base, how else might the user end up at Rcpp_eval?), it seems like the author should be doing the equivalent of BiocGenerics::evalq() if that's what they require for dispatch. I'm more than willing to live with this fallout. |
@mtmorgan I wasn't clear enough in my previous postings. I obviously don't encourage using undocumented functions/ relying on unintended behaviour, but I have seen packages before that do things in non-standard ways. I merely wanted the people who have packages in the Bioconductor system to be aware, and wondered if there were contributed packages that did such a thing. Hence my suggestion and mail on bioc-devel. To be clear: even though it might sound that way, it was not my intent to suggest that the official packages of the Bioconductor core team would do such a thing. My apologies for possible confusion, I hope I clarified myself. |
It's part of the Rcpp API so it is public. I agree it's ok (and even desirable) to break packages relying on these semantics, if they exist. |
Fixed via #863 |
I'm not really sure where the responsibility for this lies, but
results in a segfault
Normally (e.g., typing
evalq
at the command line), 'conflicted' would report the conflict between the two definitions of evalq as an error.Rcpp seems to run in to trouble at inst/include/Rcpp/api/meat/Rcpp_eval.h:118 and 134
the call stack before the segfault is
and the expression leading to the exception is, after stepping to line 118
I guess the problem is that an exception occurs while Rcpp is trying to handle an exception?
This is the third time through Rcpp_eval(); the second time through generates the 'conflicted' error. The code in xml2 is
where somehow it seems like
evalq()
used to evaluatereadBin()
should be the version seen by the xml2 namespace rather than found on the search path?The context is at r-lib/conflicted#8
The text was updated successfully, but these errors were encountered: