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

Langage Delphi Discussion :

Les exceptions feraient des fuites mémoire?


Sujet :

Langage Delphi

  1. #1
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut Les exceptions feraient des fuites mémoire?
    Bonjour,

    je développe un logiciel de contrôle d'un automate, logiciel qui doit tourner plusieurs semaines d'affilées.
    Mon dernier soucis est qu'au bout de quelques jours, il a pris de l'embonpoint, passant de 9Mo à son lancement à plus de 100Mo.
    Pourtant chaque procédure, chaque fonction est testée unitairement et chaque test unitaire vérifie qu'il n'y a pas de fuite mémoire. Par contre du fait du matériel qui n'est pas très stable l'application génère un flot d'exceptions assez conséquent. Le journal texte de ces exceptions n'est pas gardé en mémoire mais écrit sur disque.

    J'ai fait un petit programme pour vérifier, et effectivement la mémoire qu'il utilise augmente de 4 ou 8 ko de temps en temps... (surveillés avec le gestionnaire des tâches Windows)
    C'est une form CLX vide avec juste un bouton, que je presse plusieurs fois avant de laisser tourner quelques dizaines de minutes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      while true do begin
        Application.ProcessMessages;
        try
          raise Exception.Create('coucou');
        except
          on E:Exception do Nb := Nb + 1;
          end;
        end;
      end;
    Dernier test, au démarrage j'avais 6472 ko, et 10 mn plus tard 6524 ko.

    Si quelqu'un a une idée, ça m'intéresse fortement.
    Merci
    Cédric

  2. #2
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut
    Je précise, les hausses de l'utilisation mémoire se produisent surtout quand je re-clique sur le bouton alors que la fonction tourne déjà.
    Une sorte de double-exception presque simultanée qui peut se produire dans mon appli en fait.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut
    Autre point, le même programme de test en VCL
    - prend trois fois moins de mémoire au démarrage
    - augmente de temps en temps la mémoire utilisée comme l'autre
    - redescend parfois brusquement à 580ko utilisé (ce que ne fait jamais l'autre)

    Y'aurait-il dans la VCL un nettoyage de certains blocs mémoires qui aurait été oublié dans la CLX?
    Sinon je viens d'ajouter MemCheck à mon projet, on va voir s'il trouve des trucs.

  4. #4
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Vu que tu crées une exception Exception.Create('coucou'); cela pourrait venir de la.

    As tu essayé sans la création pour voir ?

    PS: il existe une fonction Editer que tu aurais pu utiliser au lieu de faire 3 post d'affiliés
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  5. #5
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut
    Certes, mais mon problème est bien là : mon application génère des exceptions, c'est quelque chose d'assez banal malheureusement et je n'y peux rien.
    Par contre je trouve anormal qu'une exception gérée perde de la mémoire ainsi, d'autant plus que cela semble ne touche que l'appli CLX, pas l'appli VCL qui a un comportement type garbage collector.

    ps: pour gérer moi même un forum, et en tant que simple lecteur, je trouve qu'un énorme message est indigeste à lire, mais j'y penserai.

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 530
    Points : 25 063
    Points
    25 063
    Par défaut
    Bon, j'ai fait bcp de programmes automates, je n'avais pas de fuite mémoire mais bcp d'erreur de page à cause des TList, je n'avais pas non plus bcp d'exception ...

    as-tu testé sans application.processmessages (qui ne sert pas à grand chose puisque boucle infini, surement pour le close de la forme, quoi que, est-ce que cela arrête la boucle ? non) ... car le petit processmessages, lance le traitement des messages windows et delphi, ce qui peut donner parfois de l'occupation mémoire ...

    sinon, les chaines, c'est une GROSSE chiasse en Delphi 4-5, cela été amélioré en 7, puis qu'un nouveau gestionnaire mémoire a été mis (cela se ressent sur le thread), dans mon ancienne boite, on était en delphi 5 et le programmeur que notre équipe remplaçait (ouais 3 personne pour 1 ... c'était un génie), et bien, il avait écrit son propre MemoryManager, qui est en fait une ancienne version parallèle de FastMM ...

    Je précise, les hausses de l'utilisation mémoire se produisent surtout quand je re-clique sur le bouton alors que la fonction tourne déjà.
    Une sorte de double-exception presque simultanée qui peut se produire dans mon appli en fait.
    j'avais pas vu ça ! biensur ! empilement d'appel de procédure ... mais pour en faire autant, tu dois cliquer bcp, j'ai fait le teste, je monte aussi en mémoire (je le vois avec le pauvre Gestionnaire d'XP, et sinon je mesure avec GetHeapStatus qui ne donne que 4 d'écart à chaque coup, pour le pointeur de quelque chose)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Clic 1
      - ProcessMessages - Traitement Event
      - Clic 2
        - ProcessMessages - Traitement Event
        - Clic 3
           - ...
    Dans tes boucles, c'est le dernier exécuté qui prend la main, hors ProcessMessages n'a pas fini de bosser, donc ses propres consommations ne sont pas libérés ... Malatar tu confirmes ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Bonjour,
    ton programme de test risque de faire déborder la pile (comme l'a remarqué ShaiLeTroll)
    Citation Envoyé par cedricgirard
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      while true do begin
        Application.ProcessMessages;
        try
          raise Exception.Create('coucou');
        except
          on E:Exception do Nb := Nb + 1;
          end;
        end;
      end;
    Avec la boucle infinie, tu ne sors jamais d'un appel à TForm1.Button1Click, même si Application.ProcessMessages permet de traiter les messages en attente. Si un Button1Click se produit Application.ProcessMessages va le traiter et ne rendra jamais la main (la pile grossie). Si tu stoppes l'application après plusieurs cliques, la pile que tu obtiendras sera du type :
    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
    //-------- haut de la pile --------- //
    TForm1.Button1Click(Sender);  // dernier clique
    ...
    Application.ProcessMessages;
    ...
    TForm1.Button1Click(Sender);
    ...
    Application.ProcessMessages;
    ...
    TForm1.Button1Click(Sender);
    ...
    Application.ProcessMessages;
    ...
    TForm1.Button1Click(Sender); // 3eme clique
    ...
    Application.ProcessMessages;
    ...
    TForm1.Button1Click(Sender); // 2eme clique 
    ...
    Application.ProcessMessages;
    ...
    TForm1.Button1Click(Sender);  // 1er clique 
    ...
    //-------- bas de la pile --------- //

  8. #8
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Essaie plutôt avec OnIdle :
    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
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        Nb : integer;
        procedure Idle(Sender: TObject; var Done: Boolean);
      end;
     
    var
      Form1: TForm1;
     
    implementation
    {$R *.dfm}
    procedure TForm1.Button1Click(Sender: TObject);
    begin
       ShowMessage( IntToStr( Nb ) );
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
       Nb := 0;
       Application.OnIdle := Idle;
    end;
     
    procedure TForm1.Idle(Sender: TObject; var Done: Boolean);
    begin
        try
          raise Exception.Create('coucou');
        except
          on E:Exception do Nb := Nb + 1;
        end;
        Done := false; // Continuer à appeler Idle
    end;
    Comme tu utilise la CLX, je suppose que la version de ton Delphi doit être 7 ou moins. Sinon tu aurais pu essayer avec le nouveau Gestionnaire Mémoire de Delphi (qui permet aussi de traquer les fuites mémoires ).

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 530
    Points : 25 063
    Points
    25 063
    Par défaut
    Effectivement gb_68, empilement de boucle ... d'où l'a consommation mémoire ... mais son programme n'est qu'un exemple, il serait bien qu'il revienne nous fournir un code plus concret, il est possible qu'il ai mis des Application.ProcessMessages maladroit ... par exemple dans un gestionnaire d'event socket (ou port de communication avec le matériel)

    D'ailleurs, un matériel non stable ne provoque pas d'exception normalement ?!Comment est faite la communication (dll driver, direct via port, carte de bus de terrain, carte d'acquisition, ... ) ??
    Soit ça plante totalement (écran bleau et autre)
    Soit cela renvoi des codes d'erreur non ?
    sauf si encapsulation dans un ActiveX/COM d'un pilote ce qui renvoit effectivement des EOleError ...

    sinon, vive le OnIdle, je l'utilise souvent en direct (pour tous les flush dans les programmes automate ou par l'intermédaire du Synchronize dans mes threads (tu me corrige gb_68, si je dis des bétises) mais le OnIdle est lancé avant le CheckSynchronize (fonction qui va lancé la procédure passée en paramètre de Synchronize), d'ailleurs cet ordre de lancement est pratique pour corriger le contexte (variables globales) car il est triste que Synchronize ne puisse pas accepter de paramètre (un petit pointer par exemple) ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut
    Je reviens. Désolé pour le retard de réaction, mais j'ai depuis quitté la boite où j'avais ce soucis. Il me sera donc difficile de continuer l'exploration.

    Il est possible que mon programme de test reproduise fort mal le problème réel, mais il reste quelques faits :
    - un programme Delphi CLX Windows qui fait des fuites mémoires alors que son code est entièrement testé contre cela. Plus il y a d'exceptions, et plus les fuites sont importantes
    - le programme de test mentionné ici version CLX perd de la mémoire, alors que la version VCL la perd et la retrouve d'un coup, genre un garbage collector qui s'occuperait de trucs qui traînent.

    Merci pour vos réponses, ce fut instructif malgré que le problème demeure.

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 530
    Points : 25 063
    Points
    25 063
    Par défaut
    @gb_68, Malatar
    Pour dire à quel point le monde est petit, Cedric a rejoind ma Boite
    Et il n'est pas près de se poser autant de question en fuite mémoire, ... c'est pas les Exception qui fuit mais les DataSet et Form qui reste toujours dans les coins sombres ...

    Sinon, quelques comprend la directive PC_MAPPED_EXCEPTIONS, car entre les différences de gestion des exceptions entre Windows et Linux, ce truc là n'aide pas à comprendre ... déjà entre

    d'ailleurs, lorsque PC_MAPPED_EXCEPTIONS est défini ne peut pas utilisé EAbstractError
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  12. #12
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    La directive PC_MAPPED_EXCEPTIONS indique si la RTL gère les exceptions par elle-même (par opposition à des exceptions gérées par l'OS).

    Sous Windows, il existe un mécanisme géré par l'OS d'exceptions. Donc la directive n'est pas définie. En revanche, sous Linux, elle l'est.

    Par contre, pas compris ce que tu voulais dire sur les EAbstractError
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  13. #13
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 530
    Points : 25 063
    Points
    25 063
    Par défaut
    ok, pour PC_MAPPED_EXCEPTIONS, c'est ce que j'avais plus ou moins compris, qu'il y avait une histoire de mapping auto ... mais en Delphi, on ne l'utlise jamais non ? quelques API tel que RaiseException de Windows sont utilisés, mais cela utilise surtout la dll de borland pour l'inclure dans les routines normal des exception, et pour Linux, il fait la même chose avec le fichier '.so'

    On voit qu'il y a quelques traitements uniquement fait pour Windows ou pour Linux, la fuite, doit venir du fait que les exceptions sont empilés quelques part sous Linux (pour le Dump) et que sous Windows, une fois capturé, il l'oublie ...

    Sinon sur ma machine, PC_MAPPED_EXCEPTIONS n'est pas défini car je ne pourrais pas avoir de EAbstractError ... type que j'utlise dans ma classe abstraite pour gérer une exception qui provient d'une non-implementation d'une méthode devant être surchargé ...

    Pour EAbstractError, la déclaration de ce type est comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    {$IFNDEF PC_MAPPED_EXCEPTIONS}
      EAbstractError = class(Exception) end platform;
    {$ENDIF}
    C'est étrange non ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  14. #14
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    mais en Delphi, on ne l'utlise jamais non ?
    En effet, c'est ce que j'ai dit : cette constante est définie exclusivement sous Linux (Kylix).
    Citation Envoyé par ShaiLeTroll Voir le message
    quelques API tel que RaiseException de Windows sont utilisés, mais cela utilise surtout la dll de borland pour l'inclure dans les routines normal des exception, et pour Linux, il fait la même chose avec le fichier '.so'

    On voit qu'il y a quelques traitements uniquement fait pour Windows ou pour Linux, la fuite, doit venir du fait que les exceptions sont empilés quelques part sous Linux (pour le Dump) et que sous Windows, une fois capturé, il l'oublie ...
    Là je ne te comprends pas très bien Les exceptions sont un mécanisme universalisé qui sont gérées par l'OS sous Windows. Des informations sur les gestionnaires d'exceptions en cours sont enregistrer dans les informations locales aux threads : c'est le structured exception handling (SEH).

    Les exceptions ne peuvent être empilées. Si une exception survient dans le gestionnaire d'une autre (pendant l'unwind) : c'est l'arrêt brutal du programme.

    Ce qui peut être empilé, ce sont les gestionnaires d'exceptions (les try..except et les try..finally). Et ça c'est grâce au SEH, et ça fonctionne très bien sous Windows.

    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon sur ma machine, PC_MAPPED_EXCEPTIONS n'est pas défini car je ne pourrais pas avoir de EAbstractError ... type que j'utlise dans ma classe abstraite pour gérer une exception qui provient d'une non-implementation d'une méthode devant être surchargé ...

    Pour EAbstractError, la déclaration de ce type est comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    {$IFNDEF PC_MAPPED_EXCEPTIONS}
      EAbstractError = class(Exception) end platform;
    {$ENDIF}
    C'est étrange non ?
    Quand on fouille un peu (et qu'on sait où fouiller), on comprend vite que c'est normal, et prévu. Lorsque tu appelles une méthode abstraite, il n'est pas déclenché immédiatement une EAbstractError. C'est d'abord la routine @AbstractError qui est appelée.

    Celle-ci consulte la variable AbstractErrorProc, déclarée dans System. Si elle est renseignée, la procédure pointée est appelée. Si pas, une runtime error 210 est déclenchée.

    L'unité SysUtils renseigne cette variable dans son code d'initialisation, mais seulement si PC_MAPPED_EXCEPTIONS n'est pas définie. On trouve le commentaire suivant qui explique tout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {$IFNDEF PC_MAPPED_EXCEPTIONS}
      // We don't hook this under PC mapped exceptions, because
      // we have no idea what the parameters were to the procedure
      // in question.  Hence we cannot hope to unwind the stack in
      // our handler.  Since we just throw an exception from our
      // handler, that pretty much rules out using this without
      // exorbitant compiler support.  If you do hook AbstractErrorProc,
      // you must make sure that you never throw an exception from
      // your handler if PC_MAPPED_EXCEPTIONS is defined.
      AbstractErrorProc := @AbstractErrorHandler;
    {$ENDIF}
    Traduction (commentée entre crochets) :
    Nous ne renseignons pas ceci avec des exceptions mappées, parce que nous n'avons aucune idée quant aux paramètres attendus par la méthode en question [la méthode virtuelle abstraite]. Dès lors, nous ne pouvons pas espérer "dérouler" (unwind) la pile de notre gestionnaire [AbstractErrorHandler]. Puisque nous lançons juste une exception depuis ce gestionnaire, ça fonctionne plutôt bien comme ça, sans un support énorme du compilateur [pour connaître les paramètres - cela dit, ce serait faisable]. Si vous modifiez AbstractErrorProc, vous devez vous assurer que vous ne lancez pas d'exception depuis celui-ci si PC_MAPPED_EXCEPTIONS est définie.
    Cela répond-il a tes doutes ?
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  15. #15
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 530
    Points : 25 063
    Points
    25 063
    Par défaut
    Mon Anglais est pitoyable, et il est vrai que les traductions net, sont parfois pas terrible ... Bon, je t'avoue que j'ai cherché, mais je n'ai su trouvé ...

    Sinon, les Error RunTime 210, j'en ai eu lors d'exception dans un Finalization, j'ai souffert pour les trouver ...

    Pour les Fuites mémoires, cela semble donc s'expliquer, sous Window, même si il y en a ça doit trainer quelques part mais on ne le voit pas via le Gestionnaire de Taches, alors que sous Linux, ça se voit parce que c'est le code qui le gère ?!

    Sinon pour les Méthodes Abstraites, ce texte explique bien, et cela semble cohérent avec la particularité de ces méthodes ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  16. #16
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon, les Error RunTime 210, j'en ai eu lors d'exception dans un Finalization, j'ai souffert pour les trouver ...
    La prochaine fois, ajoute un gestionnaire d'exception fatale avec la variable ExceptProc, également déclarée dans System. Voir l'aide pour plus d'infos.

    Citation Envoyé par ShaiLeTroll Voir le message
    Pour les Fuites mémoires, cela semble donc s'expliquer, sous Window, même si il y en a ça doit trainer quelques part mais on ne le voit pas via le Gestionnaire de Taches, alors que sous Linux, ça se voit parce que c'est le code qui le gère ?!
    Euh, non. Normalement l'empilement des gestionnaire d'exceptions permet de ne pas avoir de fuites mémoire. Même les variables string et autres types dynamiques créent des gestionnaires d'exceptions invisibles pour se libérer correctement même en cas d'exception.
    Donc rien n'est expliqué. Il reste soit une erreur, soit un bug quelque part (de ton côté ou de celui de la RTL).

    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon pour les Méthodes Abstraites, ce texte explique bien, et cela semble cohérent avec la particularité de ces méthodes ...
    N'empêche que je me pencherai sur le gestionnaire de Linux à mon retour de vacances. Ca me paraît fort qu'il ait besoin de savoir les paramètres envoyés pour libérer le tout correctement
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  17. #17
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 530
    Points : 25 063
    Points
    25 063
    Par défaut
    Pour mes Error RunTime 210, j'ai tout simplement ajouté des Try Except autour dans les Finalize pour écrire dans le Journal d'Evènement la présence d'une erreur et je redéclenchait l'exception, d'ailleurs, depuis j'en ai plus, c'était du à des doubles libérations d'objet (problème de notification dans les Collections et Owner)

    Citation Envoyé par sjrd Voir le message
    Il reste soit une erreur, soit un bug quelque part (de ton côté ou de celui de la RTL).
    Je ne suis pas l'auteur du sujet, c'est juste que cela m'interessait énormément, je me suis toujours posé des questions sur la libération des exceptions ...

    fort possible que la RTL Kylix soit moins au point que celles de Delphi, après tout, il y a une différence de 10 ans d'expérience des experts Borland entre Windows (delphi était pour Win 3.1 non ?) et Linux

    Citation Envoyé par sjrd Voir le message
    je me pencherai sur le gestionnaire de Linux à mon retour de vacances
    Bon sujet pour la FAQ, mais Cedric ne pourra pas tester si tes modifications améliorent le bousin ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. HeapAgent, le bon outil pour la détection des fuites mémoires en C ?
    Par SteAlma dans le forum Choisir un environnement de développement
    Réponses: 2
    Dernier message: 04/07/2014, 10h42
  2. Test des fuites mémoires
    Par wawa84 dans le forum C++
    Réponses: 2
    Dernier message: 09/06/2009, 18h10
  3. Réponses: 19
    Dernier message: 04/10/2006, 16h53
  4. Traquer les fuites mémoires (memoryLeak) ?
    Par MonsieurAk dans le forum Windows
    Réponses: 2
    Dernier message: 08/09/2005, 09h07

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