I got a strange problem. I have this code (simplified, the Graph represented by graph_tool is a control flow graph):
class CFG(graph_tool.Graph):
def get_function_bbs(self, function):
print(self.vertex(function))
for edge in self.vertex(function).out_edges():
print(edge.__dict__)
print(edge)
if self.ep.type[edge] == CFType.f2b:
yield edge.target()
Calling the function `get_function_bbs` now leads to a `ValueError: invalid edge descriptor`. The stack trace says the `print(edge)` instruction is responsible for the error:
File "/.../graph.py", line 93, in get_function_bbs
print(edge)
ValueError: invalid edge descriptor
In my tests the function is called many times. This is the output (--- indicates a new call of get_function_bbs)
```
> My question: How can I debug this and find out, why it is invalid? Can I do/print anything in Python? Should I use GDB? Where would be a good place to set a breakpoint?
>
> I cannot print the faulty edge. It is fairly complicate to make an minimal example. My whole code uses no remove_edge() or remove_vertex(). I'm using graph_tool 2.43.
What you should do is produce a minimal example that shows the
problem... No debugger is going to replace this simple strategy.
The function is not new. It has worked for some time now. I'm pretty sure, that this exact graph produces the problem.
So to make a minimal example, it would help to understand the problem first.
From the code fragment that you have shown, it's not possible to say much.
I notice that you are subclassing Graph, and probably omitting to us
specializations that you are making to Graph.vertex() and other methods.
There are no specializations of any graph-tool function in the subclass. It only exists to provide additional specialized functions.
Has the Python wrapper object that boost creates some special data fields that I could print? I'm compiling graph-tool on my own, anyway. Can I add some prints at the place in the graph-tool sourcecode where the "invalid edge descriptor" is generated?
I have found my error. The function `get_function_bbs` actually is a generator and thus leaving the out_edges() iterator intact.
In the code which calls `get_function_bbs`, however, some additional edges are created for this exact node (`function`) which probably destroys the iterator.
Storing the generator output in memory first fixes the problem.