Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 夏普邮政';s OneExceptionSpect正在损坏堆栈跟踪行号_C#_Exception Handling_Postsharp - Fatal编程技术网

C# 夏普邮政';s OneExceptionSpect正在损坏堆栈跟踪行号

C# 夏普邮政';s OneExceptionSpect正在损坏堆栈跟踪行号,c#,exception-handling,postsharp,C#,Exception Handling,Postsharp,我们将PostSharp应用于项目的每个方法,这些方法会破坏堆栈跟踪中报告的行号:内部堆栈帧行号不再指向发生异常的行,而是指向发生异常的方法的右括号 这似乎是Windows的一个已知限制,当重新引发异常时,会重置堆栈跟踪原点(请参阅) 您可以使用此代码重现此问题(需要安装): 命名空间控制台应用程序1 { 使用制度; 使用PostSharp.Aspects; 公共静态类程序 { 公共静态void Main() { 尝试 { 富(2),; } 捕获(异常) { var type=exception

我们将PostSharp应用于项目的每个方法,这些方法会破坏堆栈跟踪中报告的行号:内部堆栈帧行号不再指向发生异常的行,而是指向发生异常的方法的右括号

这似乎是Windows的一个已知限制,当重新引发异常时,会重置堆栈跟踪原点(请参阅)

您可以使用此代码重现此问题(需要安装):

命名空间控制台应用程序1
{
使用制度;
使用PostSharp.Aspects;
公共静态类程序
{
公共静态void Main()
{
尝试
{
富(2),;
}
捕获(异常)
{
var type=exception.GetType();
Console.Write(type.FullName);
控制台。写(“-”;
Console.WriteLine(异常消息);
Console.WriteLine(exception.StackTrace);
}
}
私有静态void Foo(int值)
{
如果(值%2==0)
{
抛出新异常(“无效值”);
}
WriteLine(“你好,世界”);
}
}
[可序列化]
公共类LogExceptionSpect:OneExceptionSpect
{
public override void OneException(MethodExecutionArgs MethodExecutionArgs)
{
}
}
}
执行此代码将提供以下堆栈跟踪:

System.Exception-无效值。
在…\Program.cs:第36行中的ConsoleApplication1.Program.Foo(Int32值)处
在…\Program.cs:第15行中的ConsoleApplication1.Program.Main()处
第36行不是
抛出新异常(“无效值”)
但是
私有静态void Foo(int值)
的右大括号

解决方案是将异常包装成新的异常,并在OneExceptionSpect的OneException方法中重新调用它:

[程序集:控制台应用程序1.LogExceptionAspect]
命名空间控制台应用程序1
{
使用制度;
使用PostSharp.Aspects;
公共静态类程序
{
公共静态void Main()
{
尝试
{
富(2),;
}
捕获(异常)
{
while(异常!=null)
{
var type=exception.GetType();
Console.Write(type.FullName);
控制台。写(“-”;
Console.WriteLine(异常消息);
Console.WriteLine(exception.StackTrace);
exception=exception.InnerException;
}
}
}
私有静态void Foo(int值)
{
如果(值%2==0)
{
抛出新异常(“无效值”);
}
WriteLine(“你好,世界”);
}
}
[可序列化]
公共类LogExceptionSpect:OneExceptionSpect
{
public override void OneException(MethodExecutionArgs MethodExecutionArgs)
{
抛出新异常(“Foo”,methodExecutionArgs.Exception);
}
}
}
这将给出正确的行号(
抛出新异常(“无效值”);
现在位于第37行):

System.Exception-Foo
在控制台上…\Program.cs:第49行中的Application 1.LogExceptionAspect.OneException(MethodExecutionArgs MethodExecutionArgs)中
在…\Program.cs:第41行中的ConsoleApplication1.Program.Foo(Int32值)处
在…\Program.cs:第15行中的ConsoleApplication1.Program.Main()处
System.Exception-无效值。
在…\Program.cs:第37行中的ConsoleApplication1.Program.Foo(Int32值)处
然而,这个解决方案将垃圾添加到堆栈跟踪中(System.Exception-Foo条目不应该真的存在),对我们来说,这使它们几乎毫无用处(请记住,方面应用于我们项目中的每个方法:因此,如果一个异常冒泡出二十个方法,我们将有二十个新的嵌套异常添加到堆栈跟踪中)


考虑到我们不能-cough PHB cough-摆脱方面,我们必须有正确的行号和可读的堆栈跟踪吗?

我是PostSharp的开发人员之一。这是一个已知的问题(或者更确切地说是一个功能)CLR的
rethrow
指令。为简洁起见,它会根据该指令的序列点更改堆栈跟踪。如果在catch语句中使用
throw;
,也会发生同样的情况,但当您看到导致堆栈跟踪的语句时,这一点就更加明显了


我们正在进行一项重大更改,该更改将提供此行为的修复,并有望在将来的版本中发布(目前我无法确定是哪个版本)。恐怕在发布之前,您正在使用的解决方案(或类似的解决方案)是唯一可能的解决方案。

我是PostSharp的开发人员之一。这是一个已知的问题(或者更确切地说是一个功能)CLR的
rethrow
指令。为简洁起见,它会根据该指令的序列点更改堆栈跟踪。如果在catch语句中使用
throw;
,也会发生同样的情况,但当您看到导致堆栈跟踪的语句时,这一点就更加明显了

我们正在进行一项重大更改,该更改将提供此行为的修复,并有望在将来的版本中发布(目前我不知道是哪个版本)。恐怕在发布之前,您正在使用的解决方案(或类似的解决方案)是唯一可能的解决方案。

As and,由于“功能”对于CLR,当重新触发在同一方法中引发的异常时,无法保留原始堆栈跟踪

下面的示例演示了如何通过将原始异常包装到第一个堆栈帧(如图所示)中来实现变通方法