2017-02-13 18 views
0

でAccessViolationException私はVS2015で実行されている大規模なvb.net x86のプロジェクトを持っていると.NET 4.5.2診断、最適化コンパイルされたコード

それをコンパイルして最適化することなく、デバッグで実行された場合、それがOKに動作します。しかし、最適化を有効にしてリリースモードでコンパイルして実行すると、同じ無害なコード行でさまざまな例外が発生します。私はリリースモードでそれをデバッグしようとしましたが、ブレークポイントは信頼できません。また、それをデバッグする行為も例外を修正するようです。また、コードを変更すると(たとえば、MsgBoxを情報を表示するなど)問題が解決されない場合があります。たとえば、私は(制御)リストへのArrayListを変更しないと、それは前にやったが、現在は別の場所に移動するという問題はもはや発生しました。

私は異なる時間に、以下のすべて受け取った

:AccessViolationExceptionで AccessViolationException、 とNullReferenceException(どこか深い.NETクラス内) とFatalExecutionEngineError

例外の詳細は、これがしばしばある」ことを除いては何も伝えていないが他のメモリが壊れていることを示す "。スタックトレースは無意味であり、無効なメモリアドレスであったと考えられていることの記述はありません。

私はまた、コンパイラに何の最適化についての意味の詳細を見つけることができません実際にはない - 一つの解決策は、最適化をオフにするかもしれないが、私は利益/マイナスの影響がこれを行うのが何であるかを理解していません。

は、信頼性のない最適ですか?何が起こっているのか、どうやって試してみることができますか?

我々が使用する唯一のアンマネージコードは、ファイル拡張子に関連するアイコンを取得するためにいくつかの呼び出しである - そして、管理対象オブジェクトにクローニングし、アンマネージメモリが破壊されています。これはかなり標準的なものであり、同じAPIが1.1から4.5.2まで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 

答えて

0

私は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 

は、私はここで全体のリファクタリング、コードを再現します
関連する問題