注意:mutex windows vista 以上系统用SRWLOCK 实现,winxp用的是rtlocks.cpp
critical_section 调用InterlockedCompareExchangePointer 来实现的 一下分别以win7 和 xp 对比下dmp
#include "stdafx.h"
#include "mutex_d.h"
#include<thread>
#include<mutex>
#include<iostream>
std::mutex test;
void t_fun()
{
test.lock();//重入导致死锁
std::cout << "hello\n";
test.unlock();
}
int main(int argc, TCHAR* argv[])
{
test.lock();
std::thread th(t_fun);
th.join();
return 0;
}
1、win7 系统如下图:
windbg 输入~*kb打印堆栈 可以看到
0:000> ~*kb
. 0 Id: 120c.18b4 Suspend: 1 Teb: 7efdd000 Unfrozen
ChildEBP RetAddr Args to Child
0019f554 75a71629 00000030 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15
0019f5c0 75781194 00000030 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x98
0019f5d8 0f89dd44 00000030 ffffffff 00000000 kernel32!WaitForSingleObjectExImplementation+0x75
0019f5f4 00fe551f 00000030 00001990 00000000 MSVCP140D!_Thrd_join+0x14 [f:\dd\vctools\crt\crtw32\stdcpp\thr\cthread.c @ 50]
0019f708 00fe58b6 b6845292 00000000 00000000 mutex_d!std::thread::join+0xdf [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thread @ 194]
0019f80c 00fe6a0e 00000001 005fd810 005febc8 mutex_d!main+0x66 [d:\布局测试\glog_test\mutex_d\mutex_d.cpp @ 26]
0019f820 00fe6890 b68452e6 00000000 00000000 mutex_d!invoke_main+0x1e [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 64]
0019f878 00fe672d 0019f888 00fe6a28 0019f894 mutex_d!__scrt_common_main_seh+0x150 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 253]
0019f880 00fe6a28 0019f894 7578344d 7efde000 mutex_d!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 296]
0019f888 7578344d 7efde000 0019f8d4 77b89802 mutex_d!mainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 17]
0019f894 77b89802 7efde000 77ac69ae 00000000 kernel32!BaseThreadInitThunk+0xe
0019f8d4 77b897d5 00fe10b4 7efde000 00000000 ntdll!__RtlUserThreadStart+0x70
0019f8ec 00000000 00fe10b4 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b
1 Id: 120c.1990 Suspend: 1 Teb: 7efda000 Unfrozen
ChildEBP RetAddr Args to Child
0088f3a8 77bc0690 00000000 0088f3d0 00000000 ntdll!NtWaitForKeyedEvent+0x15
0088f408 0f8efd12 00ff0388 77b8409f 77b8409f ntdll!RtlAcquireSRWLockExclusive+0x12e
0088f41c 0f8c3143 00ff0388 00ff0384 0088f488 MSVCP140D!__crtAcquireSRWLockExclusive+0x32 [f:\dd\vctools\crt\crtw32\misc\winapisupp.cpp @ 605]
0088f42c 0f8c3206 005e5580 00000000 005e5580 MSVCP140D!Concurrency::details::stl_critical_section_win7::lock+0x13 [f:\dd\vctools\crt\crtw32\stdcpp\thr\primitives.h @ 166]
0088f488 0f8c372e 00ff0380 00000000 0088f570 MSVCP140D!mtx_do_lock+0xb6 [f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c @ 100]
0088f498 00fe4b6a 00ff0380 0088f654 0088f730 MSVCP140D!_Mtx_lock+0xe [f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c @ 186]
0088f570 00fe56e1 00ff0380 0088f728 0088f730 mutex_d!std::_Mtx_lockX+0x2a [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 70]
0088f654 00fe57a8 0088f7fc 0088f730 005fdd50 mutex_d!std::_Mutex_base::lock+0x31 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\mutex @ 43]
0088f728 00fe32b0 0088f8d4 0088fba0 005fdd50 mutex_d!t_fun+0x28 [d:\布局测试\glog_test\mutex_d\mutex_d.cpp @ 16]
0088f7fc 00fe3650 005fdd20 0088f9ac 0088fba0 mutex_d!std::_Invoker_functor::_Call<void (__cdecl*)(void)>+0x30 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits @ 1375]
0088f8d4 00fe3319 005fdd20 0088faa8 0088fba0 mutex_d!std::invoke<void (__cdecl*)(void)>+0x30 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits @ 1443]
0088f9ac 00fe4e90 005fdd20 000000cc b615502a mutex_d!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Execute<0>+0x39 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 240]
0088fab4 00fe4a0c 0019f5d0 0088fc6c 0088fba0 mutex_d!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Run+0x80 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 247]
0088fb98 00fe471c 00000000 00000000 005fdd50 mutex_d!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Go+0x2c [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 232]
0088fc6c 004d8968 0019f5d0 00fe11c2 b67306c7 mutex_d!std::_Pad::_Call_func+0x2c [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 209]
0088fc80 004d867b 00fe11c2 0019f5d0 b673068f ucrtbased!invoke_thread_procedure+0x28 [d:\th\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp @ 92]
0088fcc8 7578344d 005fdd50 0088fd14 77b89802 ucrtbased!thread_start<unsigned int (__stdcall*)(void *)>+0xab [d:\th\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp @ 115]
0088fcd4 77b89802 005fdd50 773d6c6e 00000000 kernel32!BaseThreadInitThunk+0xe
0088fd14 77b897d5 004d85d0 005fdd50 00000000 ntdll!__RtlUserThreadStart+0x70
0088fd2c 00000000 004d85d0 005fdd50 00000000 ntdll!_RtlUserThreadStart+0x1b
重点看这段代码
1 Id: 120c.1990 Suspend: 1 Teb: 7efda000 Unfrozen
ChildEBP RetAddr Args to Child
0088f3a8 77bc0690 00000000 0088f3d0 00000000 ntdll!NtWaitForKeyedEvent+0x15
0088f408 0f8efd12 00ff0388 77b8409f 77b8409f ntdll!RtlAcquireSRWLockExclusive+0x12e
0088f41c 0f8c3143 00ff0388 00ff0384 0088f488 MSVCP140D!__crtAcquireSRWLockExclusive+0x32 [f:\dd\vctools\crt\crtw32\misc\winapisupp.cpp @ 605]
0088f42c 0f8c3206 005e5580 00000000 005e5580 MSVCP140D!Concurrency::details::stl_critical_section_win7::lock+0x13 [f:\dd\vctools\crt\crtw32\stdcpp\thr\primitives.h @ 166]
0088f488 0f8c372e 00ff0380 00000000 0088f570 MSVCP140D!mtx_do_lock+0xb6 [f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c @ 100]
0088f498 00fe4b6a 00ff0380 0088f654 0088f730 MSVCP140D!_Mtx_lock+0xe [f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c @ 186]
ntdll!NtWaitForKeyedEvent在等待一个SRWLock 所以找到死锁原因L
{
有没有想起 AcquireSRWLockExclusive
}
由于std::mutex内部实现是用SRWLock 使用的时候不能重入!!!!!
2、xp系统如下图:
5 Id: 644.15c Suspend: 0 Teb: 7ffda000 Unfrozen
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
00cbf650 00567250 00000080 ffffffff 00000000 ntdll!KiFastSystemCallRet
00cbf670 005239c7 004b4b26 0016b670 00cbf6b0 mutex_d!Concurrency::details::ExternalContextBase::Block+0xa0 [f:\dd\vctools\crt\crtw32\concrt\externalcontextbase.cpp @ 151]
00cbf680 0051b923 00cbf8b8 7c931008 00000004 mutex_d!Concurrency::Context::Block+0x27 [f:\dd\vctools\crt\crtw32\concrt\context.cpp @ 63]
00cbf6b0 0051c5cb 0000000a 0051ad50 00cbf6d0 mutex_d!Concurrency::details::LockQueueNode::Block+0x123 [f:\dd\vctools\crt\crtw32\concrt\rtlocks.cpp @ 710]
00cbf6dc 0051dad7 00cbf6ec 00000000 0016b670 mutex_d!Concurrency::critical_section::_Acquire_lock+0x9b [f:\dd\vctools\crt\crtw32\concrt\rtlocks.cpp @ 1207]
00cbf70c 004cfc92 00688d4c 00cbf774 004cfd96 mutex_d!Concurrency::critical_section::lock+0x27 [f:\dd\vctools\crt\crtw32\concrt\rtlocks.cpp @ 1035]
00cbf718 004cfd96 7c930040 00000000 00150178 mutex_d!Concurrency::details::stl_critical_section_concrt::lock+0x12 [f:\dd\vctools\crt\crtw32\stdcpp\thr\primitives.h @ 245]
00cbf774 004d03be 00688d48 00000000 00cbf85c mutex_d!mtx_do_lock+0xb6 [f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c @ 100]
00cbf784 004cafb7 00688d48 00cbf940 00cbfa1c mutex_d!_Mtx_lock+0xe [f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c @ 186]
00cbf85c 004cd741 00688d48 00cbfa14 00cbfa1c mutex_d!std::_Mtx_lockX+0x27 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 70]
00cbf940 004ce0d8 00cbfae8 00cbfa1c 0016b090 mutex_d!std::_Mutex_base::lock+0x31 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\mutex @ 43]
00cbfa14 004c6290 00cbfbc0 00cbfe8c 0016b090 mutex_d!t_fun+0x28 [d:\布局测试\glog_test\mutex_d\mutex_d.cpp @ 17]
00cbfae8 004c6f60 0016afa8 00cbfc98 00cbfe8c mutex_d!std::_Invoker_functor::_Call<void (__cdecl*)(void)>+0x30 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits @ 1375]
00cbfbc0 004c63c9 0016afa8 00cbfd94 00cbfe8c mutex_d!std::invoke<void (__cdecl*)(void)>+0x30 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits @ 1443]
00cbfc98 004cb9d0 0016afa8 000000cc e4ae730f mutex_d!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Execute<0>+0x39 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 240]
00cbfda0 004cab6c 0012fd08 00cbff58 00cbfe8c mutex_d!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Run+0x80 [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 247]
00cbfe84 004c9d8c 0016ae08 00689ba0 0016b090 mutex_d!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Go+0x2c [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 232]
00cbff58 0058fc98 0012fd08 004b5fa3 e4ae71c3 mutex_d!std::_Pad::_Call_func+0x2c [d:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread @ 209]
00cbff6c 0058f83b 004b5fa3 0012fd08 e4ae711b mutex_d!invoke_thread_procedure+0x28 [d:\th\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp @ 92]
00cbffb4 7c80b713 0016b090 0016ae08 00689ba0 mutex_d!thread_start<unsigned int (__stdcall*)(void *)>+0xab [d:\th\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp @ 115]
00cbffec 00000000 0058f790 0016b090 00000000 kernel32!GetModuleFileNameA+0x1b4