thisisnic commented on code in PR #51288:
URL: https://github.com/apache/arrow/pull/51288#discussion_r4508296703
##########
r/tests/testthat/test-altrep.R:
##########
@@ -654,3 +654,64 @@ test_that("Materialized ALTREP arrays don't cause arrow to
crash when attempting
expect_equal(infer_type(b_int), int32())
expect_equal(as_arrow_array(b_int), a_int)
})
+
+test_that("strings returned by ALTREP Elt() survive garbage collection", {
+ # Base R may hold the CHARSXP returned by STRING_ELT() across an allocation,
+ # so an unmaterialized ALTREP string vector must keep every string it has
+ # handed out reachable (GH-51198). Reproducer adapted from
+ # https://gist.github.com/traversc/a5204821451198d457edc38cceda9d90
+ withr::local_options(list(arrow.use_altrep = TRUE))
+ skip_on_cran()
+
+ # Build the string inside Arrow so that this R session never holds a CHARSXP
+ # with these contents: the only one is the one Elt() creates. It is large so
+ # that R returns its memory to the OS when it is freed, which turns a silent
+ # read of freed memory into a crash.
+ input <- call_function(
+ "binary_repeat",
+ Array$create("a"),
+ Array$create(16L * 1024L * 1024L)
+ )$as_vector()
+ expect_true(is_arrow_altrep(input))
+ expect_false(test_arrow_altrep_is_materialized(input))
+
+ # A latin1 target makes charmatch() allocate (for UTF-8 translation) while
+ # it still holds the pointer to the element of `input`.
+ target <- rawToChar(as.raw(c(rep.int(0x61L, 64L), 0xe9L)))
+ Encoding(target) <- "latin1"
+ target <- rep.int(target, 256L)
+
+ gctorture(TRUE)
+ on.exit(gctorture(FALSE), add = TRUE)
+ observed <- charmatch(input, target, nomatch = NA_integer_)
+ gctorture(FALSE)
Review Comment:
I'll add a comment to explain it better
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]