0

アプリケーションのシャットダウン中に、プロセスの 1 つがクラッシュしています。ErrorHandlingClient は dll です。クラッシュ ダンプに次の行が表示されます。

"`CErrorLog::m_IErrorHandlingServerPtr の動的 atexit デストラクタ"

スタックオーバーフローもmsdnで検索しました。明確な答えを得ることができませんでした。私たちのアプリケーションは vc 9.0 コンパイラに移植されています。以前のバージョンでは、この問題は発生していません。クラッシュダンプを貼り付けています。

0018fcf4  76c28681 ole32!CStdIdentity::~CStdIdentity+0x8c
0018fcf8  00000002
0018fcfc  0081aa38
0018fd00  0081a990
0018fd04  693bbf14 ErrorHandlingClient!__native_startup_lock
0018fd08  007a1890
0018fd0c  0018fd18
0018fd10  76c285eb ole32!CStdIdentity::`scalar deleting destructor'+0xd
0018fd14  0081a990
0018fd18  0018fd2c
0018fd1c  76c2882a ole32!CStdIdentity::CInternalUnk::Release+0x6e
0018fd20  00000001
0018fd24  005c037c
0018fd28  737d3607 msvcr90!_decode_pointer
0018fd2c  0018fd38
0018fd30  76d3b6b9 ole32!IUnknown_Release_Proxy+0x11
0018fd34  80000000
0018fd38  0018fd60
0018fd3c  693a8421 ErrorHandlingClient!`dynamic atexit destructor for 'CErrorLog::m_IErrorHandlingServerPtr''+0x11
0018fd40  0081c9ec
0018fd44  693a462f ErrorHandlingClient!_CRT_INIT+0x1be [f:\dd\vctools\crt_bld\self_x86\crt\src\crtdll.c @ 449]
0018fd48  693a8410 ErrorHandlingClient!`dynamic atexit destructor for 'CErrorLog::m_IErrorHandlingServerPtr''
0018fd4c  00000001
0018fd50  00000000
0018fd54  69390000 ErrorHandlingClient!Define_the_symbol__ATL_MIXED::Thank_you::Thank_you <PERF> (ErrorHandlingClient+0x0)
0018fd58  693a8410 ErrorHandlingClient!`dynamic atexit destructor for 'CErrorLog::m_IErrorHandlingServerPtr''
0018fd5c  00000000
0018fd60  0018fda4
0018fd64  693a474e ErrorHandlingClient!__DllMainCRTStartup+0xb7 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtdll.c @ 560]
4

1 に答える 1

0

本当に十分な情報を提供していませんが、これは COM が初期化されていない後に COM オブジェクトが破棄されるという問題ですか?

奇妙な名前の m_IErrorHandlingServerPtr は、最後のインスタンス (クラスのメンバーとして保持されている) がスコープ外になると破棄される COM 共有ポインターである可能性がありますが、この削除を実行するには COM がまだ生きている必要があります。

考えられる解決策の 1 つは、クラスに独自の Initialize/Uninitialize ペアがあることを確認することです。これは、コンストラクタで初期化を行い、デストラクタで初期化を解除する基本クラスから派生させることで実現できます。これにはプライベート継承を使用できます。さまざまなスレッド モデルに注意する必要があります。

古い環境でクラッシュしない理由はわかりませんが、過去にさまざまなことに COM を使用していた可能性があり、現在は COM を使用しないように変更されているため、たまたま COM が生きていました。さらに、これがある種のグローバルである場合、それらの破棄順序は常に非決定論的であるため、本質的にこれは常に未定義の動作でしたが、過去に観察された「未定義」の動作は、機能しただけで、現在は機能していません。 t。

于 2012-06-14T09:14:22.463 に答える