主线程与调用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
...全文
1167 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组件对多线程支持有问题,套间线程等。把它放主线程试试。
代码下载地址: https://pan.quark.cn/s/8236006bf1f9 Word精灵插件:一款用于增强Microsoft Word功能的辅助软件,能够将多种复杂功能转化为插件形式,并在软件状态栏中进行展示,涵盖诸如批注管理、表格处理、内容替换、文档拆分、数学运算、字符提取、批量重命名等多项实用工具。在工作环境中应用该插件能够显著降低工作强度,提升操作效率。Word精灵插件兼容32位与64位的Microsoft Word版本,支持Word 2007、2010、2013以及Word 2016操作系统,但不适用于Word 2003版本。此外,该插件同样支持WPS办公软件。 功能概述: 1、表格自动调整宽度:自动优化文档内所有表格的显示宽度。 2、批量导出批注信息:将文档内所有批注集中导出到Excel工作簿中。 3、表格至Excel多表导出:在将表格导出到Excel时,每个Word表格将独立存放在一个工作表中,Word文档内的表格数量与Excel生成的工作表数量相等,并附有工作表目录。 4、表格至Excel单表导出:将文档内所有表格整合后导出到一个Excel工作表中,多个表格将按顺序排列于同一工作表内。 5、统一图片分辨率:对指定文件夹内的所有图片进行分辨率标准化处理。 6、图片批量缩放:依据设定比例对图片进行放大或缩小,支持按百分比调整。 7、图片批量插入:将图片批量插入到当前文档,可选择图片名称的展示形式,并设定图片的高度。 8、图片格式统一转换:将指定文件夹内的所有图片转换为相同的文件格式。 9、内容批量替换:对文档内容、页眉及页脚执行批量替换操作,例如将数字1替换为字母A,数字2替换为字母B,数字3替换为字母C等。 10、图片批量导出:将文档内所...
打开链接下载源码: https://pan.quark.cn/s/245ca7a27256 OmniGraffle是一款效能卓越的图形设计软件,在构建图表、流程图以及组织结构图等领域的应用尤为突出。该软件起源于Mac操作系统,并且兼容iOS平台,作为专业人士及业余爱好者进行图形设计时的首选工具之一。在OmniGraffle的功能模块中,“泳道图流程图”占据着核心地位,它要用于勾勒业务流程图或系统流程图,其中各个分隔的泳道象征着不同的职能角色、部门划分或工作流程的各个阶段。泳道图(Lanes Diagram)作为流程图的一种特殊形式,通过将流程中的各个操作步骤分配到垂直或水平的“泳道”之中,能够明确地揭示出每个参与方或部门所承担的责任以及整个流程的走向。此类图形通常应用于业务流程管理(BPM)和系统分析领域,旨在帮助用户深入理解并优化复杂的业务流程。 在OmniGraffle中构建泳道图时,由于软件本身并未提供现成的泳道图模板,用户需要自行设计图形和布局以模拟出泳道的效果。然而,您提供的"06stencil泳道图流程图.graffle"文件很可能是一个预先构建好的模板,能够显著简化这一过程。该模板可能包含了预先设计好的泳道形态、箭头以及其他流程图组件,使用户能够直接在此基础上进行修改和增添个人的步骤,从而节省了大量的设计时间。 应用OmniGraffle的泳道图模板,你可以: 1. **导入模板**:首先需要启动OmniGraffle并将"06stencil泳道图流程图.graffle"文件添加到你的项目工作中。 2. **定制泳道**:依据实际需求调整泳道的数量和尺寸,使之契合你的业务流程。每个泳道对应一个角色或部门,确保它们的排列顺序和宽度能够精确地体现实际的工...

15,465

社区成员

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

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