-
-
Notifications
You must be signed in to change notification settings - Fork 203
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
Setting attribute to vertex sequence leads to failed assertion #807
Comments
Introduced in efc8bec. |
This particular commit has been added to trigger the creation of the native igraph object. Maybe we need to be more careful with what we allow as attributes. Do we really need to support vertex/edge sequences as attributes? |
CRAN igraphoptions(conflicts.policy = list(warn = FALSE))
library(igraph)
gg <- make_ring(2, directed = TRUE)
V(gg)$id <- V(gg)
dput(gg)
#> structure(list(2, TRUE, c(0, 1), c(1, 0), c(0, 1), c(1, 0), c(0,
#> 1, 2), c(0, 1, 2), list(c(1, 0, 1), list(name = "Ring graph",
#> mutual = FALSE, circular = TRUE), list(id = structure(1:2, class = "igraph.vs", is_all = TRUE, env = <weak reference>, graph = "17d54ab3-1bea-4723-8d5f-2e86ada40fe5")),
#> list()), <environment>), class = "igraph")
dput(as.list(unclass(gg)[[10]]))
#> list(me = structure(list(2, TRUE, c(0, 1), c(1, 0), c(0, 1),
#> c(1, 0), c(0, 1, 2), c(0, 1, 2), list(c(1, 0, 1), list(name = "Ring graph",
#> mutual = FALSE, circular = TRUE), list(), list()), <environment>), class = "igraph"),
#> myid = "17d54ab3-1bea-4723-8d5f-2e86ada40fe5") Created on 2023-05-21 with reprex v2.0.2 dev igraphoptions(conflicts.policy = list(warn = FALSE))
library(igraph)
gg <- make_ring(2, directed = TRUE)
V(gg)$id <- V(gg)
dput(gg)
#> structure(list(2, TRUE, c(0, 1), c(1, 0), NULL, NULL, NULL, NULL,
#> list(c(1, 0, 1), list(name = "Ring graph", mutual = FALSE,
#> circular = TRUE), list(id = structure(1:2, class = "igraph.vs", is_all = TRUE, env = <weak reference>, graph = "a59b2801-46a9-4a00-a77b-53c364c25ac5")),
#> list()), <environment>), class = "igraph")
dput(as.list(unclass(gg)[[10]]))
#> list(me = structure(list(2, TRUE, c(0, 1), c(1, 0), NULL, NULL,
#> NULL, NULL, list(c(1, 0, 1), list(name = "Ring graph", mutual = FALSE,
#> circular = TRUE), list(), list()), <environment>), class = "igraph"),
#> igraph = <pointer: 0x600000ac81e0>, myid = "a59b2801-46a9-4a00-a77b-53c364c25ac5") Created on 2023-05-21 with reprex v2.0.2 |
This is getting way too complicated. Do we even need to support sequences as vertex/edge attributes? Perhaps it's worth doing a revdepcheck with just that change on top of v1.4.2 . |
Do you have a clear understanding of how that null pointer arises, and if yes, can you please share it? (BTW an ASan-enabled test would make this much clearer as fatal errors cause the printing of a stack trace.) The fix you propose is for the symptom, but it's good to be aware of the underlying cause ... |
Theoretically, there's some benefit, as one might want to maintain a mapping between the vertex (or edges) of two graphs, e.g. after vertex deletion or subsetting. This is a convenient way to do it. Of course, using plain vertex or edge IDs would also achieve the same. |
ASan output:
To get line numbers, the package must be loaded from the dev directory instead of the installed location.
|
As far as I can tell, the |
Some more investigation (adding extra https://github.com/igraph/igraph/blob/release/0.9/src/operators/subgraph.c#L246 Copying the code with context and annotating it: /* Copy the graph attributes */
IGRAPH_CHECK(igraph_i_attribute_copy(res, graph,
/* ga = */ 1, /* va = */ 0, /* ea = */ 0));
// eids_new2old is valid here
/* Copy the vertex attributes */
IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, res,
my_vids_new2old));
// eids_new2old is no longer valid here, eids_new2old.stor_begin is now NULL
/* Copy the edge attributes */
IGRAPH_CHECK(igraph_i_attribute_permute_edges(graph, res, &eids_new2old)); This makes no sense to me, since CC @ntamas |
During the changes of igraph stucture, attributes was not changed and also as I see the vector which is lost pointer allocated just in C, so seems it's really some exception inside of |
Indeed something calls After adding some printfs to
|
Exception is coming from Which also means that |
No, not quite. But I already debugged that far. What is happening is that something triggers a call to Hypothesis: One of the R API calls fails, resulting in a call to Can you substantiate or refute this hypothesis @Antonov548 ? |
To be more specific, this line fails in some way in
What's to be resolved is not quite why it fails (has to do with copying a vertex selector, I guess), but why that failure doesn't result in a return to the top level, and whether anything can be done about that. Or if this is not actually a failure, why does the above quoted line end up calling |
@szhorvat 's hypothesis is a plausible explanation. I don't really know whether the attribute handler implementation in R is rigorously prepared for handling errors, and even if so, how does it handle longjmps and stuff. |
I believe Ideally, the entire loop in |
What kind of performance impact would that have? Note that this function will be invoked during any sort of graph modification or subsetting, so it is performance critical. But what's missing here for me is an understanding of why the finalizer gets invoked here at all. This is a greater problem that can cause problems elsewhere too. |
@Antonov548 @krlmlr If I understood you right, you are saying that this is basically an instance of the last bullet point of #253 (comment), i.e. calling an R/igraph function from C code? In other words, there is no failure, but some part of If so, then the ENTER/EXIT mechanism of igraph 0.10 should be helpful here. It allows inserting checkpoints in the "finally stack" (the stack of destructor calls) so that a single call to Also, if so, then it's entirely reasonable to fix this now by disallowing vertex/edge selectors as attributes (or rather converting to indices, as you did @krlmlr ) |
I have another one theory :) Which seems the most possible for me as I think. So, first of all I know how to fix example which is failing: options(conflicts.policy = list(warn = FALSE))
library(igraph)
gg <- make_ring(3, directed = TRUE)
V(gg)$id <- V(gg)
subgraph(gg, 1)
#> Error in induced_subgraph(graph, vids): At core/core/vector.pmt:483 : Assertion failed: v->stor_begin != NULL. This is an unexpected igraph error; please report this as a bug, along with the steps to reproduce it.
#> Please restart your R session to avoid crashes or other surprising behavior. Need to comment this line. What is problem in this code: And here is the thing: in the enviorement in dev version there is pointer to native stucture and the question is how |
Do we really need that complexity in |
Chipping in as a person who incidentally bumped into that issue... From a user perspective I think the main (only?) concern is whether igraph will allow an arbitrary vector-like object (atomic vector or list with |
@Antonov548: Is this fixed with #813? |
Closed with #808. |
Can you clarify how this leads to the invocation of the finalizer? |
This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary. |
Describe the bug
A specific usage pattern leads to a failed assertion in the C core.
To reproduce
Created on 2023-05-21 with reprex v2.0.2
Version information
The text was updated successfully, but these errors were encountered: