-
-
Notifications
You must be signed in to change notification settings - Fork 220
Description
I've been running into a very hard-to-debug problem which I believe is due to a GC during assignment to an Environment. In some cases, the result of assignment into an Environment has the wrong type, and in other cases, the Environment somehow gets lost.
Here is an example to run in a clean R session:
library(Rcpp)
cppFunction(
code = '
Environment f() {
Environment env = Function("new.env")();
env["A"] = "a";
env["B"] = "b";
env["C"] = "c";
env["FOO"] = "foo";
return env;
}
'
)
gctorture(TRUE)
e <- f()
gctorture(FALSE)
e$A
e$B
e$C
e$FOOWhen I run this on my Mac, here's what it prints out for the last commands:
> gctorture(TRUE)
> e <- f()
> gctorture(FALSE)
> e$A
[1] "a"
> e$B
<CHARSXP: "B">
> e$C
[1] "c"
> e$FOO
<CHARSXP: "FOO">
Inspecting the objects gives this:
> .Internal(inspect(e$A))
@7fd168ce9c68 16 STRSXP g1c1 [MARK,NAM(2)] (len=1, tl=0)
@7fd168868598 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "a"
> .Internal(inspect(e$B))
@7fd168ce9c98 09 CHARSXP g1c1 [MARK,NAM(2),gp=0x61] [ASCII] [cached] "B"
If I run the code a second time, then the results turn out normal. This is the output from a second run:
> gctorture(TRUE)
> e <- f()
> gctorture(FALSE)
> e$A
[1] "a"
> e$B
[1] "b"
> e$C
[1] "c"
> e$FOO
[1] "foo"
I get the exact same result when I run the same code in the r-base Docker image. To reproduce:
docker run --rm -ti r-base
install.packages('Rcpp')
# Now run the code from above
When I run the same code in a custom build of R-devel with PROTECTCHECK defined, I get something else weird:
....
> gctorture(TRUE)
> e <- f()
> gctorture(FALSE)
> e$A
Error: object 'e' not found
> e$B
Error: object 'e' not found
> e$C
Error: object 'e' not found
> e$FOO
Error: object 'e' not found
e simply never gets assigned.
If the strings get wrapped with CharacterVector(), then the problem doesn't happen. Unlike the code above, this code works fine:
library(Rcpp)
cppFunction(
code = '
Environment f() {
Environment env = Function("new.env")();
env["A"] = CharacterVector("a");
env["B"] = CharacterVector("b");
env["C"] = CharacterVector("c");
env["FOO"] = CharacterVector("foo");
return env;
}
'
)
gctorture(TRUE)
e <- f()
gctorture(FALSE)
e$A
e$B
e$C
e$FOOIn my particular case, the problem happens with httpuv. When I run the PROTECTCHECK build of R, I get this error in some httpuv code when it assigns a string to an environment:
Error: GC encountered a node (0x5611e376c9d0) with type FREESXP (was STRSXP) at memory.c:1696
The code in question looks like this:
env["rook.version"] = "1.1-0"And many other places where a string is assigned results in the same error message. Wrapping all of them in CharacterVector() seems to make the error go away.
If it would help, I can provide the Dockerfile used to create the build of R with PROTECTCHECK defined.
> sessioninfo::session_info()
─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 3.4.2 (2017-09-28)
os macOS High Sierra 10.13.1
system x86_64, darwin15.6.0
ui X11
language (EN)
collate en_US.UTF-8
tz <NA>
date 2017-12-01
─ Packages ───────────────────────────────────────────────────────────────────
package * version date source
clisymbols 1.2.0 2017-05-21 CRAN (R 3.4.0)
Rcpp * 0.12.14 2017-11-23 CRAN (R 3.4.3)
sessioninfo 1.0.0 2017-06-21 CRAN (R 3.4.1)
withr 2.1.0 2017-11-01 CRAN (R 3.4.2)