laike9m / Cyberbrain

Python debugging, redefined.
http://bit.ly/cyberbrain-features
MIT License
2.51k stars 159 forks source link

Node missing in loops #108

Closed laike9m closed 3 years ago

laike9m commented 3 years ago

Reported by @victorjzsun.

For https://github.com/laike9m/Cyberbrain/blob/master/examples/issue47.py

@trace
def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return b

if __name__ == "__main__":
    fib(3)

nodes on line 8 and 9 disappear when the loop counter is set to 1 or 2:

image

laike9m commented 3 years ago

Like you mentioned, the root cause is this change that modified the updateVisibleEvents method: https://github.com/laike9m/Cyberbrain/commit/f11db4db3f72f312d0c88e43625c0010906e69b0.

To deal with conditionally executed code in loops (See "Test early return from loop" in loop_test.js for an example), we added some heuristics to remove nodes that are not supposed to show up:

Remove nodes that should not appear in the trace graph, if the following two conditions are met:

  • It has a source which is an invisible node
  • It is not a source of any visible node

However these heuristics fail in this case, as the nodes on line 8 and 9 should be displayed. On line 8 it should be like: image

To solve this issue, we basically have two options:

Theoretically, the second solution is more robust, and may solve this and future loop related problems once and for all. But it requires more careful consideration and a much bigger change.

I'll need some time to think about it. What I can do now is adding a test case in loop_test to cover issue47.py

--

Actually, I think there is an easy way to solve it. I'll need to experiment to see if it works. But basically the idea is, instead of picking the nodes to remove, we simply scan through each of the visible nodes (after replacing), and check whether a node falls in the range of [currentIterationStart(), currentIterationEnd()]. If yes, keep it; if not, remove it.