godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.1k stars 20.2k forks source link

Continuing execution after an assert is reached does not continue from the assert #34054

Open Zylann opened 4 years ago

Zylann commented 4 years ago

Godot 3.2 beta2

When debugging a game from the editor, if an assert statement is raised, the debugger stops on that line as normal. But if you try to place a breakpoint after the assert and then "Continue", the breakpoint won't be hit. The whole stack is lost. I think it's desirable for the debugger to continue from the assert (in that case it was an infinite loop failsafe, I could have seen what was the execution path taken). I know I could replace it with an if then breakpoint, but that means it's not an assert anymore and I need to repro the bug...

tom-jk commented 4 years ago

Can reproduce in 3.2.beta2 thru 3.2.3.rc3

Clarification, the whole stack (as I understand it) is not lost, only the function with the failed assert.

This code (with breakpoints on the breakpoint1/2/3 lines):

extends Node

func _ready():
    print("    START")
    print(" 1. pre callfunc1")
    callfunc1()
    print("16. post callfunc1")
    print("    END")

func callfunc1():
    print(" 2. |  callfunc1")
    print(" 3. |  pre callfunc2")
    callfunc2()
    print("13. |  post callfunc2")
    print("14. |  breakpoint1")
    print("15. |  end of callfunc1")

func callfunc2():
    print(" 4. |  |  callfunc2")
    print(" 5. |  |  pre callfunc3")
    callfunc3()
    print("10. |  |  post callfunc3")
    print("11. |  |  breakpoint2")
    print("12. |  |  end of callfunc2")

func callfunc3():
    print(" 6. |  |  |  callfunc3")
    assert(false)
    print(" 7. |  |  |  post assert")
    print(" 8. |  |  |  breakpoint3")
    print(" 9. |  |  |  end of callfunc3")

Produces this output:

    START
 1. pre callfunc1
 2. |  callfunc1
 3. |  pre callfunc2
 4. |  |  callfunc2
 5. |  |  pre callfunc3
 6. |  |  |  callfunc3
10. |  |  post callfunc3
11. |  |  breakpoint2
12. |  |  end of callfunc2
13. |  post callfunc2
14. |  breakpoint1
15. |  end of callfunc1
16. post callfunc1
    END

Breakpoint2 and breakpoint1 are successfully hit (the debugger breaks). Points 7, 8, 9 are missed off the end of callfunc3, but everything else carries on working.

Pshy0 commented 8 months ago

Still happens in Godot 4.2.1.

From the documentation:

Asserts that the condition is true. If the condition is false, an error is generated. When running from the editor, the running project will also be paused until you resume it. This can be used as a stronger form of @GlobalScope.push_error() for reporting errors to project developers or add-on users.

So the correct behavior should be equivalent to conditionally running push_error followed by breakpoint. Instead, assert is behaving the way assert usually behave in other programs (aborting execution).