IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

DialogBoxParam et EndDialog consomme de la mémoire ?


Sujet :

Windows

  1. #1
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 14
    Points
    14
    Par défaut DialogBoxParam et EndDialog consomme de la mémoire ?
    Bonjour,
    Je viens de m'apercevoir qu'aprés avoir ouvert et fermé une boite de dialogue (qui me sert de progress bar) de multiple fois, que mon état mémoire disponible va en diminuant ???

    Je l'ouvre via la Cde DialogBoxParam et j'en sort via ma DlgProc et la fonction EndDialog .... Avez vous déjà vu ce genre de défaut. Il est vrai qu'il faut l'ouvrir et la fermer un paquet de fois pour s'en apercevoir, mais dans mon cas, des progress Bar peuvent s'afficher plusieurs centaines de fois par jour et quelquefois me lancer le message "Memory full ...."
    Merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2006
    Messages : 507
    Points : 705
    Points
    705
    Par défaut
    Citation Envoyé par theoldisgood
    Avez vous déjà vu ce genre de défaut?
    Pour avoir déjà critiqué des bibliothèques "sérieuses", en général, si bug il y a, il est dans ton programme et non dans la bibliothèque... N'oublies-tu pas de faire une (des) libération(s) de mémoire ??? Attention, les fuites de mémoires sont parfois bien cachées, et c'est un connaisseur qui te le dit!!!

  3. #3
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Fabllot
    Pour avoir déjà critiqué des bibliothèques "sérieuses", en général, si bug il y a, il est dans ton programme et non dans la bibliothèque... N'oublies-tu pas de faire une (des) libération(s) de mémoire ??? Attention, les fuites de mémoires sont parfois bien cachées, et c'est un connaisseur qui te le dit!!!
    A part les APIs citées, je n'utilise pas de malloc ...

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Poste un code compilable et minimal qui montre le problème.

  5. #5
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Médinoc
    Poste un code compilable et minimal qui montre le problème.
    Voila, c'est déjà un bout de code que j'ai piqué sur ce site. Il faut en même temps lancer le "Gestionnaire des tâches" sur l'onglet "performance" ou afficher l'état de la mémoire par "GlobalMemoryStatus" et on peut voir la mémoire diminuer petit à petit ....

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    #include <windows.h>
    #include <Commctrl.h>
    #include "resource.h"
    
    #define IDT_TIMER 10
    
    HINSTANCE  hInst;
    HWND       hWnd;
    FARPROC    lpfnOldWndProc;
    
    int compteurdepassage=0;
    int Increment=0;
    
    LONG FAR PASCAL SubClassFunc(HWND hwnd, WORD Message, WORD wParam, LONG lParam)
    {
    	if (Message == WM_PAINT)
    	{
    		HDC           hDC;
    		PAINTSTRUCT   ps;
    		RECT          ClientRect, LeftRect, RightRect;
    		char          szTexte[30];
    		HRGN          hRgn;
    
    		DWORD dwTextStyle = DT_CENTER | DT_VCENTER | DT_SINGLELINE;
    		int nPos = (int)SendMessage(hwnd, PBM_GETPOS, 0, 0);
    		COLORREF crBarColour = GetSysColor(COLOR_HIGHLIGHT);
    		COLORREF crBgColour  = GetSysColor(COLOR_WINDOW);
    		
    		GetClientRect(hwnd, &ClientRect);
    		LeftRect = RightRect = ClientRect;
    		int D = LeftRect.right - LeftRect.left;
    		LeftRect.right = LeftRect.left + (int)((D * nPos) / 100);
    		RightRect.left = LeftRect.right;
    		
    		hDC = BeginPaint(hwnd, &ps) ;
    
    		// Dessiner la bar
    		FillRect(hDC, &LeftRect, (HBRUSH)CreateSolidBrush(crBarColour));
    		FillRect(hDC, &RightRect, (HBRUSH)CreateSolidBrush(crBgColour));
    
    		// Afficher le texte
    		wsprintf(szTexte, "ATTENTE : %d%%", nPos);
    		SetBkMode(hDC, TRANSPARENT);
    		// Le blanc
    		hRgn = CreateRectRgn(LeftRect.left, LeftRect.top, LeftRect.right, LeftRect.bottom);
    		SelectClipRgn(hDC, hRgn);
    		SetTextColor(hDC, crBgColour);
    		DrawText(hDC, szTexte, (int)lstrlen(szTexte), &ClientRect, dwTextStyle);
    		// Le bleu
    		DeleteObject(hRgn);
    		hRgn = CreateRectRgn(RightRect.left, RightRect.top, RightRect.right, RightRect.bottom);
    		SelectClipRgn(hDC, hRgn);
    		SetTextColor(hDC, crBarColour);
    		DrawText(hDC, szTexte, (int)lstrlen(szTexte), &ClientRect, dwTextStyle);
    		
    		EndPaint (hwnd, &ps) ;
    		return TRUE;
    	}
    
       if (Message == WM_GETDLGCODE) //Bloque les touches clavier (enter)
           return DLGC_WANTALLKEYS;
    
       return CallWindowProc((WNDPROC)lpfnOldWndProc, hwnd, Message, wParam, lParam);
    }
    
    
    
    LRESULT CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {	
    	switch (message)
    	{
    		case WM_INITDIALOG:
    			{ 
    				Increment = 3000/10;
    				SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
    				SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETSTEP, (WPARAM) 10, 0);
    				lpfnOldWndProc = (FARPROC)SetWindowLong(GetDlgItem(hDlg, IDC_PROGRESS1), 
    					GWL_WNDPROC, (DWORD) SubClassFunc);
    				SetTimer(hDlg, IDT_TIMER, Increment, NULL); 
    			}
    			break;
    		
    		case WM_TIMER:
    			if(wParam == IDT_TIMER)
    			{
    				SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_STEPIT, 0, 0);
    				compteurdepassage ++;
    				if(compteurdepassage >= 10)
    				{
    					KillTimer(hDlg,IDT_TIMER);
    					EndDialog(hDlg, FALSE);
    				}
    				return TRUE;
    				break;
    			}
    
    		case WM_COMMAND:
    			break;
    	}
        return FALSE;
    }
    
    
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	int i;
    
    	InitCommonControls();
    	for(i=0;i<10;i++)
    	{
    		Sleep(500);
    		compteurdepassage=0;
    		Increment=0;
    		DialogBox(hInstance, (LPCTSTR)IDD_DIALOG, NULL, (DLGPROC)DlgProc);
    	}
    	return 1;
    }

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Code obsolète (surtout au niveau du prototype de la DialogProc) et loin d'être minimal : Il y a des créations d'objets GDI, qui ne sont peut-être pas correctement détruits (fuite de ressources)...

  7. #7
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Je crois surtout que l'erreur est dans ta maniere de mesurer cette perte memoire. La seule chose a laquelle tu peux a peu pres te fier est la valeur "Taille MV" de ton process.

  8. #8
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    J'ai le même défaut lorsque je détruit la DlgBox pendant la phase d'initialisation !!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    case WM_INITDIALOG:
    	{ 
    	EndDialog(hDlg, FALSE);
    	....
    Et dans ce cas, je ne lance aucun objet GDI !!

    Ma mesure de mémoire n'est peut ètre pas génial, mais une chose est sur, ça plante au bout d'un certain temps ... Même avec ce code (ci dessus) minimisé.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Peux-tu poster le code minimal?

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    et detailler le "ca plante" et verifier que ton process consomme bien de + en + de memoire.

  11. #11
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    J'ai du mal à vous suivre

    Donc le code minimal c'est le même que le premier au complet, mais avec l'insertion de EndDialog(....) dans le WM_InitDialog puis return TRUE;

    Pour le code erreur, en fait je lance l'affichage d'un BMP entre mes fenêtres de dialog (ce code ne figure pas, pour ne pas alourdir la compréhension).
    Puis au moment ou ma mémoire devient full (environ 3/4h), un popup apparait m'indiquant qu'il ne trouve pas le BMP (normal il n'a pas pu le charger vu le manque de mémoire).

    Pas facile d'expliquer cela sans le code ... mais si je n'affiche pas cette DialogBox, le programme tourne à l'infini sans défaut.

    et detailler le "ca plante" et verifier que ton process consomme bien de + en + de memoire.
    Quelle est la procédure pour voir l'état de mon process avec VC++ v6.0

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Ce n'est pas un code minimal.
    Dans un code minimal, tu retire TOUT le reste du code. Y compris ton subclassing et ton timer. Et ce, jusqu'à ce qu'il n'y ait plus rien à enlever.

  13. #13
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Médinoc
    Ce n'est pas un code minimal.
    Dans un code minimal, tu retire TOUT le reste du code. Y compris ton subclassing et ton timer. Et ce, jusqu'à ce qu'il n'y ait plus rien à enlever.
    D'accord mais si je ne passe pas dedans, ça reviens au même

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Test minimal, avec une boîte de dialogue toute simple (juste les deux boutons OK et Cancel) :
    Code C++ : 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    // TestDlg.cpp : Defines the entry point for the console application.
    //
     
    #include "stdafx.h"
    #include "resource.h"
     
    static INT_PTR CALLBACK AutoEndDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    	INT_PTR bRet = TRUE;
    	(void)wParam;
    	(void)lParam;
     
    	switch(uMsg)
    	{
    	case WM_INITDIALOG:
    		EndDialog(hWnd, 42);
    		break;
    	default:
    		bRet = FALSE;
    		break;
    	}
    	return bRet;
    }
     
    int _tmain(void)
    {
    	HINSTANCE hInst = GetModuleHandle(NULL);
    	unsigned int cpt = 0;
     
    	while(!_kbhit())
    	{
    		INT_PTR ret = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, AutoEndDialogProc, 0);
    		cpt++;
    		printf("Resultat %u : %d\n", cpt, (int)ret);
    		//Sleep(500);
    	}
    	return 0;
    }
    Après 100000 itérations, j'ai pu constater une augmentation progressive de "l'utilisation mémoire" de 1800k à 1832k, par tranches de 4k.
    Par contre, la "taille de la mémoire virtuelle" est restée stable à 472k.

    Donc, à moins d'une erreur dans mon code, on peut en effet soupçonner une fuite, vu l'augmentation mémoire...

  15. #15
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par theoldisgood
    Pour le code erreur, en fait je lance l'affichage d'un BMP entre mes fenêtres de dialog (ce code ne figure pas, pour ne pas alourdir la compréhension).
    A mon avis, la fuite est dans ce code BMP.

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    J'ignore si ce sont les seules, mais je viens d'en trouver deux belles:
    Code faux : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    		FillRect(hDC, &LeftRect, (HBRUSH)CreateSolidBrush(crBarColour));
    		FillRect(hDC, &RightRect, (HBRUSH)CreateSolidBrush(crBgColour));
    D'ailleurs, pourquoi ces casts ?

  17. #17
    Membre actif Avatar de Nyarlathotep
    Profil pro
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    174
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 174
    Points : 217
    Points
    217
    Par défaut
    C'est normal si tu ne détruits pas la seconde Région ?
    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
    hRgn = CreateRectRgn(LeftRect.left, LeftRect.top, LeftRect.right, LeftRect.bottom);
    SelectClipRgn(hDC, hRgn);
    SetTextColor(hDC, crBgColour);
    DrawText(hDC, szTexte, (int)lstrlen(szTexte), &ClientRect, dwTextStyle);
    // Le bleu
    DeleteObject(hRgn);
    
    
    hRgn = CreateRectRgn(RightRect.left, RightRect.top, RightRect.right, RightRect.bottom);
    SelectClipRgn(hDC, hRgn);
    SetTextColor(hDC, crBarColour);
    DrawText(hDC, szTexte, (int)lstrlen(szTexte), &ClientRect, dwTextStyle);
    
    //Et le 2nd DeleteObject ???

  18. #18
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    En general les fuites gdi ne saturent pas la memoire mais plutot le stock d'objets GDI ce qui provoque des bugs graphiques bizares, a l'echelle de l'OS parfois. Donc je pense qu'il y a aussi des fuites de memoire en plus des GDI leaks...

  19. #19
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    Citation Envoyé par Médinoc
    Test minimal, avec une boîte de dialogue toute simple (juste les deux boutons OK et Cancel) :
    Après 100000 itérations, j'ai pu constater une augmentation progressive de "l'utilisation mémoire" de 1800k à 1832k, par tranches de 4k.
    Par contre, la "taille de la mémoire virtuelle" est restée stable à 472k.

    Donc, à moins d'une erreur dans mon code, on peut en effet soupçonner une fuite, vu l'augmentation mémoire...
    J'ai vu aussi des incréments par 4K, mais ça va beaucoup + vite que toi. Quelques centaines d'itérations suffisent....

    A mon avis, la fuite est dans ce code BMP.
    J'ai viré l'affichage du BMP et le résultat est le même. En fait dés le départ, je pensais que ça provenait de lui ... sans succés.

  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    J'ai refait un test de mon programme minimal :
    L'utilisation mémoire indiquée était différente (plus de 1900k dès le début), donc de fiabilité douteuse. Par contre, la taille VM est restée à 472k, et les comptes d'objets USER et GDI oscillaient respectivement de 0 à 3 et de 8 à 9.

Discussions similaires

  1. Comment reduire la consommation de la mémoire vive
    Par souarit dans le forum Débuter
    Réponses: 3
    Dernier message: 27/12/2008, 20h37
  2. Applet qui consomme de la mémoire. Que faire ?
    Par kmdkaci dans le forum Applets
    Réponses: 3
    Dernier message: 06/11/2008, 16h09
  3. Une lecture de fichier midi qui consomme trop de mémoire
    Par padodanle51 dans le forum Général Java
    Réponses: 6
    Dernier message: 12/04/2008, 11h52
  4. [Images] Erreur liée à une consommation excessive de mémoire
    Par cyrill.gremaud dans le forum Bibliothèques et frameworks
    Réponses: 15
    Dernier message: 04/11/2007, 22h55
  5. Réponses: 5
    Dernier message: 02/03/2007, 08h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo