Некоторые предпосылки: Я пытаюсь отслеживать ошибку, которая вызывает у меня серьезные головные боли. После многих тупиков (см this question) я, наконец, в конечном итоге с этим кодом:Программа зависает в отладчике Visual Studio
#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
...........................
странно достаточно. Если я приостанавливаю отладчик и проверяю, что происходит, один из потоков находится внутри AcquireSRWLockExclusive (в NtWaitForAlertByThreadId), по-видимому, нет причин, по которым программа висит. Когда я нажимаю кнопку «возобновить», программа с радостью продолжает и печатает еще несколько вещей, пока она не будет заблокирована снова.
У вас есть идея, что здесь происходит?
Некоторые подробнее:
- Насколько я могу судить, это ошибка существует только на Windows, 8.1.
- Я пробовал VS2013.4 и VS2015 RC.
- Я могу воспроизвести его на двух разных компьютерах под Windows 8.1.
- Один из машины был отформатирован, ОЗУ, процессор и диск испытания (я подумал о неисправности, потому что сначала я мог только наблюдать ошибку на этой конкретной машине)
- Я никогда не мог воспроизвести его на Windows 7.
- Может быть полезно изменить код между комментариями для наблюдения за ошибкой. Когда я добавил микросекундный сон, я мог наконец воспроизвести ошибку на другом компьютере.
- С VS2015 RC я мог бы воспроизвести одно и то же поведение с простым std :: mutex. Однако на VS2013 SRWLOCK кажется обязательным для наблюдения за ошибкой.
Возможно, вы находитесь в тупике, и как только вы входите в отладчик, он меняет синхронизацию, и тупик исчезает. – NathanOliver
@NathanOliver Как это возможно? В коде есть только один мьютекс. – Arnaud
Запускает ли программа когда-либо за пределами отладчика? –