c ++ - Hvorfor mister denne kode håndtag på Windows 7 Beta?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg leder efter nogle tilfældige nedbrud i en gammel c ++-applikation. Ved hjælp af sysinternals proces explorer bemærkede jeg app'en, der tabte håndtag og hentede den nøjagtige situation, hvor programmet taber håndtag til et meget kort stykke kode.


DWORD WINAPI MyTestThread( void*  PThread)
{
 \_endthreadex(0);
 return 0;
}

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR  PParameter, int)
{
 for (int i=0;i<10000;i++)
 {
   unsigned int threadID;
   HANDLE hThread= (HANDLE)\_beginthreadex( (void*)NULL, (unsigned int)32768, (unsigned int (\_\_stdcall *)(void *))MyTestThread, (void*)NULL, (unsigned int)0, &threadID);
   WaitForSingleObject((HANDLE)hThread, 1000);
   CloseHandle((HANDLE)hThread);
 }
 return 0;
}


Mit problem: Jeg kan ikke finde ud af, hvad der er galt med denne kode. Det taber præcis 5 håndtag på hver iteration, men det ser OK ud til mig.

Sjovt: Det ser ud til ikke at tabe håndtag på Windows Vista, men jeg er meget overrasket over, om det skulle være en fejl i Windows 7.


[[Opdatering]] Jeg forsøgte at bruge \_beginthread/\_endthread og CreateThread/ExitThread i stedet, de to mister også 5 håndtag ligesom \_beginthreadex.


[[2. Opdatering]] koden kører som forventet. Alle returværdier er gode. Det er 'bare' at miste håndtag som om der ikke er nogen i morgen.


[[3. Opdatering]] Stor ny info Koden taber kun håndtag, hvis de kompileres med/clr! Og mere, hvis jeg kalder GC :: Collect () på hver iteration, vil håndtagene blive genvundet!

Så, hvordan finder jeg hvilke clr-objekter der bliver indsamlet der?

Bedste reference


Kontroller, om nogle DLL'er, der er knyttet til din exe, gør noget mærkeligt i dets DLLMain som svar på DLL\_THREAD\_ATTACH underretninger.

Andre referencer 1


Har du kontrolleret, om funktionerne lykkes? Returværdierne og GetLastError() kunne give nogle tip, hvad der går galt.

Andre referencer 2


Fra http://msdn.microsoft.com/en-us/library/kdzttdcb.aspx[3]


'Hvis det lykkes, returnerer hver af disse funktioner et håndtag til den nyoprettede tråd, men hvis den nyoprettede tråd udløber for hurtigt, kan \_beginthread muligvis ikke returnere et gyldigt håndtag (se diskussionen i afsnittet Bemærkninger). \_Beginthread returnerer -1L på en fejl, i hvilket tilfælde errno er indstillet til EAGAIN, hvis der er for mange tråde, til EINVAL, hvis argumentet er ugyldigt eller stakken er forkert, eller til EACCES i tilfælde af utilstrækkelige ressourcer (f.eks. hukommelse). \_beginthreadex returnerer 0 ved en fejl, i hvilket tilfælde errno og \_doserrno er angivet. '


Din tråd slutter hurtigt, gør det ikke.

Andre referencer 3


Har du forsøgt at teste dette med Win32s CreateThread? Det kunne muligvis indsnævre problemet til CRT.