为什么我的堆栈跟踪被截断了

本文关键字:跟踪 我的 堆栈 为什么 | 更新日期: 2023-09-27 18:02:37

我有一个部分信任的AppDomain,我在其中运行一个完全信任的调试窗口。使用PermissionSetAttribute获得权限,我可以创建窗口并使用它做很多事情,但有时在数据绑定期间会抛出SecurityException。

一个容易重复的情况抛出这个:Property accessor 'Namespace' on object 'System.RuntimeType' threw the following exception:'Request failed.'。深入研究这个异常,我可以看到它是在要求完全信任时抛出的。

没问题,调试窗口程序集具有完全信任,我只需要断言它。但是当我查看内部SecurityException的堆栈跟踪时,我看到了这个:

   at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   at System.Security.CodeAccessSecurityEngine.Check(PermissionSet permSet, StackCrawlMark& stackMark)
   at System.Security.PermissionSet.Demand()
   at System.SecurityUtils.DemandGrantSet(Assembly assembly)
   at System.SecurityUtils.DemandReflectionAccess(Type type)
   at System.SecurityUtils.MethodInfoInvoke(MethodInfo method, Object target, Object[] args)
   at System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component)

在这里结束,在ReflectPropertyDescriptor.GetValue

在Visual Studio的调用堆栈窗口中,我可以看到ReflectPropertyDescriptor.GetValue在堆栈的最尖端。这个堆栈一直追溯到调试窗口的创建和我在那里执行的安全断言,这正是我想要的。

为什么堆栈像这样分成两部分?我怎样才能阻止它的发生?

我正在使用。net 4.0安全(即2级)。

为什么我的堆栈跟踪被截断了

这并不奇怪。Visual studio的调用堆栈显示当当前异常被抛出时所处的方法。InnerException显示了发生内部异常异常的调用堆栈。抛出内部异常后,它向上传播调用堆栈,从而展开它,直到到达ReflectPropertyDescriptor.GetValue。此时,它被捕获在catch块中,并被设置为新异常的内部异常,然后抛出并一直向上冒泡。因此,第二个异常的调用堆栈从抛出点(即ReflectPropertyDescriptor.GetValue)开始

下面是一个简单的例子。

namespace Exceptions
{
    class ExceptionTester
    {
        public void Run()
        {
            ThrowSecondException();
        }
        public void DoSomething()
        {
            DoMore();
        }
        public void DoMore()
        {
            ThrowFirstException();
        }
        public void ThrowFirstException()
        {
            throw new FooException();
        }
        public void ThrowSecondException()
        {
            try
            {
                DoSomething();
            }
            catch (FooException e)
            {
                throw new BarException("derp", e);
            }
        }
    }
    class FooException : Exception
    {
    }
    class BarException : Exception
    {
        public BarException(string msg, Exception inner) : base(msg, inner)
        {
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var tester = new ExceptionTester();
            tester.Run();
        }
    }
}

当抛出BarException类型的第二个异常时,您会注意到visual studio将ThrowSecondException置于调用堆栈的顶部,因为这是抛出BarException的地方。但是,当您深入BarException's InnerException并查看FooException's调用堆栈时,它将显示FooException抛出的位置(ThrowFirstException())。