get_stack
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — get_stack
get_stack
定义
get_stack() 用于获取当前的调用栈信息。调用栈就像是程序的"行动路线图"——它记录了程序从启动到当前这一刻,经过了哪些函数、在哪个文件的哪一行。
想象你在追踪一个快递包裹:从仓库打包 -> 中转站分拣 -> 运输车配送 -> 快递员派送 -> 你收到包裹。调用栈就是这条"追踪链",get_stack() 让你随时查看这条链上的每一站。
在调试时,如果你想知道"这个函数是被谁调用的"、"执行流程是怎么走到这里的",get_stack() 就是你的好帮手。
函数签名
C#
// C# 中使用 System.Diagnostics.StackTrace
var stackTrace = new System.Diagnostics.StackTrace(true);
// 或使用 System.Environment.StackTrace
string trace = System.Environment.StackTrace;GDScript
func get_stack() -> Array[Dictionary]参数说明
无参数。调用时不需要传入任何值。
返回值
Array[Dictionary] —— 返回一个字典数组,每个字典代表调用栈中的一层(一个函数调用)。每个字典包含以下键:
| 键 | 类型 | 说明 |
|---|---|---|
source | String | 脚本文件的路径 |
function | String | 函数名 |
line | int | 代码行号 |
数组中的第一个元素是最近调用的函数,最后一个元素是最外层的入口函数。
代码示例
基础用法:查看调用栈
C#
using Godot;
using System.Diagnostics;
public partial class GetStackExample : Node
{
public override void _Ready()
{
MethodA();
}
private void MethodA()
{
MethodB();
}
private void MethodB()
{
MethodC();
}
private void MethodC()
{
// 打印当前调用栈
var stack = new StackTrace(true);
GD.Print("=== 调用栈 ===");
GD.Print(stack.ToString());
// 运行结果:
// === 调用栈 ===
// at GetStackExample.MethodC() in ...GetStackExample.cs:line XX
// at GetStackExample.MethodB() in ...GetStackExample.cs:line XX
// at GetStackExample.MethodA() in ...GetStackExample.cs:line XX
// at GetStackExample._Ready() in ...GetStackExample.cs:line XX
}
}GDScript
extends Node
func _ready():
method_a()
func method_a():
method_b()
func method_b():
method_c()
func method_c():
# 打印当前调用栈
var stack = get_stack()
print("=== 调用栈 ===")
for frame in stack:
print(" %s:%d in %s" % [frame["source"], frame["line"], frame["function"]])
# 运行结果:
# === 调用栈 ===
# res://get_stack_example.gd:15 in method_c
# res://get_stack_example.gd:11 in method_b
# res://get_stack_example.gd:8 in method_a
# res://get_stack_example.gd:5 in _ready实际场景:调试伤害计算流程
C#
using Godot;
using System.Diagnostics;
public partial class DamageSystem : Node
{
public void ApplyDamage(Node target, int amount)
{
// 如果伤害值异常,打印调用栈辅助排查
if (amount <= 0 || amount > 10000)
{
GD.PrintErr($"异常伤害值: {amount}");
GD.Print("调用来源:");
GD.Print(new StackTrace(true).ToString());
}
// 正常的伤害处理逻辑...
GD.Print($"对 {target.Name} 造成 {amount} 点伤害");
}
}GDScript
extends Node
func apply_damage(target: Node, amount: int) -> void:
# 如果伤害值异常,打印调用栈辅助排查
if amount <= 0 or amount > 10000:
push_error("异常伤害值: %d" % amount)
print("调用来源:")
for frame in get_stack():
print(" %s:%d in %s" % [frame["source"], frame["line"], frame["function"]])
return
# 正常的伤害处理逻辑...
print("对 %s 造成 %d 点伤害" % [target.name, amount])进阶用法:自定义调试追踪工具
C#
using Godot;
using System.Diagnostics;
public static class DebugTracer
{
// 打印简化的调用链(只显示函数名)
public static void PrintCallChain()
{
var stack = new StackTrace(true);
GD.Print("--- 调用链 ---");
for (int i = 0; i < stack.FrameCount && i < 5; i++)
{
var frame = stack.GetFrame(i);
GD.Print($" {i}: {frame.GetMethod().Name}() (行 {frame.GetFileLineNumber()})");
}
}
// 检查某个函数是否在调用链中
public static bool IsCalledFrom(string functionName)
{
var stack = new StackTrace();
for (int i = 0; i < stack.FrameCount; i++)
{
if (stack.GetFrame(i).GetMethod().Name == functionName)
return true;
}
return false;
}
}
public partial class MyNode : Node
{
public override void _Ready()
{
InitializeGame();
}
private void InitializeGame()
{
SetupPlayer();
}
private void SetupPlayer()
{
// 查看调用链
DebugTracer.PrintCallChain();
// 检查是否被特定函数调用
if (DebugTracer.IsCalledFrom("InitializeGame"))
{
GD.Print("确认:是从 InitializeGame 调用来的");
}
}
}GDScript
extends Node
# 打印简化的调用链(只显示函数名)
func print_call_chain() -> void:
var stack = get_stack()
print("--- 调用链 ---")
for i in range(min(stack.size(), 5)):
var frame = stack[i]
print(" %d: %s() (行 %d)" % [i, frame["function"], frame["line"]])
# 检查某个函数是否在调用链中
func is_called_from(function_name: String) -> bool:
for frame in get_stack():
if frame["function"] == function_name:
return true
return false
func _ready():
initialize_game()
func initialize_game():
setup_player()
func setup_player():
# 查看调用链
print_call_chain()
# 运行结果:
# --- 调用链 ---
# 0: setup_player() (行 XX)
# 1: initialize_game() (行 XX)
# 2: _ready() (行 XX)
# 检查是否被特定函数调用
if is_called_from("initialize_game"):
print("确认:是从 initialize_game 调用来的")注意事项
仅 GDScript 支持:
get_stack()是 GDScript 特有的全局函数。C# 中需要使用System.Diagnostics.StackTrace或System.Environment.StackTrace来获取调用栈信息。性能开销:获取调用栈是一个相对昂贵的操作,不要在
_process()等高频调用的函数中频繁使用get_stack()。它主要作为调试工具使用。发布版中的行为:在导出的发布版中,
get_stack()可能返回空数组或信息不完整,因为发布版会移除部分调试信息。它主要在开发调试阶段使用。数组顺序:返回的数组中,索引 0 是最近调用的函数(即调用
get_stack()的那个函数),越往后是越外层的调用者。
