节目挂在Visual Studio调试器中
Program hangs in Visual Studio debugger
一些背景:我正在尝试跟踪一个引起我重大头痛的错误。经过许多死末端(请参阅此问题),我终于得到了此代码:
#include <thread>
#include <vector>
#include <iosfwd>
#include <sstream>
#include <string>
#include <windows.h>
int main()
{
SRWLOCK srwl;
InitializeSRWLock(&srwl);
for(size_t i=0;i<1000;++i)
{
std::vector<std::thread>threads;
for(size_t j=0;j<100;++j)
{
OutputDebugString(".");
threads.emplace_back([&](){
AcquireSRWLockExclusive(&srwl);
//Code below modifies the probability to see the bug.
std::this_thread::sleep_for(std::chrono::microseconds(1));
std::wstringstream wss;
wss<<std::this_thread::get_id();
wss.str();
//Code above modifies the probability to see the bug.
ReleaseSRWLockExclusive(&srwl);});
}
for(auto&t:threads){t.join();}
OutputDebugString((std::to_string(i)+"n").data());
}
return 0;
}
当我在vs 2013调试器内运行此代码时,程序以这样的输出悬挂:
....................................................................................................0
....................................................................................................1
....................................................................................................2
...........................
奇怪的是,如果我暂停调试器并检查正在发生的事情,那么其中一个线程在CAECAIRESRESRESRWLOCKEXCLUSICY(在Ntwaitforalertbythreadid中)显然没有理由悬挂该程序。当我单击简历时,该程序会愉快地继续并打印更多东西,直到再次被阻止为止。
您是否知道这里发生了什么?
更多信息:
- 据我所知,此错误仅在Windows 8.1上存在。
- 我尝试了VS2013.4和VS2015 RC。
- 我可以在Windows 8.1下的两台不同计算机上复制它。
- 一台机器的格式化是测试的RAM,CPU和磁盘(我想到了故障,因为起初我只能在该特定机器上观察到错误)
- 我永远无法在Windows 7上复制它。
- 修改评论之间的代码以观察错误可能很有用。当我添加微秒睡眠时,我最终可以在另一台计算机上重现该错误。
- 使用VS2015 RC,我可以使用简单的std :: Mutex复制相同的行为。在VS2013上,SRWLOCK似乎必须观察该错误。
此问题是由Windows 8.1春季更新中引入的OS调度程序错误引起的。该问题的一个Hotfix于2015年5月发布,可在https://support.microsoft.com/en-us/kb/3036169.
对我来说,它看起来像是Windows OS中的一个错误,我有不同的代码变体,该变体使用WIN 8.1/Server 2012R2在2014年4月更新后的Win 8.1/Server 2012R2中使用新的Vista Primitives悬挂。另一些线程池等待功能也挂起。看起来它主要与等待/锁定时的其他线程完成的执行。这是Ntwaitforalertbythreadid()中的调试器下总是悬挂在调试器下的简单代码:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#pragma optimize("",off)
VOID CALLBACK _WorkCallback(PTP_CALLBACK_INSTANCE Instance, PVOID pUser, PTP_WORK Work)
{
for (int i = 0; i < INT_MAX / 256; i++) {}
}
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
for (int i = 0; i < INT_MAX / 256; i++) {}
return 0;
}
#pragma optimize("",on)
int _tmain(int argc, _TCHAR* argv[])
{
LONGLONG c = 0;
while(!_kbhit())
{
PTP_WORK ptpw = CreateThreadpoolWork(&_WorkCallback, NULL, NULL);
if (ptpw != NULL)
{
for(long i = 0; i < 3; i++) SubmitThreadpoolWork(ptpw);
CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
WaitForThreadpoolWorkCallbacks(ptpw, FALSE);
CloseThreadpoolWork(ptpw);
}
printf("%I64d r", c++);
}
_getch();
return 0;
}
不幸的是,我不知道将其报告给Microsoft。
相关文章:
- 为什么我的程序无法在GDB在线编译器/调试器或Visual Studio C++ 2019中运行
- 附加调试器并以编程方式获取变量地址 Visual Studio
- Visual Studio图形调试器引发读取访问冲突异常
- C++ Visual Studio 调试器枚举错误
- 在 Visual Studio 调试器中,如何从内存中打印字节范围?
- 如何在Visual Studio 2017中启动HLSL调试器?
- 按值传递的参数在 Visual Studio 2010, C++ 的调试器中显示为通过引用传递
- 运行调试器Visual Studio时ARGV中的路径
- C++ 从命令行附加 Visual Studio 调试器
- 值传递的参数在 Visual Studio 2015 x64 调试器中显示不正确
- 无法在 Visual Studio 代码中启动 c++ 的调试器
- 在Visual Studio调试器中查看C 智能指针数组的内容
- 节目挂在Visual Studio调试器中
- 无法在Visual Studio C 调试器中查看数组
- 逐步介绍源代码的线路导致Visual Studio调试器退出
- Visual Studio 2013 C++:STL 容器的元素显示在调试器中
- Visual Studio调试器中的cdb命令,如WinDbg
- 找到 Visual Studio 2015 调试器在源不可用时读取符号 defs 的位置
- Visual Studio调试器失败,但程序在生成时运行良好.
- 如何为Visual Studio 2012调试器编写自定义本机可视化工具DLL