【问题标题】:Skip particular method from showing up in stacktrace跳过显示在堆栈跟踪中的特定方法
【发布时间】:2017-04-02 03:15:57
【问题描述】:

我一直在尝试获得一种在移动设备上运行时打印堆栈跟踪的可靠方法。我遇到了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 &lt;ProjectPath&gt;\Test3.cs:line 10。我想跳过它显示在堆栈跟踪中。

 

任何帮助表示赞赏,在此先感谢。如果问题似乎太长,请提出修改建议:)

【问题讨论】:

  • 为什么不希望堆栈跟踪中的Test3.ActionThing(System.Action act) 行?处理 Environment.StackTrace 并删除不需要的行将是一件简单的事情,但不清楚是什么让某些行可以接受而其他行不能接受
  • 该方法的总体思路是通过它路由所有代码,这样如果它抛出错误,我可以在一个地方看到/打印它们。但是,如果调用的方法链太长,并且所有内容都通过该方法进行路由,则该字符串会相当长,并且会使错误不太容易快速理解,以及不必要的堆栈条目
  • 我想你也不想要System.Environment.get_StackTrace()
  • 那也太棒了,但我不介意,因为这将是整个堆栈跟踪中的一次性打印。

标签: c# unity3d stack-trace


【解决方案1】:

最直接的方法是简单地处理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 函数将它们从集合中排除。然后我们将跳过操作的结果转换成带有ToArray的数组。所以relevantStackFrames 是一个堆栈帧字符串数组,不包括你不想要的。

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

记得添加using System.Linq,这样你就可以访问SkipToArray

【讨论】:

  • 我以前用过toarray和string.Join。我还没有使用过Skip,所以我不确定它是如何工作的。但是根据方法名称猜测,它会跳过堆栈跟踪的拆分数组中的第二个元素。这是一个硬编码的值,如果方法链不同,它可能不会一直有效。
  • 我自己也考虑过字符串操作,但我通常不是这种做法的忠实拥护者。如果可行并且没有更好的解决方案,我会接受这个答案。再次感谢
  • 我认为在这种情况下硬编码值不是问题,因为您始终知道要跳过多少帧(错误处理函数和调用堆栈获取器)。但是如果你真的需要,你可以做更复杂的事情,比如过滤掉包含你不感兴趣的函数的堆栈帧。
  • 还有一点很重要:Skip 不会跳过第二个元素,它会跳过两个元素。如果你想跳过第二个元素,你可以替换 Skip(2)Take(1).Skip(1)
  • 我接受这个答案,因为它似乎在某种程度上有效。它删除了第一次出现的 ActionThing 方法,但没有删除第二次。但我会弄清楚的
猜你喜欢
  • 2012-06-19
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
相关资源
最近更新 更多