You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Merge pull request #105801 from dalexeev/gds-update-stack-funcs
GDScript: Update `get_stack()`, `print_stack()`, and `print_debug()`
This commit is contained in:
@@ -84,7 +84,7 @@
|
|||||||
<method name="get_stack">
|
<method name="get_stack">
|
||||||
<return type="Array" />
|
<return type="Array" />
|
||||||
<description>
|
<description>
|
||||||
Returns an array of dictionaries representing the current call stack. See also [method print_stack].
|
Returns an array of dictionaries representing the current call stack.
|
||||||
[codeblock]
|
[codeblock]
|
||||||
func _ready():
|
func _ready():
|
||||||
foo()
|
foo()
|
||||||
@@ -99,8 +99,8 @@
|
|||||||
[codeblock lang=text]
|
[codeblock lang=text]
|
||||||
[{function:bar, line:12, source:res://script.gd}, {function:foo, line:9, source:res://script.gd}, {function:_ready, line:6, source:res://script.gd}]
|
[{function:bar, line:12, source:res://script.gd}, {function:foo, line:9, source:res://script.gd}, {function:_ready, line:6, source:res://script.gd}]
|
||||||
[/codeblock]
|
[/codeblock]
|
||||||
[b]Note:[/b] This function only works if the running instance is connected to a debugging server (i.e. an editor instance). [method get_stack] will not work in projects exported in release mode, or in projects exported in debug mode if not connected to a debugging server.
|
See also [method print_debug], [method print_stack], and [method Engine.capture_script_backtraces].
|
||||||
[b]Note:[/b] Calling this function from a [Thread] is not supported. Doing so will return an empty array.
|
[b]Note:[/b] By default, backtraces are only available in editor builds and debug builds. To enable them for release builds as well, you need to enable [member ProjectSettings.debug/settings/gdscript/always_track_call_stacks].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="inst_to_dict" deprecated="Consider using [method JSON.from_native] or [method Object.get_property_list] instead.">
|
<method name="inst_to_dict" deprecated="Consider using [method JSON.from_native] or [method Object.get_property_list] instead.">
|
||||||
@@ -209,19 +209,20 @@
|
|||||||
Test print
|
Test print
|
||||||
At: res://test.gd:15:_process()
|
At: res://test.gd:15:_process()
|
||||||
[/codeblock]
|
[/codeblock]
|
||||||
[b]Note:[/b] Calling this function from a [Thread] is not supported. Doing so will instead print the thread ID.
|
See also [method print_stack], [method get_stack], and [method Engine.capture_script_backtraces].
|
||||||
|
[b]Note:[/b] By default, backtraces are only available in editor builds and debug builds. To enable them for release builds as well, you need to enable [member ProjectSettings.debug/settings/gdscript/always_track_call_stacks].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="print_stack">
|
<method name="print_stack">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
Prints a stack trace at the current code location. See also [method get_stack].
|
Prints a stack trace at the current code location.
|
||||||
The output in the console may look like the following:
|
The output in the console may look like the following:
|
||||||
[codeblock lang=text]
|
[codeblock lang=text]
|
||||||
Frame 0 - res://test.gd:16 in function '_process'
|
Frame 0 - res://test.gd:16 in function '_process'
|
||||||
[/codeblock]
|
[/codeblock]
|
||||||
[b]Note:[/b] This function only works if the running instance is connected to a debugging server (i.e. an editor instance). [method print_stack] will not work in projects exported in release mode, or in projects exported in debug mode if not connected to a debugging server.
|
See also [method print_debug], [method get_stack], and [method Engine.capture_script_backtraces].
|
||||||
[b]Note:[/b] Calling this function from a [Thread] is not supported. Doing so will instead print the thread ID.
|
[b]Note:[/b] By default, backtraces are only available in editor builds and debug builds. To enable them for release builds as well, you need to enable [member ProjectSettings.debug/settings/gdscript/always_track_call_stacks].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="range" qualifiers="vararg" keywords="seq">
|
<method name="range" qualifiers="vararg" keywords="seq">
|
||||||
|
|||||||
@@ -349,14 +349,10 @@ struct GDScriptUtilityFunctionsDefinitions {
|
|||||||
s += p_args[i]->operator String();
|
s += p_args[i]->operator String();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Thread::get_caller_id() == Thread::get_main_id()) {
|
|
||||||
ScriptLanguage *script = GDScriptLanguage::get_singleton();
|
ScriptLanguage *script = GDScriptLanguage::get_singleton();
|
||||||
if (script->debug_get_stack_level_count() > 0) {
|
if (script->debug_get_stack_level_count() > 0) {
|
||||||
s += "\n At: " + script->debug_get_stack_level_source(0) + ":" + itos(script->debug_get_stack_level_line(0)) + ":" + script->debug_get_stack_level_function(0) + "()";
|
s += "\n At: " + script->debug_get_stack_level_source(0) + ":" + itos(script->debug_get_stack_level_line(0)) + ":" + script->debug_get_stack_level_function(0) + "()";
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
s += "\n At: Cannot retrieve debug info outside the main thread. Thread ID: " + itos(Thread::get_caller_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
print_line(s);
|
print_line(s);
|
||||||
*r_ret = Variant();
|
*r_ret = Variant();
|
||||||
@@ -365,11 +361,6 @@ struct GDScriptUtilityFunctionsDefinitions {
|
|||||||
static inline void print_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
|
static inline void print_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
|
||||||
DEBUG_VALIDATE_ARG_COUNT(0, 0);
|
DEBUG_VALIDATE_ARG_COUNT(0, 0);
|
||||||
|
|
||||||
if (Thread::get_caller_id() != Thread::get_main_id()) {
|
|
||||||
print_line("Cannot retrieve debug info outside the main thread. Thread ID: " + itos(Thread::get_caller_id()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptLanguage *script = GDScriptLanguage::get_singleton();
|
ScriptLanguage *script = GDScriptLanguage::get_singleton();
|
||||||
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
|
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
|
||||||
print_line("Frame " + itos(i) + " - " + script->debug_get_stack_level_source(i) + ":" + itos(script->debug_get_stack_level_line(i)) + " in function '" + script->debug_get_stack_level_function(i) + "'");
|
print_line("Frame " + itos(i) + " - " + script->debug_get_stack_level_source(i) + ":" + itos(script->debug_get_stack_level_line(i)) + " in function '" + script->debug_get_stack_level_function(i) + "'");
|
||||||
@@ -380,11 +371,6 @@ struct GDScriptUtilityFunctionsDefinitions {
|
|||||||
static inline void get_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
|
static inline void get_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
|
||||||
DEBUG_VALIDATE_ARG_COUNT(0, 0);
|
DEBUG_VALIDATE_ARG_COUNT(0, 0);
|
||||||
|
|
||||||
if (Thread::get_caller_id() != Thread::get_main_id()) {
|
|
||||||
*r_ret = TypedArray<Dictionary>();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptLanguage *script = GDScriptLanguage::get_singleton();
|
ScriptLanguage *script = GDScriptLanguage::get_singleton();
|
||||||
TypedArray<Dictionary> ret;
|
TypedArray<Dictionary> ret;
|
||||||
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
|
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ config_version=5
|
|||||||
|
|
||||||
config/name="GDScript Integration Test Suite"
|
config/name="GDScript Integration Test Suite"
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
|
||||||
|
settings/gdscript/always_track_call_stacks=true
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
test_input_action={
|
test_input_action={
|
||||||
|
|||||||
@@ -1,10 +1,28 @@
|
|||||||
|
@warning_ignore_start("unsafe_call_argument")
|
||||||
|
|
||||||
class_name Utils
|
class_name Utils
|
||||||
|
|
||||||
|
|
||||||
# `assert()` is not evaluated in non-debug builds. Do not use `assert()`
|
# `assert()` is not evaluated in non-debug builds. Do not use `assert()`
|
||||||
# for anything other than testing the `assert()` itself.
|
# for anything other than testing the `assert()` itself.
|
||||||
static func check(condition: Variant) -> void:
|
static func check(condition: Variant) -> void:
|
||||||
if not condition:
|
if condition:
|
||||||
printerr("Check failed.")
|
return
|
||||||
|
|
||||||
|
printerr("Check failed. Backtrace (most recent call first):")
|
||||||
|
for stack: ScriptBacktrace in Engine.capture_script_backtraces():
|
||||||
|
if stack.get_language_name() == "GDScript":
|
||||||
|
var dir: String
|
||||||
|
for i: int in stack.get_frame_count():
|
||||||
|
if i == 0:
|
||||||
|
dir = stack.get_frame_file(i).trim_suffix("utils.notest.gd")
|
||||||
|
else:
|
||||||
|
printerr(" %s:%d @ %s()" % [
|
||||||
|
stack.get_frame_file(i).trim_prefix(dir),
|
||||||
|
stack.get_frame_line(i),
|
||||||
|
stack.get_frame_function(i),
|
||||||
|
])
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
static func get_type(property: Dictionary, is_return: bool = false) -> String:
|
static func get_type(property: Dictionary, is_return: bool = false) -> String:
|
||||||
@@ -34,7 +52,11 @@ static func get_type(property: Dictionary, is_return: bool = false) -> String:
|
|||||||
return type_string(property.type)
|
return type_string(property.type)
|
||||||
|
|
||||||
|
|
||||||
static func get_property_signature(property: Dictionary, base: Object = null, is_static: bool = false) -> String:
|
static func get_property_signature(
|
||||||
|
property: Dictionary,
|
||||||
|
base: Object = null,
|
||||||
|
is_static: bool = false,
|
||||||
|
) -> String:
|
||||||
if property.usage & PROPERTY_USAGE_CATEGORY:
|
if property.usage & PROPERTY_USAGE_CATEGORY:
|
||||||
return '@export_category("%s")' % str(property.name).c_escape()
|
return '@export_category("%s")' % str(property.name).c_escape()
|
||||||
if property.usage & PROPERTY_USAGE_GROUP:
|
if property.usage & PROPERTY_USAGE_GROUP:
|
||||||
@@ -88,13 +110,17 @@ static func get_human_readable_hint_string(property: Dictionary) -> String:
|
|||||||
return property.hint_string
|
return property.hint_string
|
||||||
|
|
||||||
|
|
||||||
static func print_property_extended_info(property: Dictionary, base: Object = null, is_static: bool = false) -> void:
|
static func print_property_extended_info(
|
||||||
|
property: Dictionary,
|
||||||
|
base: Object = null,
|
||||||
|
is_static: bool = false,
|
||||||
|
) -> void:
|
||||||
print(get_property_signature(property, base, is_static))
|
print(get_property_signature(property, base, is_static))
|
||||||
print(' hint=%s hint_string="%s" usage=%s class_name=&"%s"' % [
|
print(' hint=%s hint_string="%s" usage=%s class_name=&"%s"' % [
|
||||||
get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"),
|
get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"),
|
||||||
get_human_readable_hint_string(property).c_escape(),
|
get_human_readable_hint_string(property).c_escape(),
|
||||||
get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""),
|
get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""),
|
||||||
property.class_name.c_escape(),
|
str(property.class_name).c_escape(),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +135,7 @@ static func get_method_signature(method: Dictionary, is_signal: bool = false) ->
|
|||||||
var args: Array[Dictionary] = method.args
|
var args: Array[Dictionary] = method.args
|
||||||
var default_args: Array = method.default_args
|
var default_args: Array = method.default_args
|
||||||
var mandatory_argc: int = args.size() - default_args.size()
|
var mandatory_argc: int = args.size() - default_args.size()
|
||||||
for i in args.size():
|
for i: int in args.size():
|
||||||
if i > 0:
|
if i > 0:
|
||||||
result += ", "
|
result += ", "
|
||||||
var arg: Dictionary = args[i]
|
var arg: Dictionary = args[i]
|
||||||
@@ -261,7 +287,7 @@ static func get_property_usage_string(usage: int) -> String:
|
|||||||
result += "PROPERTY_USAGE_DEFAULT|"
|
result += "PROPERTY_USAGE_DEFAULT|"
|
||||||
usage &= ~PROPERTY_USAGE_DEFAULT
|
usage &= ~PROPERTY_USAGE_DEFAULT
|
||||||
|
|
||||||
for flag in FLAGS:
|
for flag: Array in FLAGS:
|
||||||
if usage & flag[0]:
|
if usage & flag[0]:
|
||||||
result += flag[1] + "|"
|
result += flag[1] + "|"
|
||||||
usage &= ~flag[0]
|
usage &= ~flag[0]
|
||||||
|
|||||||
Reference in New Issue
Block a user