为什么我的堆栈跟踪被截断了
本文关键字:跟踪 我的 堆栈 为什么 | 更新日期: 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()
)。