跳过在堆栈跟踪中显示的特定方法

Skip particular method from showing up in stacktrace

我一直在尝试找到一种在移动设备上运行时打印堆栈跟踪的可靠方法。我遇到了 System.Environment.StackTrace

我正在尝试使用 3 类 做一些事情:

public class Test : MonoBehaviour {
    public static void Do() {
        Test3.ActionThing(() => {
            Test2.DoSomethingElse();
        });
    }
}


public class Test2 : MonoBehaviour {
    void Start () {
        Test3.ActionThing(() => {
            Debug.Log("Start execution");
            Test.Do();
        });
    }

    public static void DoSomethingElse(){
        Test3.ActionThing(() => {
            var a = 0;
            a = int.Parse("s1");
        });
    }
}

public class Test3 : MonoBehaviour {
    public static void ActionThing(Action act){
        try{
            if (act != null)
                act();
        }catch(Exception e){
            Debug.LogError("Error occured " + e.Message);
            Debug.LogError("StackTrace was " + Environment.StackTrace);
        }
    }
}

我在抛出错误时得到了这个堆栈跟踪

StackTrace was    at System.Environment.get_StackTrace() in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Environment.cs:line 227
   at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 13
   at Test2.DoSomethingElse() in <ProjectPath>\Test2.cs:line 14
   at Test.<Do>m__0() in <ProjectPath>\Test.cs:line 8
   at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 10
   at Test.Do() in <ProjectPath>\Test.cs:line 7
   at Test2.<Start>m__0() in <ProjectPath>\Test2.cs:line 9
   at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 10
   at Test2.Start() in <ProjectPath>\Test2.cs:line 7
UnityEngine.Debug:LogError(Object)
Test3:ActionThing(Action) (at Assets/Test3.cs:13)
Test2:DoSomethingElse() (at Assets/Test2.cs:14)
Test:<Do>m__0() (at Assets/Test.cs:8)
Test3:ActionThing(Action) (at Assets/Test3.cs:10)
Test:Do() (at Assets/Test.cs:7)
Test2:<Start>m__0() (at Assets/Test2.cs:9)
Test3:ActionThing(Action) (at Assets/Test3.cs:10)
Test2:Start() (at Assets/Test2.cs:7)

显然,因为我希望这是发布版本中的调试,所以它不会显示内部堆栈跟踪,而只会显示消息。

但问题出在堆栈跟踪本身,它甚至打印了方法 at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 10。我想在堆栈跟踪中跳过它。

感谢任何帮助,在此先感谢。如果问题看起来太长,请提出修改建议 :)

最直接的方法是简单地处理 Environment.StackTrace 字符串并清除您不关心的堆栈帧。

 public static void ActionThing(Action act){
    try{
        if (act != null)
            act();
    }catch(Exception e){
        var relevantStackFrames = 
            Environment.StackTrace
                .Split('\n')
                .Skip(2)
                .ToArray();
        var relevantStackTrace = string.Join("\n", relevantStackFrames);
        Debug.LogError("Error occured " + e.Message);
        Debug.LogError("StackTrace was " + relevantStackTrace );
    }
}

我们分配给 relevantStackFrames 的行将堆栈跟踪字符串拆分为一个字符串数组,每个元素都是对应堆栈帧的行。 System.Environment.get_StackTrace()Test3.ActionThing(System.Action act) 的堆栈帧是该数组中的前两个元素,由于您不需要它们,我们使用 linq 的 Skip 函数将它们从集合中排除。然后我们将skip操作的结果转换成一个数组ToArray。所以 relevantStackFrames 是一个堆栈帧字符串数组,不包括你不想要的。

然后我们创建一个名为 relevantStackTrace 的字符串,它将包含整个堆栈跟踪的字符串。我们只是加入 relevantStackTrace 的每个元素,然后将换行符放回 string.Join.

记得添加 using System.Linq 以便您可以访问 SkipToArray