30

Bon je viens de télécharger Visual Studio C++ Express pour tester :

- Plus de plantage, j'ai testé 100 boucles de 100 threads et ça termine sans planter
- Mais à la fin de l'exécution, VS m'affiche le message : "Run-Time Check Failure #2 - Stack around the variable 'threads' was corrupted.", donc il y a quand même un soucis quelque part (même si je ne sais pas où)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

31

Tu as donc un débordement sur la pile.. C'est le meme code que cité dans le topic? ou il y a des choses en plus?
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

32

c'est le même code, j'ai juste ajouté les ExitThread / _endthreadex qui vont bien pour terminer les threads proprement (mais j'ai testé sans et le problème apparaît dans les deux cas).
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

33

Et tu ne peux pas utiliser un debugguer ? (je prends un peu le topic en route, désolé sorry)
Y a pas un équivalent de valgrind pour windows ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

34

nop ça plante en passant "à travers" le débuggeur.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

35

C'est-à-dire ? Tu ne peux pas faire du just in time debugging ?

36

réfléchissons: qu'est ce qui peut provoquer un débordement de pile dans ce code?

37

Heu le throw non ? tongue
Je ne connais pas tous les détails de la gestion d'exceptions en C++, mais un throw() dans un thread c'est sensé faire quoi "proprement" ?
A priori, de base il n'y a aucune information (correcte) dans la pile qui lui permette de fonctionner comme il le faut, ou je me trompe ?
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

38

Pen^2 : Bah déjà c'est pas évident à détecter comme bug puisque ça plante "n'importe quand" et que je ne sais pas où placer un breakpoint pour détecter quelque chose (je ne peux pas faire du pas à pas puisqu'il se passe potentiellement des milliers de tour de boucle avant d'avoir un plantage). En plus de ça je ne sais pas s'il y a un vrai outil de débugging sous CodeBlocks mais si je suis obligé de me taper GDB c'est pas gagné :/

GoldenCrystal : Aucune idée, je sais pas comment fonctionne un thread ^^

Sinon par curiosité, si un thread n'est pas censé lancer d'exceptions, on est censé gérer comment le cas d'un constructeur qui échoue ? Parceque j'aurais bien tenté de virer toutes mes exceptions des threads mais je ne peux pas supprimer ceux des constructeurs (et pas question de me retrouver avec des "a = new MyClass (); if (!a.isReady ()) return;" parceque c'est vraiment trop laid :/)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

39

Un thread c'est une fonction appelée avec une pile séparée, et le cpu donne la main a chaque thread a tour de role. un peu comme pour des process, mais dans le même espace mémoire. Normalement quand il y a une exception dans un thread, celui ci le termine, mais là tu l'as mis dans un catch, qui devrait l'intercepter.

A mon avis il faudrait se demander comment marchent les exceptions en C++, si elles marchent pareil entre mingw et vcpp.

(d'ailleurs ça marche comment? y'a du setjmp et co? )

40

Zephyr (./38) :
Pen^2 : Bah déjà c'est pas évident à détecter comme bug puisque ça plante "n'importe quand" et que je ne sais pas où placer un breakpoint pour détecter quelque chose (je ne peux pas faire du pas à pas puisqu'il se passe potentiellement des milliers de tour de boucle avant d'avoir un plantage). En plus de ça je ne sais pas s'il y a un vrai outil de débugging sous CodeBlocks mais si je suis obligé de me taper GDB c'est pas gagné :/

Y a pas un équivalent de valgrind ? pour détecter les accès mémoires foireux, justement ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

41

que fait ce test chez toi, Zephyr?

http://sourceforge.net/mailarchive/forum.php?thread_name=4A0A8E05.2070104%40remedy.nl&forum_name=cegcc-devel

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int a = 0, b = 0, c = 0;
HANDLE h[2];

DWORD thread_fun1(void *param)
{
int i;

printf ("I am %d\n", GetCurrentThreadId ());

for (i=1; i<=9; i++) {
Sleep(700);
a++;
// fprintf(stderr, "Fun1 : %d\n", i);
}
}

DWORD thread_fun2(void *param)
{
int i, *j = NULL;

printf ("I am %d\n", GetCurrentThreadId ());

for (i=1; i<=10; i++) {
Sleep(1000);
b++;
// fprintf(stderr, "Fun2 : %d\n", i);
}
}

main(int argc, char *argv[])
{
int i;
printf ("Starting process with id %d\n", GetCurrentProcessId());
fprintf(stderr, "Start\n");
h[0] = CreateThread(NULL, 0, thread_fun1, NULL, 0, NULL);
h[1] = CreateThread(NULL, 0, thread_fun2, NULL, 0, NULL);

for (i=0; i<10; i++) {
Sleep(500);
c++;
fprintf(stderr, "Main %d %d %d\n", a, b, c);
}
fprintf(stderr, "After for loop\n");

WaitForMultipleObjects(2, h, FALSE, 0xFFFFFFFF);
fprintf(stderr, "Stop\n");
}

si j'étais toi je testerai avec printf puis avec du std::cout

42

squalyl (./41) :
que fait ce test chez toi, Zephyr?

Rien, il compile pas. Si je corrige les erreurs (pas de type de retour pour main, pas de return dans les threads et WINAPI manquant dans leur déclaration) il m'affiche ce qu'il est censé afficher, c'est à dire ça... mais rien de miraculeux dans tout ça, ça ne fait que créer deux threads et les quitter...

Le problème est lié aux exceptions lancées depuis les threads, du coup je ne vois pas à quoi sert ce test ? (cf. post ./11, je n'aurais pas eu besoin de créer un topic pour tester des trucs au pif, ce qui m'intéresse c'est si quelqu'un a une idée de la raison qui provoque ces problèmes).

Pour ce qui est du début à coup de printf / std::cout je ne peux pas : comme expliqué au post ./34 ce n'est pas dans mon code que se déclenche le bug.

Flanker : pas à ma connaissance sous Windows (si quelqu'un connait je suis preneur)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

43

ok on va attendre les spécialistes du traitement des exceptions en C++ parce que dans ce cas ça me dépasse.

44

Je pense que tu as tout simplement dépassé le maximum de threads possible, qui en général se calcule par (taille totale réservée pour la pile de ton programme) / (taille de la pile par thread). Donc il commence à écrire n'importe où sur la pile du programme et donc à corrompre le contenu de la pile (pas très intelligent, les systèmes d'exploitation mieux conçus arrêtent le programme avec un segfault, mais peu importe).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

45

Kevin Kofler (./44) :
tu as tout simplement dépassé le maximum de threads possible
Non.
Kevin Kofler (./44) :
il commence à écrire n'importe où sur la pile du programme et donc à corrompre le contenu de la pile
Non plus.
If a process grows its stack into the stack guard page, the unhandled exception filter catches the guard exception and extends the stack.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

46

Merci pour les liens Zerosquare smile (même si du coup le problème reste entier grin)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

47

Zephyr (./42) :
Flanker : pas à ma connaissance sous Windows (si quelqu'un connait je suis preneur)

erf :/ (mais j'avoue que ça m'étonne un peu, c'est pourtant un truc de base pour débugguer :/ )
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

48

il y a avec visual studio, mais je suis pas sur que ça soit gratuit
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

49

Zerosquare (./45) :
Kevin Kofler (./44) :
tu as tout simplement dépassé le maximum de threads possible
Non.

Euh, l'article dit la même chose que moi, à savoir: "qui en général se calcule par (taille totale réservée pour la pile de ton programme) / (taille de la pile par thread)".
Kevin Kofler (./44) :
il commence à écrire n'importe où sur la pile du programme et donc à corrompre le contenu de la pile
Non plus.
If a process grows its stack into the stack guard page, the unhandled exception filter catches the guard exception and extends the stack.

Cet article-là est valable pour un processus à une seule pile, donc à un seul thread. Ce n'est pas valable pour les piles par thread! Il n'y a pas de "guard page" qui peut magiquement extendre la pile dans ce cas (cf. l'autre article pour voir qu'un thread utilise au minimum une page de RAM, pas 2, de plus, il n'y a pas l'espace d'adressage dans lequel grandir la pile du thread). Cela dit, ce que j'ai dit est probablement faux aussi: apparemment CreateThread échoue s'il n'y a plus de place sur la pile (cf. encore le premier article), ça ne devrait pas corrompre la pile.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

50

Zephyr (./38) :
Pen^2 : Bah déjà c'est pas évident à détecter comme bug puisque ça plante "n'importe quand" et que je ne sais pas où placer un breakpoint pour détecter quelque chose (je ne peux pas faire du pas à pas puisqu'il se passe potentiellement des milliers de tour de boucle avant d'avoir un plantage). En plus de ça je ne sais pas s'il y a un vrai outil de débugging sous CodeBlocks mais si je suis obligé de me taper GDB c'est pas gagné :/


Pas le temps de lire les autres messages, mais dans mon esprit, du JIT Debugging c'est : tu compiles avec les infos de debug, tu laisses tourner le programme, et quand il plante ça lance le debuggueur sur la ligne qui pose problème.

J'ai réussi à en faire avec GDB (enfin avec Insight pour être plus précis).

J'avais besoin de simuler un ASSERT(false) de VS en fait, pour débugguer une DLL qui était lancée depuis du Java/JNI, lui même lancé dans une JVM lancée depuis du Java J2EE exécuté sur un serveur qui se trouve être un Fedora 5 virtualisé lancé sur ma machine trioui
J'avais ouvert un topic pour ça. Je vais le chercher.

51

52

Oui mais comme je l'ai déjà expliqué, au moment où ça plante l'endroit où l'exécution en est par rapport à mon code n'a aucune importance (en même temps il y a 2 boucles for, un throw et un catch dans mon code donc c'est vite vu). C'est probablement une histoire de mémoire, mais la ligne qui déclenche le plantage est quelque part dans le code du système, pas dans le mien, donc je ne peux pas le voir et encore moins déclencher un débuggeur dessus.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

53

squalyl (./39) :
A mon avis il faudrait se demander comment marchent les exceptions en C++, si elles marchent pareil entre mingw et vcpp.

(d'ailleurs ça marche comment? y'a du setjmp et co? )

C'est différent. Je sais que Visual base les exceptions C++ sur le SEH (une exception C++ est juste une exception Win32 avec un code particulier), et je me souviens avoir déjà posé la question sur ce forum à propos de gcc: À moins que ma mémoire me fasse défaut, Dbl-K m'a répondu que gcc utilisait un truc à base de setjmp.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

54

C'est setjmp par défaut, et il y a des versions compilées avec DWARF2 (mais le problème, c'est que ça ne marche (marchait?) pas à travers les DLLs).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

55

le truc qui est "marrant", c'est qu'en faisant comme ce qu'il suit, ça ne plante plus. (j'ai un processeur multicore, comme la plupart d'entre vous sans doute)
Sur un ordinateur monocoeur, la version sans SetThreadAffinityMask ne plante jamais.

Par contre je n'est pas d'explications...
source
#include <iostream> 
#include <map> 
#include <windows.h> 
 
struct	MyException {}; 
 
DWORD WINAPI	MyCallback (LPVOID)
{ 
	try 
	{ 
		throw MyException (); 
	} 
	catch (MyException& e) 
	{ 

	} 
 
	return 0; 
} 

int	main() 
{ 
	const int		count = 100; 
	std::map<int, HANDLE>	threads; 
	DWORD			id; 

	for (int j = 0; j < 100; ++j)
	{	 
		for (int i = 0; i < count; ++i) 
			threads[i] = CreateThread (NULL, 0, &MyCallback, 0, CREATE_SUSPENDED, &id); 
	 

		for (int i = 0; i < count; ++i)
			SetThreadAffinityMask(threads[i], 1);
	 
		for (int i = 0; i < count; ++i) 
			ResumeThread (threads[i]); 
	 
		for (int i = 0; i < count; ++i)
		{
			WaitForSingleObject( threads[i], INFINITE);
			CloseHandle(threads[i]);
			threads[i] = NULL;
		}
	}
 
	return 0; 
}

avatar

56

apparemment y'a des problèmes d'exceptions avec mingw, je vois bcp de gens qui s'en plaignent sur la liste cegcc-devel (gcc/migw pour wince)

ok c'est de l'arm mais ça confirme que c'est pas tout rose les exceptions gcc/mingw