Skip to content
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

Double free crash with uncaught exceptions on CRAN's fedora-clang platform #161

Open
glin opened this issue Jan 8, 2023 · 5 comments
Open

Comments

@glin
Copy link

glin commented Jan 8, 2023

Splitting this out from #128:

I just had to fix a really tough double free crash on CRAN's fedora-clang platform with my V8-using package too. Maybe it's the same issue, or related, or at least helpful in some way.

For whatever reason, the double free error was being caused by an uncaught exception in V8 there. To reproduce, you can use R-hub's fedora-clang-devel image (Fedora 33 and a bit behind CRAN, but still works). Install V8 using g++, not clang, as CRAN does, and then throw any error in V8 like throw new Error().

docker run -it --rm rhub/fedora-clang-devel

dnf install -y v8-devel

# Compile V8 with g++ as CRAN does - there's probably a better way to do this
cp ~/.R/Makevars ~/.R/Makevars.bk
echo 'CXX17=g++' >> ~/.R/Makevars
/opt/R-devel/bin/R -e 'options(repos = "https://cloud.r-project.org"); install.packages("V8")'
mv -f ~/.R/Makevars.bk ~/.R/Makevars

/opt/R-devel/bin/R -e 'ctx <- V8::new_context(); ctx$eval("throw new Error()")'
# > ctx <- V8::new_context(); ctx$eval("throw new Error()")
# free(): double free detected in tcache 2
# Aborted (core dumped)

My package was throwing an error to detect the broken V8 package on Fedora <= 36 (#65) to skip some tests, and hitting this crash. My sketchy workaround was to try and test for this in a separate R process like:

code <- "V8::new_context()$eval('not_defined')"
output <- suppressWarnings(
  system2(R.home("bin/R"), c("-e", shQuote(code)), stdout = TRUE, stderr = TRUE)
)
if (attr(output, "status") > 0 && !grepl("ReferenceError", paste(output, collapse = "\n"))) {
  # Then skip any tests that may throw uncaught exceptions
}

@jeroen:

I think this is a separate issue that is caused by an ABI incompatibility between libcxx (used by R) and libstdc++ (used by Fedora to compile v8-devel).

@jeroen
Copy link
Owner

jeroen commented Jan 15, 2023

FYI this problem disappears when we also recompile compile Rcpp with g++. I think the issue is that V8 throws an error using libstdc++, which gets caught by Rcpp, which uses the other libcxx.

Update: compiling V8 with -DRCPP_USE_UNWIND_PROTECT does not make any difference.

@jeroen
Copy link
Owner

jeroen commented Jan 17, 2023

@glin which package was the package that crashed for you? That allows me to test for a solution.

@jeroen
Copy link
Owner

jeroen commented Jan 17, 2023

You should now be able to install V8 with clang-libcxx by setting a variable DOWNLOAD_STATIC_LIBV8=1 at install time:

export DOWNLOAD_STATIC_LIBV8=1
/opt/R-devel/bin/R -e 'options(repos = "https://cloud.r-project.org"); install.packages("V8")'

So you shouldn't need to use gcc to install V8.

@glin
Copy link
Author

glin commented Jan 21, 2023

It was my package, reactable, but I had to fix it asap so it's no longer failing CRAN checks (glin/reactable#308). If you still want to test it out though, you could grab the v0.4.2 tag from GitHub: https://github.com/glin/reactable/tree/v0.4.2

And awesome, I can confirm that installing the static V8 fixes the crash on Fedora with both my simple repro and v0.4.2 package tests. The only other question is whether CRAN would be able to install that on their fedora-clang machine?

@jeroen
Copy link
Owner

jeroen commented Jan 21, 2023

The only other question is whether CRAN would be able to install that on their fedora-clang machine?

I sent a message to BDR but he has not responded. I guess we'll need to be patient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants