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 :

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);
};
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.

Mais quand je regarde sous OllyDebug, je vois ça:

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
On voit très bien que bTestEmpty est mis sur FALSE avant de remplir bTest.
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 :

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
Mais alors les optimisations pour la taille de ma fonction ne sont pas faites.
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+