簡體   English   中英

從StackTrace中過濾掉非用戶代碼方法

[英]Filter out non-user code methods from StackTrace

我正在嘗試實現更復雜的錯誤處理。 為了實現我的目標,我需要從curent StackTrace中過濾掉非用戶代碼方法(框架)。

在ASP.NET典型的StackTrace中,您可能會猜到許多方法與調試目的無關,因為它們不在用戶代碼中。 Visual Studio為您提供了篩選出這個非用戶代碼(框架)的選項,因此我猜它是可能的。 然而,在探索StackFrames(以及方法,模塊,程序集......)的方法和屬性大約30分鍾后,我找不到任何可用於識別“系統”框架的東西。

我最終手動指定了我要記錄的模塊(模塊是程序集的一部分,在我的例子中是1:1)。

有沒有更好的方法來做到這一點? 只需包含核心ASP.NET之外的所有內容

如果部署'* .pdb'文件並且只是嘗試從異常中獲取堆棧跟蹤,則可以獲取異常的StackTrace屬性並將其拆分為行並過濾掉沒有源代碼引用的行。

        catch (Exception ex)
        {
            var lines = ex.StackTrace
                .Split(new[] {Environment.NewLine}, StringSplitOptions.None)
                .Where(l => Regex.IsMatch(l, @"([^\)]*\)) in (.*):line (\d)*$"));
            var userStackTrace = string.Join(Environment.NewLine, lines);
        }

StackFrame類具有GetMethod()成員函數,來自檢索到的MethodBase對象。

如果您只需要一個天真的過濾器,您可以執行以下操作之一:

  • 刪除以“System”開頭的類中的每個方法。 或“微軟”。 (因為所有的.NET庫都放在那里)。
  • 找到方法所在的程序集(參見前面),然后檢查AssemblyCompanyAttribute和“Microsoft Corporation”制作的過濾器程序集。 這比以前的方法更好,因為有時候我看到了將自己的類型放在System命名空間中的庫。

如果您需要更多內容,可以獲取定義該方法的模塊( MethodBase.Module )。 現在您有兩個選擇:

  • 如果你所有的組件簽署你能證明與公共密鑰令牌(獲得其中模塊與定義的匯編唯一方法Module.Assembly性質,建設AssemblyName與對象Assembly.FullName然后檢查公鑰AssemblyName.KeyPair財產,它必須與您的公鑰令牌匹配(只需與GetExecutingAssembly()進行比較)。
  • 如果並非所有程序集都已簽名,則可以執行相同的操作,但過濾掉與系統程序集的公鑰標記匹配的所有程序集(這可能是最簡單的情況,也包括第3部分庫)。

請注意,並非所有系統程序集都具有相同的公鑰令牌(即使在相同的Framework版本中),因此您必須收集並檢查鍵列表(只需瀏覽c:\\windows\\assembly以讀取它們)。 一種好的方法是檢查公鑰,然后使用AssemblyCompanyAttribute應用第二個過濾器。

我遇到了同樣的問題,但我使用了NLog和TraceSource,並將System.Net Trace事件重定向到NLog目標。 也就是說,過濾掉系統組件並沒有完全削減它,所以我必須檢查自定義屬性:

    private static bool IsOkay(StackFrame arg)
    {
        var method = arg.GetMethod();
        var methodAttributes = new Attribute[] { }
            .Concat(method.GetCustomAttributes<DebuggerHiddenAttribute>())
            .Concat(method.GetCustomAttributes<CompilerGeneratedAttribute>());

        if (methodAttributes.Any())
            return false;

        var methodDeclearingType = method.DeclaringType;
        var methodDeclearingTypeAttributes = new Attribute[] { }
            .Concat(methodDeclearingType.GetCustomAttributes<CompilerGeneratedAttribute>());

        if (methodDeclearingTypeAttributes.Any())
            return false;

        var methodDeclearingTypeModule = methodDeclearingType.Module;
        var methodDeclearingTypeModuleAttributes = new Attribute[] { }
            .Concat(methodDeclearingTypeModule.GetCustomAttributes<UnverifiableCodeAttribute>());

        if (methodDeclearingTypeModuleAttributes.Any())
            return false;

        return true;
    }

BR,incureforce

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM