StackFrame和StackTrace在Unity和C#中的區別

本文經過實際例子來看看StackFrame和StackTrace有什麼區別,分別在.NET和Unity中測試。shell

.NET環境

測試代碼c#

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            MyFunc1();
            MyFunc2();
            Console.ReadKey();
        }

        static void MyFunc1()  { Console.WriteLine(new StackFrame(true)); }
        static void MyFunc2() { Console.WriteLine(new StackTrace(true)); }
    }
}

經過Debug或Release模式生成exe運行而非在IDE下運行,在這兩種模式下有、無pbd文件,輸出結果是一致的,以下所示編輯器

有pdb文件

MyFunc1 at offset 59 in file:line:column E:\Code\csharp_study\ConsoleApplication1\ConsoleApplication1\Program.cs:15:34函數

在 ConsoleApplication1.Program.MyFunc2() 位置 E:\Code\csharp_study\ConsoleApplication1\ConsoleApplication1\Program.cs:行號 16
在 ConsoleApplication1.Program.Main(String[] args) 位置 E:\Code\csharp_study\ConsoleApplication1\ConsoleApplication1\Program.cs:行號 11測試

刪除pdb文件

MyFunc1 at offset 59 in file:line:column :0:0 ui

在 ConsoleApplication1.Program.MyFunc2()
在 ConsoleApplication1.Program.Main(String[] args)this

Unity環境

個人unity版本 unity 2019.3.7 我的版spa

在Unity編輯器下

測試代碼以下:code

void OnClickBtn1()
{
	MyFunc1();
	MyFunc2();
}

void MyFunc1()
{
	Debug.Log(this.name + "click stacktrace:\n" + new StackTrace(true) + "\n");
}

void MyFunc2()
{
	Debug.Log(this.name + "click stackframe:\n" + new StackFrame(true) + "\n");
}

new StackFrame(true)打印的堆棧以下:
Canvasclick stackframe:
MyFunc2 at offset 1 in file:line:column E:\Code\UGUIDemo\Assets\Function\TestLogStackTrace.cs:58:9ip

new StackTrace(true) 打印的堆棧(在上面的基礎上會有更多的Unity底層堆棧)

Canvasclick stacktrace:
at TestLogStackTrace.MyFunc1 () [0x00001] in E:\Code\UGUIDemo\Assets\Function\TestLogStackTrace.cs:53
at TestLogStackTrace.OnClickBtn1 () [0x00001] in E:\Code\UGUIDemo\Assets\Function\TestLogStackTrace.cs:35
.....中間省略一些Unity的調用棧
at UnityEngine.EventSystems.EventSystem.Update () [0x000f9] in D:\Program Files\Unity\Editor\Data\Resources\PackageManager\BuiltInPackages\com.unity.ugui\Runtime\EventSystem\EventSystem.cs:377
UnityEngine.Debug:Log(Object)
ButtonScene:OnClickBtn1() (at Assets/uGUI/Scripts/ButtonScene.cs:40)
UnityEngine.EventSystems.EventSystem:Update() (at D:/Program Files/Unity/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:377)

結論

結合實踐和反編譯mscorlib.dll的代碼來看

StackTrace中有一個StaceFrame列表,包含完整的調用棧,對於第二個函數的完整調用棧以下

new StackTrace(true) = {StackTrace} "   在 ConsoleApplication1.Program.MyFunc2()\r\n   在 ConsoleApplication1.Program.Main(String[] args)\r\n"
 FrameCount = {int} 2
 Static members = {} 
 Non-public members = {} 
  frames = {StackFrame[]} Count = 5
   [0] = {StackFrame} "GetStackFramesInternal at offset 0 in file:line:column <filename unknown>:0:0\r\n"
   [1] = {StackFrame} "CaptureStackTrace at offset 188 in file:line:column <filename unknown>:0:0\r\n"
   [2] = {StackFrame} ".ctor at offset 100 in file:line:column <filename unknown>:0:0\r\n"
   [3] = {StackFrame} "MyFunc2 at offset 27 in file:line:column <filename unknown>:0:0\r\n"
   [4] = {StackFrame} "Main at offset 43 in file:line:column <filename unknown>:0:0\r\n"
  m_iMethodsToSkip = {int} 3
  m_iNumOfFrames = {int} 2

而stackFrame中只有當前函數的這一幀調用者信息

這個結論同時適用於.NET環境和Unity環境中。

目前咱們Unity線上項目設置的堆棧爲Script only

相關文章
相關標籤/搜索