0

時々、私の C++ アプリケーションは、このページの MSDN の例に基づくコードを使用して、複数のアプリケーションの MSAA ツリーをたどります: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317975(v=vs.85 .aspx

数か月前に AccessibleChildren 呼び出しでスレッドがフリーズすることがあることに気付き始めるまで、それは完全に機能しました。

これが私が知っていることです:

  • これはあまり頻繁には発生しません
  • さまざまなアプリケーションのツリーを歩いているときに発生します。
  • ボトムコールが 1 に等しい場所のミニダンプを既にデバッグしたので、現在のノードの子の量には絶対に接続されていませんchildCount
  • 異なるPCで発生します。
  • そのような位置にあるスレッドは決して起きません。フリーズが発生すると、スレッドはアプリが再起動されるまでこの状態のままになります。
  • そのような反復中にスレッドが単に死ぬこともあり、そのような場合、スレッドのスタックトレースをキャッチできません。その後、アプリの残りの部分は実行され続けますが、タスクは基本的にスリープを伴う無限ループですが、特定のスレッドが機能しなくなったことをダンプが示しています。フリーズにつながっていると思います。何とかして。

私の質問は: 誰かがそのような凍結の理由とそれを防ぐ方法を指摘できますか? そうでない場合、別のスレッドから安全に「タイムアウト」できる再帰を別のスレッドに移動する方法はありますか?

これは、そのようなイベントのスタック トレースの例です。top は、最もネストされた呼び出しです。読みを少し短くするために、ここから再帰を削除しました。

--> ntdll.dll!_NtWaitForMultipleObjects@20()    Unknown
    ntdll.dll!_NtWaitForMultipleObjects@20()    Unknown
    KERNELBASE.dll!_WaitForMultipleObjectsEx@20()   Unknown
    kernel32.dll!_WaitForMultipleObjectsExImplementation@20()   Unknown
    user32.dll!_RealMsgWaitForMultipleObjectsEx@20()    Unknown
    ole32.dll!CCliModalLoop::BlockFn(void * * ahEvent, unsigned long cEvents, unsigned long * lpdwSignaled) Line 1222   C++
    ole32.dll!ModalLoop(CMessageCall * pcall) Line 211  C++
    ole32.dll!ThreadSendReceive(CMessageCall * pCall) Line 4979 C++
    ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall(CMessageCall * * ppCall) Line 4454    C++
    ole32.dll!CRpcChannelBuffer::SendReceive2(tagRPCOLEMESSAGE * pMessage, unsigned long * pstatus) Line 4076   C++
    ole32.dll!CCliModalLoop::SendReceive(tagRPCOLEMESSAGE * pMsg, unsigned long * pulStatus, IInternalChannelBuffer * pChnl) Line 899   C++
    ole32.dll!CAptRpcChnl::SendReceive(tagRPCOLEMESSAGE * pMsg, unsigned long * pulStatus) Line 583 C++
    ole32.dll!CCtxComChnl::SendReceive(tagRPCOLEMESSAGE * pMessage, unsigned long * pulStatus) Line 659 C++
    ole32.dll!NdrExtpProxySendReceive(void * pThis, _MIDL_STUB_MESSAGE * pStubMsg) Line 1932    C++
    rpcrt4.dll!@NdrpProxySendReceive@4()    Unknown
    rpcrt4.dll!_NdrClientCall2()    Unknown
    ole32.dll!ObjectStublessClient(void * ParamAddress, long Method) Line 474   C++
    ole32.dll!_ObjectStubless@0() Line 154  Unknown
    ole32.dll!CStdMarshal::Begin_RemQIAndUnmarshal1(unsigned short cIIDs, _GUID * pIIDs, tagQICONTEXT * pQIC) Line 4551 C++
    ole32.dll!CStdMarshal::Begin_QueryRemoteInterfaces(unsigned short cIIDs, _GUID * pIIDs, tagQICONTEXT * pQIC)    C++
    ole32.dll!CStdMarshal::QueryRemoteInterfaces(unsigned short cIIDs, _GUID * pIIDs, tagSQIResult * pQIRes) Line 4284  C++
    ole32.dll!CStdIdentity::CInternalUnk::QueryMultipleInterfaces(unsigned long cMQIs, tagMULTI_QI * pMQIs) Line 596    C++
    ole32.dll!CStdIdentity::CInternalUnk::QueryInterface(const _GUID & riid, void * * ppv) Line 352 C++
    ole32.dll!IUnknown_QueryInterface_Proxy(IUnknown * This, const _GUID & riid, void * * ppv) Line 1723    C++
    ole32.dll!CoUnmarshalInterface(IStream * pStm, const _GUID & riid, void * * ppv) Line 996   C++
    oleacc.dll!UnmarshalInterface(unsigned char const *,unsigned long,struct _GUID const &,void * *)    Unknown
    oleacc.dll!FreeUpSlot(struct OutstandingObjectEntry *)  Unknown
    oleacc.dll!_ObjectFromLresult@16()  Unknown
    oleacc.dll!NativeIAccessibleFromWindow(struct HWND__ *,unsigned long,struct _GUID const &,void * *) Unknown
    oleacc.dll!_ORIGINAL_AccessibleObjectFromWindow@16()    Unknown
    oleacc.dll!_AccessibleObjectFromWindow@16() Unknown
    oleacc.dll!GetWindowObject(struct HWND__ *,struct tagVARIANT *) Unknown
    oleacc.dll!CClient::Next(unsigned long,struct tagVARIANT *,unsigned long *) Unknown
    oleacc.dll!AccWrap_Base::Next(unsigned long,struct tagVARIANT *,unsigned long *)    Unknown
    oleacc.dll!_AccessibleChildren@20() Unknown
    //my recursion ends here
4

1 に答える 1