簡體   English   中英

調用AccessibleChildren時線程凍結

[英]Thread freezes while calling AccessibleChildren

我的C ++應用程序會時不時地使用基於此頁面的基於MSDN示例的代碼遍歷多個應用程序的MSAA樹: https : //msdn.microsoft.com/zh-cn/library/windows/desktop/dd317975(v=vs.85 ).aspx

它工作得很好,直到幾個月前我開始注意到有時AccessibleChildren調用中的線程凍結。

這是我所知道的:

  • 這種情況不會經常發生
  • 當走不同應用程序的樹時會發生這種情況。
  • 它絕對沒有連接到當前節點的子節點數量,因為我已經調試了底部調用childCount等於1的小型轉儲。
  • 它發生在不同的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

我仍然不知道為什么以上所有事情都會發生,以及如何在我的代碼中如何保護我的應用程序免受此類攻擊。 我認為自己的唯一解決方案是使用單獨的過程,並等待一段時間。 類似於此Microsoft示例 ,但超時設置為恆定值(例如半秒),而不是INFINITE

如果等待由於進程完成而結束,那么我會得到它的標准輸出作為響應(一些帶有結果的json或類似的東西)。 如果進程超時,我將終止它以清理其資源。

這不是一個完美的解決方案,但是它將使我對正在發生的事情有所控制,並且可以以某種方式保護我免受內存泄漏等的影響。

由於這只是一半,我很樂意接受任何其他想法來解決我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM