诊断AccessViolationException我有一个在VS2015和.Net 4.5.2在优化的编译的代码
运行当编译和调试未优化运行,那么它的工作原理确定一个大的vb.net 86项目。但是,如果我在优化开启的情况下编译并在Release模式下运行它,那么我会在同一个无害的代码行中得到各种异常。我试图在发布模式下调试它,但是断点是不可靠的。此外,调试它的行为似乎修改了异常。此外,如果我更改代码(例如,将MsgBox放入以显示信息),则问题可能会消失。例如,我将Arraylist更改为List(Of Control),并且问题不再出现在之前的地方,而是现在移到其他地方。
我已收到所有在不同的时间如下: AccessViolationException, 的NullReferenceException(内某处.NET类深) 和FatalExecutionEngineError
在AccessViolationException异常详细信息告诉任何不同之处在于“这是经常的指示其他内存已损坏“。堆栈跟踪没有意义,没有描述它在无效内存地址上的内容。
我也找不到有关编译器中的优化的实际内容的任何有意义的细节 - 一种解决方案可能是关闭优化,但我不明白这样做的好处/负面影响。
优化不可靠吗?如何能够试图确定发生了什么?
我们使用的唯一非托管代码是一些调用来获取与文件扩展相关的图标 - 然后将其克隆到托管对象中,并销毁非托管内存。这是非常标准的,并且从1.1到4.5.2使用了相同的API 10年,而没有发生过这种情况。
我不能创建一个小的项目,再现问题
下面是我们用来提取图标作为它的唯一的潜在原因我现在的代码。它是从别处借来的,我不能确定它是否应该如此好:
Public Class IconExtractor
<Flags()> Private Enum SHGFI
SmallIcon = &H1
LargeIcon = &H0
Icon = &H100
DisplayName = &H200
Typename = &H400
SysIconIndex = &H4000
UseFileAttributes = &H10
End Enum
<StructLayout(LayoutKind.Sequential)>
Private Structure SHFILEINFO
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As Integer
<MarshalAs(UnmanagedType.LPStr, SizeConst:=260)> Public szDisplayName As String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As String
Public Sub New(ByVal B As Boolean)
hIcon = IntPtr.Zero
iIcon = 0
dwAttributes = 0
szDisplayName = vbNullString
szTypeName = vbNullString
End Sub
End Structure
Private Declare Auto Function SHGetFileInfo Lib "shell32" (
ByVal pszPath As String, ByVal dwFileAttributes As Integer,
ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As SHGFI) As Integer
<DllImport("user32.dll", SetLastError:=True)>
Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As Boolean
End Function
Public Shared Sub GetIconsForFile(ByVal rstrFileName As String, ByRef rzSmallIcon As Icon, ByRef rzLargeIcon As Icon)
Dim zFileInfo As New SHFILEINFO(True)
Dim cbSizeInfo As Integer = Marshal.SizeOf(zFileInfo)
Dim flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes Or SHGFI.SmallIcon
SHGetFileInfo(rstrFileName, 256, zFileInfo, cbSizeInfo, flags)
' Use clone so we can destroy immediately
rzSmallIcon = DirectCast(Icon.FromHandle(zFileInfo.hIcon).Clone, Icon)
DestroyIcon(zFileInfo.hIcon)
zFileInfo = New SHFILEINFO(True)
cbSizeInfo = Marshal.SizeOf(zFileInfo)
flags = SHGFI.Icon Or SHGFI.UseFileAttributes Or SHGFI.LargeIcon
SHGetFileInfo(rstrFileName, 256, zFileInfo, cbSizeInfo, flags)
' Use clone so we can destroy immediately
rzLargeIcon = DirectCast(Icon.FromHandle(zFileInfo.hIcon).Clone, Icon)
DestroyIcon(zFileInfo.hIcon)
End Sub
End Class