Why does stack get truncated in Exception.StackTrace?

前端 未结 4 1188
梦如初夏
梦如初夏 2021-02-05 18:31

Why does the high part of the stack (in Exception.StackTrace) gets truncated? Let\'s see a simple example:

public void ExternalMethod()
{
  InternalMethod();
}         


        
4条回答
  •  遥遥无期
    2021-02-05 19:17

    As csharptest said this is by design. The StackTrace stops at the try block. Further more there is no hook in the framework that is called when an exception is thrown.

    So the best you can do is something along these lines, it its an absolute requirement to get full stack traces (store a full trace on exceptions creation):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.CompilerServices;
    using System.Diagnostics;
    
    namespace ConsoleApplication15 {
    
        [global::System.Serializable]
        public class SuperException : Exception {
    
            private void SaveStack() {
                fullTrace = Environment.StackTrace;
            }
    
            public SuperException() { SaveStack(); }
            public SuperException(string message) : base(message) { SaveStack();  }
            public SuperException(string message, Exception inner) : base(message, inner) { SaveStack(); }
            protected SuperException(
              System.Runtime.Serialization.SerializationInfo info,
              System.Runtime.Serialization.StreamingContext context)
                : base(info, context) { }
    
            private string fullTrace; 
            public override string StackTrace {
                get {
                    return fullTrace;
                }
            }
        }
    
        class Program {
    
            public void ExternalMethod() {
                InternalMethod();
            }
    
            public void InternalMethod() {
                try {
                    ThrowIt();
                } catch (Exception ex) {
                    Console.WriteLine(ex.StackTrace);
                }
            }
    
            [MethodImpl(MethodImplOptions.NoInlining)]
            public void ThrowIt() {
                throw new SuperException();
            }
    
    
            static void Main(string[] args) {
                new Program().ExternalMethod();
                Console.ReadKey();
            }
        }
    }
    

    Outputs:

     
         at System.Environment.get_StackTrace()
       at ConsoleApplication15.SuperException..ctor() in C:\Users\sam\Desktop\Source
    \ConsoleApplication15\ConsoleApplication15\Program.cs:line 17
       at ConsoleApplication15.Program.ThrowIt() in C:\Users\sam\Desktop\Source\Cons
    oleApplication15\ConsoleApplication15\Program.cs:line 49
       at ConsoleApplication15.Program.InternalMethod() in C:\Users\sam\Desktop\Sour
    ce\ConsoleApplication15\ConsoleApplication15\Program.cs:line 41
       at ConsoleApplication15.Program.Main(String[] args) in C:\Users\sam\Desktop\S
    ource\ConsoleApplication15\ConsoleApplication15\Program.cs:line 55
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
    ontextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
    
    

    It is not possible to inject this behaviour into the existing System defined exceptions, but .Net has a rich infrastructure for wrapping exceptions and rethrowing so it should not be a huge deal.

提交回复
热议问题