.net - PowerBuilder 中嵌入的 .NET 控件随机崩溃

标签 .net crash clr ole powerbuilder

在将一些嵌入 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

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

最佳答案

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

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

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

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

关于.net - PowerBuilder 中嵌入的 .NET 控件随机崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25004381/

相关文章:

Android 应用程序不会在 bluestack 中启动

c++ - 从成员类调用封装的 std::begin 时程序崩溃

C++如何使一个函数只运行一个

winforms - 如何从线程设置 ToolStripProgressBar 的值?

c# - 调用 Assembly.Load(byte[]) 可以引发 AppDomain.AssemblyResolve 事件吗?

c# - 让 ViewModel 对象持有 Dispatcher 是否被认为是不好的做法?

c# - 如何避免在 web.config 中添加程序集版本?

android - Adview错误,片刻后崩溃

c# - .NET API 文档是否应该定义/公开枚举成员的文字(数字)值?

c# - 无法从 web api POST 读取正文数据