【问题标题】:Random crashes with .NET controls embedded in PowerBuilderPowerBuilder中嵌入的.NET控件随机崩溃
【发布时间】:2014-07-28 21:07:26
【问题描述】:

在我们的 PowerBuilder (12.1 Build 7217) 窗口中添加一些嵌入的 .NET (4.0) 控件作为 OLE 对象后,我们现在在我们的应用程序中遇到随机硬崩溃。 这是一次硬崩溃,因此我们的应用程序中的异常处理不会捕获错误,应用程序只会崩溃。

我们已经能够通过自动化 UI 测试来重现它,它通常发生在打开和关闭同一组三个或四个窗口少于 100 次之后。

我们得到的最常见的错误代码是以下三个:

0xC0000005  EXCEPTION_ACCESS_VIOLATION  The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
0x80000003  EXCEPTION_BREAKPOINT A breakpoint was encountered.
0xc0000409  Unknown software exception (Application Error)

以下是 Windows 事件查看器中的一些示例错误:

Faulting application name: [OUR APP NAME], version: 1.0.0.1, time stamp: 0x512de438
Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0x80000003
Fault offset: 0x048495b4
Faulting process id: 0x2fc
Faulting application start time: 0x01cfa28c02e07932
Faulting application path: C:\Program Files (x86)\..........[our app exe]
Faulting module path: unknown
Report Id: 9c101a2e-0e7f-11e4-815e-0026b9806e38

Faulting application name: [OUR APP NAME], version: 1.0.0.1, time stamp: 0x512de438
Faulting module name: clr.dll, version: 4.0.30319.18444, time stamp: 0x52717e84
Exception code: 0xc0000005
Fault offset: 0x000fe810
Faulting process id: 0x2fc
Faulting application start time: 0x01cfa28c02e07932
Faulting application path: C:\Program Files (x86)\..........[our app exe]
Faulting module path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Report Id: a5b51191-0e7f-11e4-815e-0026b9806e38

Faulting application name: [OUR APP NAME], version: 1.0.0.1, time stamp: 0x512de438
Faulting module name: ntdll.dll, version: 6.1.7601.18229, time stamp: 0x51fb1072
Exception code: 0xc0000029
Fault offset: 0x00090892
Faulting process id: 0x272c
Faulting application start time: 0x01cfa29978c86751
Faulting application path: C:\Program Files (x86)\..........[our app exe]
Faulting module path: C:\WINDOWS\SysWOW64\ntdll.dll
Report Id: 983c1451-0e8d-11e4-a4b9-b8ca3a74f207

应用程序甚至没有在我们的代码上崩溃,但通常在 CLR 代码或 PBVM 代码的某个地方。崩溃转储中的调用堆栈甚至不包含我们的任何函数,它似乎是纯粹的 .NET 框架/CLR 代码。下面的调用堆栈是我们通常看到的,但即使这样从一次崩溃到下一次崩溃也不一致:

clr.dll!string "d:\\iso_whid\\x86fre\\base\\ntos\\rtl"...()  + 0x4f3b9b bytes   
ntdll.dll!ExecuteHandler@20()  + 0x24 bytes 
ntdll.dll!_KiUserExceptionDispatcher@8()  + 0xe bytes   
0b1cb4b4()  
clr.dll!GetFastContextCookie()  + 0x1d bytes    
clr.dll!CtxEntry::EnterContextCallback()  + 0x41 bytes  
ole32.dll!CRemoteUnknown::DoCallback()  + 0x3b bytes    
rpcrt4.dll!_Invoke@12()  + 0x30 bytes   
rpcrt4.dll!_NdrStubCall2@16()  + 0x217 bytes    
rpcrt4.dll!_CStdStubBuffer_Invoke@12()  + 0x82 bytes    
ole32.dll!SyncStubInvoke()  + 0x30 bytes    
ole32.dll!StubInvoke()  + 0x73 bytes    
ole32.dll!CCtxComChnl::ContextInvoke()  + 0xdb bytes    
ole32.dll!MTAInvoke()  + 0x1a bytes 
ole32.dll!STAInvoke()  + 0x4c bytes 
ole32.dll!AppInvoke()  + 0x8d bytes 
ole32.dll!ComInvokeWithLockAndIPID()  + 0x21b bytes 
ole32.dll!ComInvoke()  + 0x71 bytes 
ole32.dll!ThreadDispatch()  + 0x1a bytes    
ole32.dll!ThreadWndProc()  + 0x93 bytes 
user32.dll!_InternalCallWinProc@20()  + 0x28 bytes  
user32.dll!_UserCallWinProcCheckWow@32()  + 0xa2 bytes  
user32.dll!_DispatchMessageWorker@8()  + 0xc8 bytes 
user32.dll!_DispatchMessageW@4()  + 0xf bytes   
ole32.dll!CCliModalLoop::PeekRPCAndDDEMessage()  - 0x7982 bytes 
ole32.dll!CCliModalLoop::BlockFn()  + 0x1143 bytes  
ole32.dll!_CoWaitForMultipleHandles@20()  + 0xb7 bytes  
clr.dll!MsgWaitHelper()  + 0x6f bytes   
clr.dll!Thread::DoAppropriateAptStateWait()  + 0x12524 bytes    
clr.dll!Thread::DoAppropriateWaitWorker()  + 0xe9 bytes 
clr.dll!Thread::DoAppropriateWait()  + 0x60 bytes   
clr.dll!Thread::JoinEx()  + 0x83 bytes  
clr.dll!Thread::Join()  + 0x16 bytes    
clr.dll!RCW::Initialize()  + 0x1cb81f bytes 
clr.dll!RCW::CreateRCW()  + 0x62 bytes  
clr.dll!COMInterfaceMarshaler::CreateObjectRef()  + 0x4e bytes  
clr.dll!COMInterfaceMarshaler::FindOrCreateObjectRef()  + 0x8c bytes    
clr.dll!GetObjectRefFromComIP()  + 0x125 bytes  
clr.dll!UnmarshalObjectFromInterface()  + 0x1b bytes    
clr.dll!StubHelpers::InterfaceMarshaler__ConvertToManaged()  + 0xc6 bytes   
System.Windows.Forms.ni.dll!7ba745e0()  
[Frames below may be incorrect and/or missing, no symbols loaded for System.Windows.Forms.ni.dll]   
clr.dll!_COMToCLRDispatchHelper@28()  + 0x28 bytes  
clr.dll!BaseWrapper<Stub *,FunctionBase<Stub *,&DoNothing<Stub *>,&StubRelease<Stub>,2>,0,&CompareDefault<Stub *>,2>::~BaseWrapper<Stub *,FunctionBase<Stub *,&DoNothing<Stub *>,&StubRelease<Stub>,2>,0,&CompareDefault<Stub *>,2>()  + 0x175b8b bytes 
clr.dll!COMToCLRWorkerBody()  + 0x80 bytes  
clr.dll!COMToCLRWorkerDebuggerWrapper()  + 0x34 bytes   
clr.dll!_COMToCLRWorker@8()  + 0x12b bytes  
04e7a2c6()  
PBVM120.DLL!10b1a856()  

即使我们将嵌入式 .NET 控件剥离为一个简单/空的容器,上面没有子控件,也没有调用其他重要代码,我们仍然会发生崩溃。 请注意,我们仅使用基本数据类型参数对 .NET 控件进行简单的函数调用。

我们已经能够通过在所有 .NET 控件上手动调用 Dispose 并强制进行垃圾回收来显着提高稳定性,这样现在我们在显示某些嵌入式 .NET 控件时似乎根本不会收到错误,但是我们仍然得到其他人的错误。

这似乎不是内存泄漏问题,因为该应用在崩溃时仅使用了大约 100MB 的 RAM。尽管它看起来确实是某种内存损坏问题,但考虑到它是 CLR 代码中的硬崩溃,通常带有访问冲突错误,并且考虑到在我们的控件上调用 Dispose 似乎可以减少问题的发生。

由于应用程序似乎在 CLR 代码中随机崩溃,我们无法查明问题的确切原因,我们只能说它似乎只在我们的应用程序中打开嵌入了 .NET 的 PowerBuilder 窗口时发生控制。

我们更新了安装在我们机器上的 .NET 版本并应用了看起来可以解决此问题的修补程序(如下),但这并没有帮助。

http://support.microsoft.com/kb/2640103

我们将不胜感激任何帮助,因为我们无法在网络上找到任何其他人遇到此问题的证据。

【问题讨论】:

  • 是的,它们都是内存损坏问题。对于此类问题,.NET 始终是您最不怀疑的。根本没有任何暗示可能是根本原因,除了它是令人讨厌的。您需要的帮助远不止这里所能获得的帮助,是否致电 Microsoft 或 Sybase 支持由您决定。
  • 我在使用 PB 5 的客户端上遇到了类似的问题,这是与 PB 的垃圾收集器有关的问题,当虚拟和物理内存过载时,垃圾收集器正在销毁对象并中断对 ole 对象的引用,导致 Framework 4 在 clr.dll 中抛出该异常。

标签: .net crash clr ole powerbuilder


【解决方案1】:

您是否将 OLE 代码包装在 TRY、CATCH 块中以捕获异常?

OLE 通常会导致崩溃,因为属性可能不存在,或者在您未预料到的情况下可能为空。 try catch 块应该允许您从几乎任何 OLE 异常中正常退出。

我能想到的唯一另一件事是 64 位和 32 位之间的不匹配。我注意到您的 PB 程序出现在 Program Files 下,并且 .NET 对象看起来像是在 SysWOW64 64bit 文件夹中。

我想不出任何其他建议,希望这能解决您的问题。

【讨论】:

    猜你喜欢
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2013-08-23
    • 2013-04-21
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多