godot
godot copied to clipboard
Make `push_error` and `push_warning` print name of calling function
Currently, push_error and push_warning give themselve as the calling
function, which is not useful for debugging. I have altered these to use the
C stacktrace to get the name of the function that called them. This saves
having to turn these functions into macros, which would require recompiling
every single piece of code that uses them. I have also set it to, when debug
symbols are available, use them with atos (available on macOS) to find the
exact source file and line being called from. It should be possible to the same
thing on Linux using addr2line, but I don't have a Linux box handy to test
that. I am not sure how you would implement this in Windows.
I have tested this on macOS Sonoma 14.5 (23F79). It should work on any *nix system. I am not sure about Windows.
Fixes #76770
Could you provide screenshots on how this would look now?
Also check out the static check errors.
Also I'm not sure this change makes sense, this method is called from scripting, the GDScript method won't be shown, so please add some screenshots to see what this outputs
We don't want it to print the c++ method that called into scripting IMO
Okay, I have fixed the formatting and code style issues, moved the platform dependent code into relevant subclasses of OS, and fixed it so that it now properly reports the stack trace when called from scripts. This is only implemented for macOS for now as that is the system I have available. The Linux implementation should be similar except that retrieving debug symbols should be done with addr2line instead of atos. I am not sure exactly how to implement this on Windows, so perhaps someone with more knowledge of Windows debugging could contribute that part.
To clarify, there are two cases this fix covers:
push_error/push_warningare called from GDScript code This appears to have been partially implemented in the debugger for runtime code, but still fails for editor code. I have added code to retrieve the script callstack modeled after whatRemoteDebugger::_err_handlerdoes. In order for this to work requires thatDEBUG_ENABLEDbe defined (true by default foreditorandtemplate_debugtargets), and that Godot is run with the--debugflag.push_error/push_warningare called from C++ code This can be from within the Godot engine or from GDExtension/GDNative code. This requires retrieving the C++ callstack. Getting source filenames and line numbers requires that the assembly generating the message was compiled with debug symbols. If debug symbols are not available, it can still usually get the name of the function that produced the message, which is much more useful than what is currently availble.
Current behavior
Runtime GDScript
As I said, this is partially implemented already, but still includes an unhelpful reference to variant_utility.cpp that is now fixed. Here is how it looked with a warning generated from a GDScript file before in debugger:
Editor GDScript
GDScript run in the editor did not properly show where it was called from before, either in the editor logger or to stdout. Here is the view from the editor:
and here is the view from stdout (with Rider):
C++
Here is a warning generated from godot-git-plugin in the editor logger:
and the view from stdout:
Proposed improvements
Runtime GDScript
Editor GDScript
View in editor logger:
View in stdout:
C++
View in editor logger:
View in stdout:
There are I'm sure still ways to make the results look a little better. All of the various logger implementations seem to have different ideas of what the two different string arguments to errfunc are for, which makes it hard to create a unified implementation that gives the relevant information without giving extra irrelevant information. I will happily accept any contributions anyone else wants to make to improve the output formatting.
Would https://github.com/godotengine/godot/pull/91006 be of any use here?
Would #91006 be of any use here?
Yes, that looks like it would do very much the same thing as what I do for GDScript stacktraces. Though theirs is a much more sweeping change, and mine is much more targeted. Mine requires being run in debug mode to get an accurate GDScript backtraces, while theirs completely rewrites GDScript's stack system to be fast enough to run all the time. There are pros and cons to both approaches.
One thing my PR does that theirs doesn't is print the C++ stacktrace, which is still needed if push_warning or push_error are called from C++ code.
Precisely these days I'm trying to hunt down the root trigger of certain operations and the ability to obtain a proper C++ stack trace would come super handy.
Regarding the implementation, I'd just like to point out that the various handle_crash() implementations already contain code for stack trace collection. I'd say this PR would need to refactor those pieces out into individual functions instead of adding its own.
Precisely these days I'm trying to hunt down the root trigger of certain operations and the ability to obtain a proper C++ stack trace would come super handy.
Regarding the implementation, I'd just like to point out that the various
handle_crash()implementations already contain code for stack trace collection. I'd say this PR would need to refactor those pieces out into individual functions instead of adding its own.
@RandomShaper Yes, just looking at the MacOS implementation, there is definitely a lot of overlap in functionality that could be moved into a separate library to save some duplication. If you would like to contribute a refactor to do that, you are more than welcome to. Personally, I am happy with this version and need to move on to other projects.
@RandomShaper Yes, just looking at the MacOS implementation, there is definitely a lot of overlap in functionality that could be moved into a separate library to save some duplication. If you would like to contribute a refactor to do that, you are more than welcome to. Personally, I am happy with this version and need to move on to other projects.
Would it be fine with you that someone (possibly me when I can spend time on this) takes over your PR? That would mean that other contributor would take your changes, apply the refactor and commit them to a new PR superseding this one, crediting both authors (by having separate commits if it makes sense for the repo or using a co-author annotation).
@RandomShaper Yes, just looking at the MacOS implementation, there is definitely a lot of overlap in functionality that could be moved into a separate library to save some duplication. If you would like to contribute a refactor to do that, you are more than welcome to. Personally, I am happy with this version and need to move on to other projects.
Would it be fine with you that someone (possibly me when I can spend time on this) takes over your PR? That would mean that other contributor would take your changes, apply the refactor and commit them to a new PR superseding this one, crediting both authors (by having separate commits if it makes sense for the repo or using a co-author annotation).
Yes, that would be fine. Just give me credit in some way.
This is something I would really like to add to #91006 to make it more complete (my PR fixes a number of issues in GDScript and also makes it work properly outside the debugger, as well as making the log system support it properly too).
The problem is that It's kind of only usable for desktop, afaik on mobile and other platforms there is no implementation to get the C stack.