主线程与调用CoInitializeEx的子线程互锁问题

skertone 2017-05-19 03:00:55
我有一应用在WIN7下一定概率出现调用API过程中互锁卡死现象

大概执行流程:
1. 对话框应用程序在OnInitDialog中创建 A线程
2. A线程随后调用LoadLibrary加载一个使用了COM的动态库
3. 然后一定概率应用程序的0号线程与 A线程互锁卡死
请问是什么原因,又如何解决呢?

锁死的资源:

0:000> !locks
CritSec ntdll!LdrpLoaderLock+0 at 770e8340
WaiterWoken No
LockCount 1
RecursionCount 1
OwningThread 23b4
EntryCount 0
ContentionCount 5
*** Locked

CritSec ole32!g_mxsSingleThreadOle+18 at 76ab873c
WaiterWoken No
LockCount 1
RecursionCount 1
OwningThread 14c8
EntryCount 0
ContentionCount 1
*** Locked

线程列ID列表:

0:000> ~
. 0 Id: 190c.14c8 Suspend: 0 Teb: 7ffde000 Unfrozen
1 Id: 190c.1540 Suspend: 0 Teb: 7ffdd000 Unfrozen
2 Id: 190c.15bc Suspend: 0 Teb: 7ffdc000 Unfrozen
3 Id: 190c.2dc Suspend: 0 Teb: 7ffdb000 Unfrozen
4 Id: 190c.1abc Suspend: 0 Teb: 7ffda000 Unfrozen
5 Id: 190c.2608 Suspend: 0 Teb: 7ffd9000 Unfrozen
6 Id: 190c.23b4 Suspend: 0 Teb: 7ffd8000 Unfrozen
7 Id: 190c.c74 Suspend: 0 Teb: 7ffd7000 Unfrozen
8 Id: 190c.19a4 Suspend: 0 Teb: 7ffd6000 Unfrozen

线程0调用栈

0:000> ~0kb
ChildEBP RetAddr Args to Child
0012f110 770565ec 77041df5 00000104 00000000 ntdll!KiFastSystemCallRet
0012f114 77041df5 00000104 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0012f178 77041cd9 00000000 00000000 0012f1e0 ntdll!RtlpWaitOnCriticalSection+0x13e
0012f1a0 7706f88f 770e8340 705f0c1b 7722289e ntdll!RtlEnterCriticalSection+0x150
0012f23c 77072120 750d0000 0012f278 00000000 ntdll!LdrGetProcedureAddressEx+0x159
0012f258 75416d18 750d0000 0012f278 00000000 ntdll!LdrGetProcedureAddress+0x18
0012f280 771b6665 750d0000 7722289e 0012f43c KERNELBASE!GetProcAddress+0x44
0012f2c8 771b66c6 750d0000 772280d0 0012f2f8 rpcrt4!__delayLoadHelper2+0xee
0012f400 771b62ee 0012f43c 00000010 00000001 rpcrt4!_tailMerge_CRYPTBASE_dll+0xd
0012f414 769b153d 0012f43c 00000001 0012f450 rpcrt4!UuidCreate+0x11
0012f424 769b1745 0012f43c 754169c1 0012f4b4 ole32!wCoCreateGuid+0xf [d:\w7rtm\com\ole32\com\class\cocrguid.cxx @ 86]
0012f450 769b1a7f 00000008 754169c1 0012f4b4 ole32!CObjectContext::CreateObjectContext+0x52 [d:\w7rtm\com\ole32\com\dcomrem\context.cxx @ 999]
0012f46c 769b62bb 001f3fbc 001f3fd0 0012f4b4 ole32!InitThreadCtx+0x52 [d:\w7rtm\com\ole32\com\class\compobj.cxx @ 2268]
0012f498 769b0ade 00000000 00000002 00000000 ole32!wCoInitializeEx+0x62 [d:\w7rtm\com\ole32\com\class\compobj.cxx @ 2420]
0012f4b8 76d23cf6 00000002 00000002 76d23cc1 ole32!CoInitializeEx+0x2ee [d:\w7rtm\com\ole32\com\class\compobj.cxx @ 2119]
0012f4c4 76d23cc1 76d237a8 001f0448 76e037d0 imm32!CtfImmCoInitialize+0x18
0012f4c8 76d237a8 001f0448 76e037d0 0012f4f0 imm32!CanCreateThreadMgr+0x24
0012f4d8 76d23ad6 08040804 00000001 00170a08 imm32!CtfImmTIMActivate+0x6c
0012f4f0 76d22836 0778091f 00000001 0012f524 imm32!InternalImmLockIMC+0x77
0012f500 76d22cd6 0778091f 00000000 00170a08 imm32!ImmLockIMC+0xf
0012f524 76e01e7d 00170a08 00000000 00000001 imm32!ImmSetActiveContext+0x5c
0012f540 76e0030b 00170a08 00000001 00000282 user32!FocusSetIMCContext+0x28
0012f794 76e002a0 001de930 00000287 00000017 user32!ImeSystemHandler+0x31c
0012f7bc 76e1174b 00807d88 00000287 00000017 user32!ImeWndProcWorker+0x2bd
0012f7d8 76e0c4b7 00120668 00000287 00000017 user32!ImeWndProcA+0x22
0012f804 76e0c5b7 76e11729 00120668 00000287 user32!InternalCallWinProc+0x23
0012f87c 76e01b01 00000000 76e11729 00120668 user32!UserCallWinProcCheckWow+0x14b
0012f8ac 76e22bbe 76e11729 00120668 00000287 user32!CallWindowProcAorW+0x99
*** ERROR: Symbol file could not be found. Defaulted to export symbols for MFC42D.DLL -
0012f8cc 5f42f2d9 76e11729 00120668 00000287 user32!CallWindowProcA+0x1b
WARNING: Stack unwind information not available. Following frames may be wrong.
0012f964 76e0c4b7 00120668 00000287 00000017 MFC42D!Ordinal1086+0x1db
0012f990 76e0c5b7 5f42f10e 00120668 00000287 user32!InternalCallWinProc+0x23
0012fa08 76e04ede 00000000 5f42f10e 00120668 user32!UserCallWinProcCheckWow+0x14b
0012fa64 76e04f4d 00807d88 00000287 00000017 user32!DispatchClientMessage+0xcf
0012fa8c 77056bae 0012faa4 00000018 0012fc44 user32!__fnDWORD+0x24
0012fab8 76dfab81 76e1fd6f 00170a08 0012fea4 ntdll!KiUserCallbackDispatcher+0x2e
0012fabc 76e1fd6f 00170a08 0012fea4 7ffdf000 user32!NtUserSetFocus+0xc
0012fb68 76e2532a 00400000 001114aa 000000c0 user32!InternalCreateDialog+0xb67
0012fb8c 76e17208 00400000 0041f798 00000000 user32!CreateDialogIndirectParamAorW+0x33
0012fbac 5f4363e7 00400000 0041f798 00000000 user32!CreateDialogIndirectParamA+0x1b
0012fc50 5f436a22 0041f798 00000000 00400000 MFC42D!Ordinal1647+0x296
0012fcb8 004033e1 00000000 00000000 7ffdf000 MFC42D!Ordinal1862+0x144
0012feb0 5f4359f3 00000000 00000000 7ffdf000 GrgPIN_GRGBankingEPP_XFS30D+0x33e1
0012fed0 00407788 00400000 00000000 001a32ea MFC42D!Ordinal1190+0x83
0012fee8 00407553 00400000 00000000 001a32ea GrgPIN_GRGBankingEPP_XFS30D+0x7788
0012ff88 76b1ef8c 7ffdf000 0012ffd4 7707367a GrgPIN_GRGBankingEPP_XFS30D+0x7553
0012ff94 7707367a 7ffdf000 705f01f3 00000000 kernel32!BaseThreadInitThunk+0xe
0012ffd4 7707364d 004073a0 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
0012ffec 00000000 004073a0 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b

线程6调用栈

0:000> ~6kb
ChildEBP RetAddr Args to Child
0338ca00 770565ec 77041df5 00000280 00000000 ntdll!KiFastSystemCallRet
0338ca04 77041df5 00000280 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0338ca68 77041cd9 00000000 00000000 00000000 ntdll!RtlpWaitOnCriticalSection+0x13e
0338ca90 769beb0f 76ab873c 76ab7b04 76ab8724 ntdll!RtlEnterCriticalSection+0x150
0338caa4 769b0ad4 769b7998 00000845 769b79c4 ole32!COleStaticMutexSem::Request+0x39 [d:\w7rtm\com\ole32\common\olesem.cxx @ 177]
0338cac8 02151bd2 00000000 00000000 0338ccd8 ole32!CoInitializeEx+0x2e4 [d:\w7rtm\com\ole32\com\class\compobj.cxx @ 2118]
0338cbf0 02162e80 02150000 00000001 00000000 DevBaseDllD!DllMain+0xb7 [D:\workspace\SVN\Dunite\Dunite-ODevbase_v3.3.0\Src\DevBaseDll.cpp @ 81]
0338cc08 77068854 02150000 00000001 00000000 DevBaseDllD!_DllMainCRTStartup+0x80 [crtdll.c @ 273]
0338cc28 77075b3f 02162e00 02150000 00000001 ntdll!LdrpCallInitRoutine+0x14
0338cd1c 7706fb56 00000000 737530b7 7705780a ntdll!LdrpRunInitializeRoutines+0x26f
0338ce90 77072199 0338cefc 0338cec0 00000000 ntdll!LdrpLoadDll+0x472
0338cec8 7543b22e 0338cef5 0338cf1c 0338cefc ntdll!LdrLoadDll+0xaf
0338cf10 7541bde5 00000000 00000000 00000000 KERNELBASE!LoadLibraryExW+0x215
0338cf30 76b1deb7 0338cfcc 00000000 00000000 KERNELBASE!LoadLibraryExA+0x26
0338cf50 025b7c02 0338cfcc 0338d314 0338f2c0 kernel32!LoadLibraryA+0xbb
WARNING: Stack unwind information not available. Following frames may be wrong.
0338d1e4 025b2709 0338f2b8 0338f2c0 01ceb8b8 GrgSpPIND!poCreateInstance+0x662b
0338d314 025c6503 0338fb1c 0338f2c0 01ceb8b8 GrgSpPIND!poCreateInstance+0x1132
0338f2b8 01a60588 0338fda8 0338fdb4 01ceb8b8 GrgSpPIND!poCreateInstance+0x14f2c
0338fb28 01a55c04 0338fe58 0338fdb4 01ceb8b8 GrgSpFrameD!OSpIPCInterface::OSpIPCInterface+0xf07e
0338fda8 01a53cd6 0338fe18 0338feb0 00000000 GrgSpFrameD!OSpIPCInterface::OSpIPCInterface+0x46fa
0338fe58 01a53bd2 00000000 00000000 00000000 GrgSpFrameD!OSpIPCInterface::OSpIPCInterface+0x27cc
0338feb0 5f43a9e4 01ce9f50 00000000 00000000 GrgSpFrameD!OSpIPCInterface::OSpIPCInterface+0x26c8
0338ff54 1020c323 0012ed70 00000000 00000000 MFC42D!Ordinal1879+0x3cc
0338ff88 76b1ef8c 01ceb8b8 0338ffd4 7707367a MSVCRTD!_beginthreadex+0x133
0338ff94 7707367a 01ceb8b8 737501f3 00000000 kernel32!BaseThreadInitThunk+0xe
0338ffd4 7707364d 1020c2b0 01ceb8b8 00000000 ntdll!__RtlUserThreadStart+0x70
0338ffec 00000000 1020c2b0 01ceb8b8 00000000 ntdll!_RtlUserThreadStart+0x1b
...全文
986 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
sevancheng 2017-08-21
  • 打赏
  • 举报
回复
DLLMain 里面干了啥??有没有函数调用?
牧童吃五谷 2017-08-20
  • 打赏
  • 举报
回复
这个需要源代码才能查找,如果提供源代码,应该可以帮你找到问题。 以下建议几个地方: 1.主线程先初始化COM系统,一般采用套间线程,只有特殊情况才能使用自由线程 2然后启动辅助线程,在辅助线程中也是需要初始化COM系统,一般辅助线程可以用套间线程或者自由线程,辅助线程采用自由线程更好用一点 3.两个线程生成的COM接口指针除非是自由线程,否则不能在另外一个线程使用的
赵4老师 2017-05-23
  • 打赏
  • 举报
回复
《Windows核心编程》
赵4老师 2017-05-22
  • 打赏
  • 举报
回复
COM Tutorial Samples Tutorial Home Previous Lesson Lesson List Next Lesson FRECLIEN - Client of Free-threaded Server NOTE: FRECLIEN uses CoInitializeEx. CoInitializeEx is implemented only on Windows NT 4.0 and later versions. It is also implemented in the DCOM95 addition to Win95. This sample will not run on earlier versions of Windows NT or on Win95 without DCOM95. ……
xinhaoda 2017-05-22
  • 打赏
  • 举报
回复
1 CoInitializeEx 注意初始化的位置,应该在你开的线程前和调用对方Com库前 2 最好有代码试试
skertone 2017-05-22
  • 打赏
  • 举报
回复
引用 3 楼 xinhaoda 的回复:
1 CoInitializeEx 注意初始化的位置,应该在你开的线程前和调用对方Com库前 2 最好有代码试试
是的,现在就是子线程跑起来后,就开始初始化COM,还没调到COM组件时,与主线程互锁了。
skertone 2017-05-22
  • 打赏
  • 举报
回复
引用 2 楼 schlafenhamster 的回复:
CoInitializeEx 放初始化中
请问初始化COM有什么忌讳吗?
skertone 2017-05-22
  • 打赏
  • 举报
回复
引用 1 楼 oyljerry 的回复:
一种是com组件对多线程支持有问题,套间线程等。把它放主线程试试。
COM初始化是针对线程的,这里程序就是一定要开个子线程来调用一个COM组件。 如您所说,改程序架构,所有COM相关操作放在主线程,COM线程模型相同,可能是没问题,但现在还不能动架构。
schlafenhamster 2017-05-19
  • 打赏
  • 举报
回复
CoInitializeEx 放初始化中
oyljerry 2017-05-19
  • 打赏
  • 举报
回复
一种是com组件对多线程支持有问题,套间线程等。把它放主线程试试。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧