Niektóre tła: Próbuję śledzić błąd, który powoduje u mnie poważne bóle głowy. Po wielu ślepych zaułków (patrz this question) I wreszcie skończył z tym kodem:Program zawiesza się w debugerze 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;
}
Kiedy uruchomić ten kod wewnątrz VS 2013 debuggera program zawiesza się przy wyjściu jak ten:
....................................................................................................0
....................................................................................................1
....................................................................................................2
...........................
dziwne Wystarczy, że jeśli wstrzymam debuggera i sprawdzę, co się dzieje, jeden z wątków znajduje się wewnątrz AcquireSRWLockExclusive (w NtWaitForAlertByThreadId), najwyraźniej nie ma powodu, dla którego program się zawiesił. Kiedy klikam przycisk "wznów", program z radością kontynuuje i drukuje więcej rzeczy, dopóki nie zostanie ponownie zablokowany.
Czy masz pojęcie, co się tutaj dzieje?
Niektórzy więcej informacji:
- O ile mogę powiedzieć, ten błąd występuje tylko w systemie Windows 8.1.
- Próbowałem VS2013.4 i VS2015 RC.
- Mogę odtworzyć go na dwóch różnych komputerach w systemie Windows 8.1.
- Jedna maszyna została sformatowana, pamięci RAM, procesora i przetestowane Disk (myślałem o awarii, ponieważ na początku nie mogłem tylko obserwować błąd na tej konkretnej maszynie)
- nigdy nie mogłem odtworzyć go na Windows 7.
- Może być przydatne zmodyfikowanie kodu między komentarzami w celu obserwacji błędu. Kiedy dodałem mikrosekundowy sen, mogłem w końcu odtworzyć błąd na innym komputerze.
- Dzięki VS2015 RC mogłem odtworzyć to samo zachowanie przy prostym std :: mutex. W VS2013 jednak SRWLOCK wydaje się obowiązkowy, aby obserwować błąd.
Możliwe, że jesteś w martwym punkcie i po wejściu do debuggera zmienia on synchronizację i zakleszczenie znika. – NathanOliver
@NathanOliver Jak to możliwe? W kodzie jest tylko jeden muteks. – Arnaud
Czy program kiedykolwiek zawiesza się po uruchomieniu poza debuggerem? –