System.AccessViolation 异常和堆块在 PInvoke 期间修改了过去请求的大小
当尝试从托管代码 PInvoke 本机调用时,我遇到 System.AccessViolation Exception 和堆块修改了过去请求的大小。本机代码是 COBOL win32 dll。该问题仅存在于 .NET 4.0 中,在 3.5 中不是问题。
以下是 PInvoke 的 VB 代码
Declare Ansi Function RunNAS2008 Lib "NAS.DLL" Alias _
"NAS2008" (ByVal f As String, ByVal fExt As String, _
ByVal wa As String, ByVal go As String, _
ByVal c As String, ByVal cExt As String) As Integer`
fExt
、wa
和 cEXT
由本机代码更新。
字符串是固定长度的,并且根据 3.5 编译时相同的代码不会引发异常。
这是生成的 IL 代码
[DllImport("NAS.DLL", CharSet = CharSet.Ansi, EntryPoint = "NAS2008", ExactSpelling = true, SetLastError = true)]
public static extern int RunNAS2008([MarshalAs(UnmanagedType.VBByRefStr)] ref string f, [MarshalAs(UnmanagedType.VBByRefStr)] ref string fExt, [MarshalAs(UnmanagedType.VBByRefStr)] ref string wa, [MarshalAs(UnmanagedType.VBByRefStr)] ref string go, [MarshalAs(UnmanagedType.VBByRefStr)] ref string c, [MarshalAs(UnmanagedType.VBByRefStr)] ref string cExt);
这是异常
HEAP[NAtest.exe]: Heap block at 006FF6E0 modified at 00700241 past requested size of b59
(1be4.d20): Break instruction exception - code 80000003 (first chance)
eax=006ff6e0 ebx=00700241 ecx=77a9a798 edx=001be20d esi=006ff6e0 edi=00000b59
eip=77af0474 esp=001be454 ebp=001be454 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
ntdll!RtlpBreakPointHeap+0x23:
以及托管调用堆栈
001be64c 77af0474 [InlinedCallFrame: 001be64c] Microsoft.Win32.Win32Native.CoTaskMemFree(IntPtr)
001be648 5b4e230b System.StubHelpers.VBByValStrMarshaler.ClearNative(IntPtr)*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\0b6fafc69f01aa1a982b7f0bc40d48f0\mscorlib.ni.dll
001be688 004a0d47 DomainBoundILStubClass.IL_STUB_PInvoke(System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef)
001be690 004a0ab7 [InlinedCallFrame: 001be690] NAtest.Form1.RunNAS2008(System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef)
001be738 004a0ab7 NAtest.Form1.Button1_Click(System.Object, System.EventArgs)*** WARNING: Unable to verify checksum for NAtest.exe
001be760 5db34ae8 System.Windows.Forms.Control.OnClick(System.EventArgs)*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Windows.Forms\d5f67a0c3cc91bdf34152fe7f752042c\System.Windows.Forms.ni.dll
001be778 5db370a2 System.Windows.Forms.Button.OnClick(System.EventArgs)
001be790 5e0c6174 System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)
001be7ac 5e0995b5 System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)
001be840 5e45a1bf System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)
001be844 5e4618dd [InlinedCallFrame: 001be844]
001be898 5e4618dd System.Windows.Forms.ButtonBase.WndProc(System.Windows.Forms.Message ByRef)
001be8dc 5db9de00 System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef)
001be8e8 5db870f3 System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
001be8f0 5db87071 System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
001be904 5db86fb6 System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
001bead8 002e0ab8 [InlinedCallFrame: 001bead8]
001bead4 5dba2eec DomainBoundILStubClass.IL_STUB_PInvoke(MSG ByRef)
001bead8 5db971ff [InlinedCallFrame: 001bead8] System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)
001beb1c 5db971ff System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr, Int32, Int32)
001beb20 5db96e2c [InlinedCallFrame: 001beb20]
001bebb8 5db96e2c System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
001bec10 5db96c81 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
001bec40 5e08f3d0 System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext)
001bec4c 6e84c53c Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\Microsoft.VisualBas#\c8cba834d3d1a531d2f00252f4b267cc\Microsoft.VisualBasic.ni.dll
001bec78 6e84c3e8 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
001beca4 6e84cc46 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(System.String[])
001becf0 004a00c5 NAtest.My.MyApplication.Main(System.String[]) [17d14f5c-a337-4978-8281-53493378c1071.vb @ 82]
001bef44 601621bb [GCFrame: 001bef44]
和本机调用堆栈
0:000> k
ChildEBP RetAddr
001be470 77ab29c0 ntdll!RtlpBreakPointHeap+0x23
001be48c 77af14cf ntdll!RtlpValidateHeapEntry+0x16d
001be4d4 77aaab3a ntdll!RtlDebugFreeHeap+0x9a
001be5c8 77a53472 ntdll!RtlpFreeHeap+0x5d
001be5e8 76ec6e6a ntdll!RtlFreeHeap+0x142
001be5fc 76ec6f54 ole32!CRetailMalloc_Free+0x1c
001be60c 60162543 ole32!CoTaskMemFree+0x13
001be63c 5b4e230b clr!PInvokeStackImbalanceHelper+0x22
001be754 5db34ae8 mscorlib_ni+0x85230b
001be770 5db370a2 System_Windows_Forms_ni+0x1c4ae8
001be788 5e0c6174 System_Windows_Forms_ni+0x1c70a2
001be7a4 5e0995b5 System_Windows_Forms_ni+0x756174
001be830 5e45a1bf System_Windows_Forms_ni+0x7295b5
001be890 5e4618dd System_Windows_Forms_ni+0xaea1bf
001be8d4 5db9de00 System_Windows_Forms_ni+0xaf18dd
001be8e0 5db870f3 System_Windows_Forms_ni+0x22de00
001be8e8 5db87071 System_Windows_Forms_ni+0x2170f3
001be8fc 5db86fb6 System_Windows_Forms_ni+0x217071
001be984 75bd62fa System_Windows_Forms_ni+0x216fb6
001be9b0 75bd6d3a USER32!InternalCallWinProc+0x23
我已启用 PInvokeStackInbalanceMDA 来调试问题。
IMO 这是由 IL Stubs 生成的 System.StubHelpers.VBByValStrMarshaler::ClearNative(native int) 指令引起的
这里生成了 ILStubs,特别是对清除本机的调用
Cleanup {
/*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.0
/*( 2)*/ ble IL_012f
/*( 0)*/ ldloc.2
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_012f: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.1
/*( 2)*/ ble IL_013d
/*( 0)*/ ldloc.s 0x5
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_013d: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.2
/*( 2)*/ ble IL_014b
/*( 0)*/ ldloc.s 0x8
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_014b: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.3
/*( 2)*/ ble IL_0159
/*( 0)*/ ldloc.s 0xb
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_0159: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.4
/*( 2)*/ ble IL_0167
/*( 0)*/ ldloc.s 0xe
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_0167: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.5
/*( 2)*/ ble IL_0175
/*( 0)*/ ldloc.s 0x11
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_0175: /*( 0)*/ endfinally
// } Cleanup
任何帮助将不胜感激。
I am running into System.AccessViolation Exception and Heap block modified past requested size when trying to PInvoke a native call from managed code. The native code is COBOL win32 dll. The issue is only in .NET 4.0 and it isn't an issue in 3.5.
Here is the VB code for PInvoke
Declare Ansi Function RunNAS2008 Lib "NAS.DLL" Alias _
"NAS2008" (ByVal f As String, ByVal fExt As String, _
ByVal wa As String, ByVal go As String, _
ByVal c As String, ByVal cExt As String) As Integer`
The fExt
, wa
and cEXT
are updated by the native code.
The strings are fixed length and same code when complied against 3.5 doesn't throw exception.
Here is the generated IL Code
[DllImport("NAS.DLL", CharSet = CharSet.Ansi, EntryPoint = "NAS2008", ExactSpelling = true, SetLastError = true)]
public static extern int RunNAS2008([MarshalAs(UnmanagedType.VBByRefStr)] ref string f, [MarshalAs(UnmanagedType.VBByRefStr)] ref string fExt, [MarshalAs(UnmanagedType.VBByRefStr)] ref string wa, [MarshalAs(UnmanagedType.VBByRefStr)] ref string go, [MarshalAs(UnmanagedType.VBByRefStr)] ref string c, [MarshalAs(UnmanagedType.VBByRefStr)] ref string cExt);
Here is the exception
HEAP[NAtest.exe]: Heap block at 006FF6E0 modified at 00700241 past requested size of b59
(1be4.d20): Break instruction exception - code 80000003 (first chance)
eax=006ff6e0 ebx=00700241 ecx=77a9a798 edx=001be20d esi=006ff6e0 edi=00000b59
eip=77af0474 esp=001be454 ebp=001be454 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
ntdll!RtlpBreakPointHeap+0x23:
And the managed call-stack
001be64c 77af0474 [InlinedCallFrame: 001be64c] Microsoft.Win32.Win32Native.CoTaskMemFree(IntPtr)
001be648 5b4e230b System.StubHelpers.VBByValStrMarshaler.ClearNative(IntPtr)*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\0b6fafc69f01aa1a982b7f0bc40d48f0\mscorlib.ni.dll
001be688 004a0d47 DomainBoundILStubClass.IL_STUB_PInvoke(System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef)
001be690 004a0ab7 [InlinedCallFrame: 001be690] NAtest.Form1.RunNAS2008(System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef, System.String ByRef)
001be738 004a0ab7 NAtest.Form1.Button1_Click(System.Object, System.EventArgs)*** WARNING: Unable to verify checksum for NAtest.exe
001be760 5db34ae8 System.Windows.Forms.Control.OnClick(System.EventArgs)*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Windows.Forms\d5f67a0c3cc91bdf34152fe7f752042c\System.Windows.Forms.ni.dll
001be778 5db370a2 System.Windows.Forms.Button.OnClick(System.EventArgs)
001be790 5e0c6174 System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)
001be7ac 5e0995b5 System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)
001be840 5e45a1bf System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)
001be844 5e4618dd [InlinedCallFrame: 001be844]
001be898 5e4618dd System.Windows.Forms.ButtonBase.WndProc(System.Windows.Forms.Message ByRef)
001be8dc 5db9de00 System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef)
001be8e8 5db870f3 System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
001be8f0 5db87071 System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
001be904 5db86fb6 System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
001bead8 002e0ab8 [InlinedCallFrame: 001bead8]
001bead4 5dba2eec DomainBoundILStubClass.IL_STUB_PInvoke(MSG ByRef)
001bead8 5db971ff [InlinedCallFrame: 001bead8] System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)
001beb1c 5db971ff System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr, Int32, Int32)
001beb20 5db96e2c [InlinedCallFrame: 001beb20]
001bebb8 5db96e2c System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
001bec10 5db96c81 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
001bec40 5e08f3d0 System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext)
001bec4c 6e84c53c Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\Microsoft.VisualBas#\c8cba834d3d1a531d2f00252f4b267cc\Microsoft.VisualBasic.ni.dll
001bec78 6e84c3e8 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
001beca4 6e84cc46 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(System.String[])
001becf0 004a00c5 NAtest.My.MyApplication.Main(System.String[]) [17d14f5c-a337-4978-8281-53493378c1071.vb @ 82]
001bef44 601621bb [GCFrame: 001bef44]
And native call-stack
0:000> k
ChildEBP RetAddr
001be470 77ab29c0 ntdll!RtlpBreakPointHeap+0x23
001be48c 77af14cf ntdll!RtlpValidateHeapEntry+0x16d
001be4d4 77aaab3a ntdll!RtlDebugFreeHeap+0x9a
001be5c8 77a53472 ntdll!RtlpFreeHeap+0x5d
001be5e8 76ec6e6a ntdll!RtlFreeHeap+0x142
001be5fc 76ec6f54 ole32!CRetailMalloc_Free+0x1c
001be60c 60162543 ole32!CoTaskMemFree+0x13
001be63c 5b4e230b clr!PInvokeStackImbalanceHelper+0x22
001be754 5db34ae8 mscorlib_ni+0x85230b
001be770 5db370a2 System_Windows_Forms_ni+0x1c4ae8
001be788 5e0c6174 System_Windows_Forms_ni+0x1c70a2
001be7a4 5e0995b5 System_Windows_Forms_ni+0x756174
001be830 5e45a1bf System_Windows_Forms_ni+0x7295b5
001be890 5e4618dd System_Windows_Forms_ni+0xaea1bf
001be8d4 5db9de00 System_Windows_Forms_ni+0xaf18dd
001be8e0 5db870f3 System_Windows_Forms_ni+0x22de00
001be8e8 5db87071 System_Windows_Forms_ni+0x2170f3
001be8fc 5db86fb6 System_Windows_Forms_ni+0x217071
001be984 75bd62fa System_Windows_Forms_ni+0x216fb6
001be9b0 75bd6d3a USER32!InternalCallWinProc+0x23
I have enabled PInvokeStackInbalanceMDA to debug the issue.
IMO this is caused by System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
instruction generated by IL Stubs
Here are generated ILStubs especially the call to clear native
Cleanup {
/*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.0
/*( 2)*/ ble IL_012f
/*( 0)*/ ldloc.2
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_012f: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.1
/*( 2)*/ ble IL_013d
/*( 0)*/ ldloc.s 0x5
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_013d: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.2
/*( 2)*/ ble IL_014b
/*( 0)*/ ldloc.s 0x8
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_014b: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.3
/*( 2)*/ ble IL_0159
/*( 0)*/ ldloc.s 0xb
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_0159: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.4
/*( 2)*/ ble IL_0167
/*( 0)*/ ldloc.s 0xe
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_0167: /*( 0)*/ ldloc.0
/*( 1)*/ ldc.i4.5
/*( 2)*/ ble IL_0175
/*( 0)*/ ldloc.s 0x11
/*( 1)*/ call void [mscorlib] System.StubHelpers.VBByValStrMarshaler::ClearNative(native int)
IL_0175: /*( 0)*/ endfinally
// } Cleanup
Any help would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论