gpt4 book ai didi

vb.net - 在优化的编译代码中诊断 AccessViolationException

转载 作者:行者123 更新时间:2023-12-03 15:58:41 25 4
gpt4 key购买 nike

我有一个在 VS2015 和 .Net 4.5.2 中运行的大型 vb.net x86 项目

当它在没有优化的情况下编译并在调试中运行时,它可以正常工作。但是,如果我在 Release模式下编译并运行它并启用优化,那么我会在同一行无害的代码中得到各种异常。我曾尝试在 Release模式下对其进行调试,但断点不可靠。调试的行为也似乎修改了异常。此外,如果我更改代码(例如将 MsgBox 放入以显示信息),那么问题就会消失。例如,我将一个 Arraylist 更改为一个 List(Of Control),问题不再发生在它以前发生的地方,但现在转移到了其他地方。

我在不同的时间收到了以下所有信息:
AccessViolationException,
NullReferenceException(在 .Net 类的深处)
和 FatalExecutionEngineError

AccessViolationException 中的异常详细信息除了“这通常表明其他内存已损坏”之外什么也没有说明。堆栈跟踪毫无意义,并且没有描述它认为无效内存地址的内容。

我也找不到任何有意义的细节来说明编译器中的优化实际上做了什么——一种解决方案可能是关闭优化,但我不明白这样做的好处/负面影响是什么。

优化不可靠吗?一个人怎么可能试图确定正在发生的事情呢?

我们使用的唯一非托管代码是一些调用来获取与文件扩展名相关的图标 - 然后将其克隆到托管对象中并销毁非托管内存。这是相当标准的,从 1.1 到 4.5.2 已经使用了 10 年相同的 API,之前没有发生过这种情况。

我无法创建一个重现该问题的小项目

这是我们用于提取图标的代码,因为这是我现在唯一的潜在原因。它是从其他地方借来的,我真的不知道它是否像它应该的那样好:

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

最佳答案

我偶然发现了这个解决方案。

我正在阅读 SHGETFILEINFO 的文档
https://msdn.microsoft.com/en-us/library/windows/desktop/bb762179(v=vs.85).aspx
发现备注里写着:你应该从后台线程调用这个函数。不这样做可能会导致 UI 停止响应

不清楚为什么您应该从后台线程调用它,也不清楚“停止响应”实际上可能表现为什么。

然而,这似乎很可能是导致问题的原因,因此我重构以在单独的线程下执行 api 调用。这似乎确实有效。网上很多 SHGETFILEINFO 的例子似乎都没有考虑单独线程的要求。

我在这里重现了整个重构的代码:

Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Threading

''' <summary>
''' Retrieves the small and large icons registered for a filename based on the file's extension
''' </summary>
Public Class FileIcons

Private mFileName As String
Private mSmallIconHandle As IntPtr
Private mSmallIcon As Icon
Private mLargeIconHandle As IntPtr
Private mLargeIcon As Icon

Public Sub New(ByVal rFileName As String)
mFileName = rFileName

Dim t As New Thread(AddressOf GetIconsForFile)
t.SetApartmentState(ApartmentState.STA)
t.Start()
t.Join()

' Use clone so we can destroy immediately
mSmallIcon = DirectCast(Icon.FromHandle(mSmallIconHandle).Clone, Icon)
DestroyIcon(mSmallIconHandle)

' Use clone so we can destroy immediately
mLargeIcon = DirectCast(Icon.FromHandle(mLargeIconHandle).Clone, Icon)
DestroyIcon(mLargeIconHandle)
End Sub

Public ReadOnly Property SmallIcon As Icon
Get
Return mSmallIcon
End Get
End Property

Public ReadOnly Property LargeIcon As Icon
Get
Return mLargeIcon
End Get
End Property

Private Sub GetIconsForFile()
' Go and extract the small and large icons
' Full filename must be < MAX_PATH - which is 260 chars in .Net (apparently) though a file path/length of 256 also causes an error.
' Otherwise SHGetFileInfo gets nothing, Icon.FromHandle then gives "System.ArgumentException: The Win32 handle you passed to Icon is invalid or of the wrong type."
' This needs to be stopped in the calling code, or the resulting error trapped

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(mFileName, 256, zFileInfo, cbSizeInfo, flags)
mSmallIconHandle = zFileInfo.hIcon

zFileInfo = New SHFILEINFO(True)
cbSizeInfo = Marshal.SizeOf(zFileInfo)
flags = SHGFI.Icon Or SHGFI.UseFileAttributes Or SHGFI.LargeIcon
SHGetFileInfo(mFileName, 256, zFileInfo, cbSizeInfo, flags)
mLargeIconHandle = zFileInfo.hIcon
End Sub

#Region "WinAPI"
<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
#End Region

End Class

关于vb.net - 在优化的编译代码中诊断 AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42209881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com