Open AleKoure opened 3 years ago
Hi, I'm also experiencing the problem of R crashing when xml_add_parent
is used in combination with other code. As a minimal example it crashes when the code below is run three times. When I originally found the problem I was only calling xml_add_parent
once in a script with many other function calls. However, I don't know how to create a minimal example for that I'm afraid.
library(xml2)
# Create XML document
doc <- read_xml("<parent><child1>Hello</child1></parent>")
# Check current elements
children <- xml_children(doc)
new_node <- read_xml('<new_node>New text</new_node>')
xml_add_parent(children, new_node)
# Show that the parent node has been added
doc
#> {xml_document}
#> <parent>
#> [1] <new_node>New text<child1>Hello</child1></new_node>
If I run the above in a loop then it causes R to crash e.g.:
library(xml2)
for (i in 1:3){
# Create XML document
doc <- read_xml("<parent><child1>Hello</child1></parent>")
# Check current elements
children <- xml_children(doc)
#expect_equal(xml_text(children), c("Hello"))
new_node <- read_xml('<new_node>New text</new_node>')
xml_add_parent(children, new_node)
doc
}
reprex produces this:
This reprex appears to crash R. See standard output and standard error for more details.
*** caught segfault ***
address 0x5610c8000000, cause 'memory not mapped'
An irrecoverable exception occurred. R is aborting now ...
OR this:
This reprex appears to crash R. See standard output and standard error for more details.
free(): invalid pointer
Thanks to AleKoure for pointing out the workaround and helping me locate which part of my code was crashing my R session.
Created on 2021-06-02 by the reprex package (v2.0.0)
for (i in 1:500){
print(i)
doc <- xml2::read_xml("<a><b>a</b></a>")
children <- xml2::xml_children(doc)
xml2::xml_add_parent(children, xml2::read_xml('<c>d</c>'))
}
On my machine, this one can go to 60 and a segfault is triggered.
The trigger is xml_add_parent
. xml_add_child
and xml_add_sibling
won't trigger the segfault.
Possible solution is adding .copy = TRUE
in xml_replace() makes the function stable for iterations, but I guess this will have some impact on performance.
By developing a plumber API with xml2 I fall into the following error under a small stress test. I reproduce a minimal example in my local machine.
The following code chunk produces an error,
you can bypass it for example by using xml_add_child and xml_replace instead.