Bonjour,
J'ai rencontré récement un problème avec Visual Studio.
En effet, quand je compile ma source, Visual ne respecte pas l'ordre des variables, ce qui me pose problème en multithreading (race condition).
Voici un simple exemple :
Donc logiquement, si l'ordre est respecté, c'est à dire que "bTest" est remplie avant que "bTestEmpty" soit mis sur FALSE, ça ne pose aucun problème pour le multithreading.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 BOOL FuncTest() { static BOOLEAN bTestEmpty = TRUE; static BOOL bTest; DWORD dwTest; if (bTestEmpty == TRUE) { /* ICI, du code qui utilise dwTest ... */ bTest = ((dwTest) ? TRUE : FALSE); // Remplie bTest avec la bonne valeur bTestEmpty = FALSE; // Met bTestEmpty sur FALSE pour dire que le test a déjà été fait } return (bTest); };
Mais quand je regarde sous OllyDebug, je vois ça:
On voit très bien que bTestEmpty est mis sur FALSE avant de remplir bTest.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 10010D0F CMP BYTE PTR DS:[1002E206],1 // if (bTestEmpty == TRUE) 10010D16 JNE SHORT 10010D46 // ICI // DU CODE QUI UTILISE dwTest 10010D34 CMP DWORD PTR SS:[ESP],EAX 10010D37 MOV BYTE PTR DS:[1002E206],0 // bTestEmpty = FALSE; 10010D3E SETNE AL 10010D41 MOV DWORD PTR DS:[10032784],EAX // bTest = ((dwTest) ? TRUE : FALSE); 10010D46 MOV EAX,DWORD PTR DS:[10032784] // return (bTest); 10010D4B POP ECX 10010D4C RETN
Ce qui produit une Race Condition (Si plusieurs threads utilisent la fonction au même moment).
Je compile mon code avec "Optimization: Minimize Size (/O1)"
Donc ça doit être pour ça que l'ordre des variables n'est pas respecté.
Si je rajoute #pragma optimize("", off) avant et #pragma optimize("", on) après ma fonction, ça corrige le problème :
Mais alors les optimisations pour la taille de ma fonction ne sont pas faites.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 10010D12 MOVZX EAX,BYTE PTR DS:[1002E206] // if (bTestEmpty == TRUE) 10010D19 CMP EAX,1 10010D1C JNE SHORT 10010D4D // ICI // DU CODE QUI UTILISE dwTest 10010D41 MOV DWORD PTR DS:[10032784],EAX // bTest = ((dwTest) ? TRUE : FALSE); 10010D46 MOV BYTE PTR DS:[1002E206],0 // bTestEmpty = FALSE; 10010D4D MOV EAX,DWORD PTR DS:[10032784] // return (bTest); 10010D52 LEAVE 10010D53 RETN
Alors oui, ce n'est pas grave si je désactive les optimisations pour cette fonction mais j'ai plusieurs fonctions ou je fais se genre de manip.
Donc ma question est :
Il y a t'il une solution pour que l'ordre des variables soient respectée tout en laissant les optimisations activées ?
Merci d'avance !
A+
Partager