-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
C#: Improve GD.PushError
and GD.PushWarning
#79280
C#: Improve GD.PushError
and GD.PushWarning
#79280
Conversation
1e8fe72
to
962c4f6
Compare
Removed the |
a495223
to
ce4aa8b
Compare
- Use the name, file path and line number of the caller that invokes `GD.PushError` and `GD.PushWarning` instead of the location in the C++ `runtime_interop.cpp` file. - Improvements to getting the C# stack trace. - Use C# type keywords for built-in types in method declarations. - Remove extra space before each parameter in method declarations. - Skip one more frame to avoid `NativeInterop.NativeFuncs`. - Skip methods annotated with the `[StackTraceHidden]` attribute. - Improvements to `ScriptEditorDebugger` when source is in project. - Avoid overriding error metadata when the source is inside the project file. - Use the source function in the title when the source is inside the project file. Users that use these methods would expect the reported location printed by these methods to correspond to a location in their project source files. Specifically, they'd expect to see the file path and line number at which they call these methods, and not the location of the C++ code (which is always the same). Now, these methods are a lot more useful since users can know which line in their source code printed the error/warning.
ce4aa8b
to
13ab2b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the a stack from is from source generated code attempting to open its source will fail because the source doesn't exist:
ERROR: Cannot open file 'C:/dir/Net7/Godot.SourceGenerators/Godot.SourceGenerators.ScriptMethodsGenerator/Test_Node_ScriptMethods.generated.cs'.
at: (modules\mono\utils\string_utils.cpp:152)
ERROR: Failed to read file: 'C:/dir/Net7/Godot.SourceGenerators/Godot.SourceGenerators.ScriptMethodsGenerator/Test_Node_ScriptMethods.generated.cs'.
at: (modules\mono\csharp_script.cpp:2754)
ERROR: Cannot load C# script file 'C:/dir/Net7/Godot.SourceGenerators/Godot.SourceGenerators.ScriptMethodsGenerator/Test_Node_ScriptMethods.generated.cs'.
at: (modules\mono\csharp_script.cpp:2820)
ERROR: Failed loading resource: C:/dir/Net7/Godot.SourceGenerators/Godot.SourceGenerators.ScriptMethodsGenerator/Test_Node_ScriptMethods.generated.cs. Make sure resources have been imported by opening the project in the editor at least once.
at: (C:\dir\godot_4.0.1\core/io/resource_loader.cpp:274)
(Same probably happens for libraries where the sources are not available, but paths are embedded in the pdb)
Can we pretend that we don't know about the source file if it doesn't exist and avoid these errors?
Also If you open a frame from a file that does exist but is not part of the project, the editor tries to convince you to save it as part of the project, if you save any script.
Also about the formatting of method signatures: if we want to format them in C# style, reference parameters are formatted as Type&
instead of ref Type
and inner types as Outer+Inner
instead of Outer.Inner
internal static unsafe StackFrame? GetCurrentStackFrame(int skipFrames = 0) | ||
{ | ||
// We skip 2 frames: | ||
// The first skipped frame is the current method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this always reliably work or can inlining mean that these frames can potentially not exist? (Idk if such frames are available in C#)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a really good point, I don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still a concern or is this not a problem since it's only going to execute in Debug builds which hopefully disable inlining optimizations?
There is a check to avoid the source function if it's not part of the project. It only checks the path, is that check not enough?
That sounds reasonable, I'm a little worried about how this would affect the script debugger since I think it assumes the entire stack trace contains methods defined in the user project. Maybe we should filter everything that is not part of the user project from the stack trace, but that feels wrong since it may be useful information. |
What check do you mean? godot/core/io/resource_loader.cpp Lines 276 to 279 in 202e4b2
Could only trigger if the previous errors didn't happen. I would add a single error to this function: (tho I suppose we could do that in a different PR as well) godot/editor/debugger/editor_debugger_node.cpp Lines 142 to 145 in 202e4b2
|
This one:
godot/editor/debugger/script_editor_debugger.cpp Lines 608 to 611 in 13ab2b6
The metadata is then used to determine which file to open: godot/editor/debugger/script_editor_debugger.cpp Lines 1486 to 1491 in 13ab2b6
I'd prefer to do it in a different PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs #79342 to work correctly on windows, but is still a significant improvement without.
Thanks! |
GD.PushError
andGD.PushWarning
instead of the location in the C++runtime_interop.cpp
file.DeprecateGD.PushError
andGD.PushWarning
overloads that take aparams
parameter, since those can't be used with [Caller] attributes and the reported error location will be theGD.cs
file.RemoveGD.PushError
andGD.PushWarning
overloads that take a single string parameter. This breaks compatibility but otherwise overload resolution will prefer them over the new overloads, which defeats the purpose of this PR.Interestingly, I'm the one that added those overloads as performance optimization in C#: Sync GD with Core #71946.This breaks binary compatibility but not source compatibility, meaning that it only breaks for users that are calling these methods from a library that was built for 4.0 - 4.1. Users calling these methods directly in their game code will be unaffected.NativeInterop.NativeFuncs
.[StackTraceHidden]
attribute.ScriptEditorDebugger
when source is in project.Users that use these methods would expect the reported location printed by these methods to correspond to a location in their project source files. Specifically, they'd expect to see the file path and line number at which they call these methods, and not the location of the C++ code (which is always the same). Now, these methods are a lot more useful since users can know which line in their source code printed the error/warning.