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 :

Comment éviter l'erreur eAccessViolation en Delphi avec try except ?


Sujet :

Langage Delphi

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Comment éviter l'erreur eAccessViolation en Delphi avec try except ?
    Bonjour,

    Je programme depuis une dizaine d'années sous Delphi. J'utilise actuellement la version 2007. Dans le cadre d'une application multitâches je souhaite pouvoir continuer l'exécution d'un thread même si une fonction utilisée provoque une exception (notamment eAccessViolation). Après plusieurs jours de recherches, je ne trouve pas de solution à ce problème sur les différent forums ou tutoriaux que j'ai consulté. J'ai également modifié certains paramètres sur le débugger de Delphi sans succès (Outils/Options/Débuggeur CodeGear).

    Afin d'intercepter l'erreur, j'utilise une structure try ... except. Cela fonctionne pour les exceptions de type division par zéro ou autres erreurs mathématiques mais cela ne fonctionne pas pour les exceptions de type eAccessViolation qui se terminent invariablement par l'affichage d'un message sur l'écran.
    Premièrement j'aimerais éviter l'affichage de ce message et deuxièment j'aimerais poursuivre l'exécution du programme, la procédure qui provoque l'erreur devant simplement renvoyer une valeur booléenne à TRUE en cas d'erreur eAccessViolation. Est-ce possible ?

    Voici un petit programme de test que j'utilise pour tester la capture de l'erreur eAccessViolation. Il y a juste une fiche avec un seul bouton.
    Le code qui provoque l'erreur eAccessViolation avec GetMem et Move provient d'un tutorial sur la gestion des exceptions.

    Merci pour toute aide que vous pourrez m'apporter.

    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
    // créer une exception de type eAccessViolation
    // result = true si une exception s'est produite
    function Test_eAccessViolation():boolean;
    var
      p1 : pointer;
      p2 : pointer;
    begin
     result := false;
     try
      try
       GetMem(p1, 128);
       GetMem(p2, 128);
      // cette ligne provoque une exception eAccessViolation
       Move(p1, p2, 128); 
      finally
       FreeMem(p1, 128);
       FreeMem(p2, 128);
      end;
     except
      result := true;
     end;
    end;
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
     done : boolean;
      p2 : pointer;
    begin
     Button1.Caption := 'DEBUT';
     done := Test_eAccessViolation();
     if done = true then ShowMessage('Exception détectée.');
     Button1.Caption := 'FIN';
    end;

  2. #2
    Membre éclairé Avatar de DOLPat®
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2003
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 426
    Points : 790
    Points
    790
    Par défaut
    Bonjour

    Pour intercepter ce type d'erreur sans avoir de boite de dialogue, il faut gerer non pas au niveau local, mais au niveau de l'application avec Application.OnException. Mais c'est à utiliser avec des pincettes !!!

    Par 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    type
      TExceptionEvent = procedure(Sender : TObject ; E : Exception) of Object;
      procedure GestionErreurs(Sender : TObject ; E : Exception);
     
     
     
    procedure TfPrincipale.FormCreate(Sender: TObject);
    begin
      Application.OnException:=GestionErreurs;
    end;
     
    procedure TfPrincipale.GestionErreurs(Sender : TObject ; E : Exception);
    begin
      Application.MessageBox(PChar(E.Message), 'Erreur interceptée par la fonction GestionErreurs', MB_ICONINFORMATION);
    end;
     
    procedure Test_eAccessViolation;
    var
      p1 : pointer;
      p2 : pointer;
    begin
      GetMem(p1, 128);
      GetMem(p2, 128);
      // cette ligne provoque une exception eAccessViolation
      Move(p1, p2, 128);
    end;
     
     
    procedure TfPrincipale.Button1Click(Sender: TObject);
    begin
      Button1.Caption := 'DEBUT';
      Test_eAccessViolation;
      Button1.Caption := 'FIN';
    end;
    Mais, car il y a un mais ! Ce n'est pas une bonne solution. Lorsque tu exécute le code, tu verra qu'après avoir correctement affiché la boite de dialogue avec le message d'erreur, bien que l'application continue de tourner normalement, le code qui a suivi l'appel de la fonction Test_eAccessViolation (Button1.Caption := 'FIN') n'a pas été exécuté.
    Ceci est certainement dû à l'écrasement d'une zone mémoire par le Move qui a échoué...
    En conclusion, il vaut mieux éviter d'avoir des erreurs de violation que de les traiter car ils peuvent causer des dommages collatéraux...
    Il ne faut pas oublier que tant que tu pointe sur une zone valide de la mémoire (variables de l'application par exemple) les données seront écrasées et l'erreur eAccessViolation ne sera provoquée que lorsqu'on tentera d'écrire dans une zone non valide...
    PS: à l'avenir, ne pas omettre d'utiliser la balise code (boutonen haut de l'éditeur) pour insérer le code. Cela facilite sa lecture et évite de devoir le reformater. Merci.

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    le problème n'est pas dans la gestion d'exception mais dans ton code

    1/ ton move() écrase la pile d'appel de ta méthode puisque tu écris à l'adresse de p2 qui est sur la pile (en mode pas à pas, affiche la pile d'execution avant et après le move pour t'en convaincre)

    2/ ton FreeMem() de p2 ne peut pas fonctionner car la valeur de p2 a été écrasée par le move

    bref ton exemple fait tout ce qu'il peut pour faire planter l'appli et y parviens très bien

    le try/except permet de gérer les exceptions, mais si ton code corrompt la mémoire accessible en écriture (pile, data...) ça ne génère pas d'exception, ça fait juste planter le programme quand il accède à ces données (Return dans ton cas)...tu pourras alors éventuellement intercepter l'erreur à plus haut niveau, mais il y toutes les chances pour que ton appli soit instable.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Merci pour vos réponses et désolé pour l'aspect du code dans mon message.

    Si je résume la situation :

    1) l'exception eAccessViolation ne peut pas être interceptée par un bloc try ... except car elle détruit éventuellement une partie du code ou des données.

    2) l'utilisation d'un gestionnaire global (Application.OnException) permet d'éviter l'affichage du message d'erreur mais la fonction où s'est déroulée l'exception est interrompue.

    Cela ne m'arrange pas car dans le cas que je traite, il s'agit d'un programme multitâches qui tourne 24/24h et génère une erreur "eAccessViolation" 2 ou 3 fois par semaines.
    J'aurais voulu écrire un gestionnaire qui me permette de déterminer quelle tâche a déclenchée l'exception et même quelle procédure dans cette tâche.

    A défaut j'ai testé la méthode d'écrite sur le site ci-dessous qui devrait permettre de trouver le code qui a créer l'exception en se basant sur l'adresse de l'erreur.
    http://delphi.about.com/od/objectpas.../aa052201a.htm

    J'ai donc compilé l'application avec tous les paramètres de debug, le paramètre {D+} dans le fichier projet, activé la création du fichier MAP détaillé à la compilation. Lorsque l'erreur s'est produite sur l'exe (lancé depuis Windows et non de Delphi) j'ai utilisé la fonction "Aller à l'adresse" du menu "Chercher" mais sans succès. Seule la fenêtre de visualisation du code en assembleur s'est ouverte en pointant sur une série d'instructions "JUMP ????". Cela est peut-être dû au fait que les tâches sont créées à l'exécution ?

    Auriez-vous une idée de fonction à ajouter pour déterminer d'où peut venir l'erreur au moment de l'exécution ou s'il y a d'autres options à activer dans Delphi pour que le tutorial ci-dessus fonctionne ?

    Par rapport aux threads, tout les accès à la VCL sont synchronisés avec la fonction Synchronize() et les accès aux ressources (fichiers, bases de données) sont protégés par un système de jetons. Par contre j'ai un doute par rapport aux fonctions de la bibliothèque commune (fonctions arithmétiques, formatage de chaînes, ...). Durant le fonctionnement de l'application, il est possible que plusieurs threads utilisent la même fonction en même temps avec leurs propres variables locales comme arguments . Que se passe-t-il si par exemple trois tâches appellent "simultanément" la fonction StrToInt ? Est-ce que cela pourrait générer une exception eAccessViolation ?

    Merci de votre support et de vos idées.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 42
    Points : 51
    Points
    51
    Par défaut
    je n'ai pas d'idée précises, mais quelques pistes à explorer :
    - utiliser MadExcept.
    - le Remote Debugging (mais malheuresement pas au point sous D2007 (freezes))

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    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 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Essaye effectivement un code moins brutal comme

    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
    function Test_eAccessViolation():boolean;
    var
      p1 : pointer;
      p2 : pointer;
    begin
     result := false;
     try
      try
       GetMem(p1, 128);
       GetMem(p2, 128);
      // cette ligne provoque une exception eAccessViolation
       Move(p1^, p2^, 512);
      finally
       FreeMem(p1);
       FreeMem(p2);
      end;
     except
      result := true;
     end;
    end;
    ou encore

    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
    function Test_eAccessViolation():boolean;
    var
      p1 : pointer;
      p2 : pointer;
    begin
     result := false;
     try
      try
       p1 = NULL;
       GetMem(p2, 128);
      // cette ligne provoque une exception eAccessViolation
       Move(p1^, p2^, 128); 
      finally
       FreeMem(p2);
      end;
     except
      result := true;
     end;
    end;
    Ces codes devraient aussi provoqué une Violation d'Accès mais elle sera maitrisée !
    Car la violation du Move tu l'as bien capturée, mais tu ne captures pas celle du "End" de la fonction qui tente de nettoyer sa pile (asm RET)

    Au cas où, si il refuse le déréférencement ^ du type pointer, utilise un PInteger par exemple, normalement, cela fonctionne



    Citation Envoyé par F2C2SYSTEM Voir le message
    Par rapport aux threads, tout les accès à la VCL sont synchronisés avec la fonction Synchronize().
    Mieux vaut minimiser les Synchronize, si tu as la possibilité utilise la méthode Queue (minimum D2006)
    Tu peux aussi utiliser un TThreadList comme une FIFO et un TTimer, si c'est pour manipulation de VCL moins bloquante que Synchronize

    Citation Envoyé par F2C2SYSTEM Voir le message
    et les accès aux ressources (fichiers, bases de données) sont protégés par un système de jetons.
    Quel type de jeton ?
    Tu utilises bien des TCriticalSection ou des Event\Semaphore de Windows, pas juste une pseudo-sécurisation à la mano à base de booléen (ça fonctionne 99.99% des cas, un jour pas de chance, le changement de thread se produit en plein milieu d'une instruction
    seul des algoriythmes poussé comme Algorithme de Dekker ou Peterson peuvent assurer une sécurisation sans passer par Mutex ou Sémaphore de l'OS !

    Citation Envoyé par F2C2SYSTEM Voir le message
    Par contre j'ai un doute par rapport aux fonctions de la bibliothèque commune (fonctions arithmétiques, formatage de chaînes, ...). ... Que se passe-t-il si par exemple trois tâches appellent "simultanément" la fonction StrToInt ? Est-ce que cela pourrait générer une exception eAccessViolation ?
    Pour StrToInt, normalement pas de problème mais pour StrToFloat c'est écrit dans la documentation car le séparateur décimal est configurable . ou , et cela peut poser des soucis !

    La première forme de StrToFloat n'est pas adaptée aux threads car elle utilise les informations de localisation contenues dans les variables globales. La seconde forme de StrToFloat, qui est adaptée aux threads, fait référence aux informations de localisation contenues dans le paramètre AFormatSettings. Avant d'appeler la forme adaptée aux threads de StrToFloat, vous devez placer les informations de localisation dans AFormatSettings. Pour placer un ensemble de valeurs locales par défaut dans AFormatSettings, appelez TFormatSettings.Create.
    Idem les fonctions comme Format, FormatDateTime, StrToDate ...

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par F2C2SYSTEM Voir le message
    lé pour l'aspect du code dans mon message.

    Si je résume la situation :

    1) l'exception eAccessViolation ne peut pas être interceptée par un bloc try ... except car elle détruit éventuellement une partie du code ou des données.
    non, l'usage d'un pointeur Nil provoque la même erreur mais sans dommage, car l'adresse 0 est protégée en écriture...c'est le code que tu donnes en exemple qui provoque un écrasement de la pile...et là aucun debugueur ne pourra t'aider puisque le programme ne sais plus d'où il vient, ce qu'il a fait...car c'est la pile qui garde l'historique des appels

    recherche les instructions move() et Fillchar() de ton code, c'est sans doute une erreur du même type

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    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 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    ...c'est le code que tu donnes en exemple qui provoque un écrasement de la pile...
    @Paul TOTH, pense qu'il a copié ce code depuis un tutoriel sur la gestion des exceptions pour reproduire un EAccessViolation, ce code est volontairement "erroné" mais très maladroit pour un tutoriel car pourrait apporter une grosse confusion !


    F2C2SYSTEM note bien la différence

    Ton code qui provoque une erreur, ne la provoque pas sur forcément le Move mais sur les conséquence du Move, car c'est une MAUVAISE utilisation du Move, c'est un mauvais exemple, j'aimerais voir ce tutoriel car il complique inutilement la chose pour déclencher une exception EAccessViolation (il y a nettement plus simple qu'un Move)

    Ce code modifie la variable P1 et P2 ainsi que 120 octets qui suivent (le massacre), le déclenchement d'une exception n'est pas garantie (tu peux tomber sur de la mémoire accessible et parfois non selon la compilation et l'execution)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var
      p1 : pointer;
      p2 : pointer;
      p3: array[1..30] of pointer;
    regarde le contenu de P3 Avant et Après le Move, tu verras que p3 est aussi modifié alors qu'il n'était pas concerné !

    Tu es sur que ce tutoriel concernait vraiment les exceptions mais pas plutôt l'exemple typique de l'erreur que l'on fait avec Move qui au lieu de prendre des pointeurs utilise un buffer non typé variable, ce qui est très pervers !

    Le piège venant que Move nécessite un déférencement alors que CopyMemory utilise les pointeurs directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CopyMemory(p2, p1, 128);
    ces codes modifient le contenu pointé par P1 en copiant le contenu pointé par P2

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Pour le système de jetons j'utilise effectivement un système "à la mano". Au début j'utilisais le code ci-dessous dans une boucle d'attente propre à chaque thread pour être sûr qu'il n'y ai pas d'interruption mais j'ai fini par supprimer les instructions CLI et STI qui me paraissaient un peu "brusque" pour Windows.

    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
     
    // "Jeton" [integer] représente une variable globale
    // "ProcessCount" [integer] est une valeur unique, non nulle, assignée à chaque tâche lors de sa création
    // "Cnt" [word] est une variable locale de la fonction d'attente du thread
     
    Cnt := 0;
    repeat
     inc(Cnt);
     
     asm
      cli
     end;
     
     if Jeton = 0 then Jeton := ProcessCount; // affecte le numéro du thread à la ressource pour la verrouiller
     
     asm
      sti
     end;
     
     
     sleep(25);
     if Terminated then EXIT;
    until (Jeton=ProcessCount) or (Cnt = 40*5); // timeout après 5 secondes (40*5*25ms)

    Il est donc possible que sans les instructions CLI et STI, Windows puisse interrompre la tâche en plein milieu de la ligne "if jeton = 0 then jeton := ProcessCount" et que de ce fait deux tâches accèdent à la ressource en même temps. Est-ce que vous pensez que remettre les instructions CLI et STI rendrait temporairement le code plus robuste en attendant que j'ai le temps de déployer des CriticalSections ou des Mutex ?

    Pour en revenir à la traque de l'exception, je n'ai pas encore trouvé le bloc d'instruction qui provoque le blocage mais je me suis rendu compte que l'exception se produit toujours dans les mêmes conditions. Mon programme pilote une machine qui effectue un certain cycle (avec des vérins, des moteurs, ...). Lorsque je lance le programme, la machine effectue des cycles de cinq seconde et il peut s'écouler une durée aléatoire avant que l'exception ne se produise (disons entre quelques minute et plusieurs jours). Mais lorsque l'exception se produit, la machine est toujours dans le même état ce qui me permet de concentrer mes recherches sur deux tâches en particulier.

    J'ai suivi vos conseils et ajouté un gestionnaire pour l'événement Application.OnException. Ce gestionnaire est effectivement appelé quand je provoque ma pseudo-exception de test et il sauvegarde un fichier texte contenant des infos sur chaque tâche. Lorsque l'exception se reproduira, je devrai en savoir plus sur les actions qui étaient en cours au moment du blocage. Je verrai également si le thread où se produit l'exception est encore actif ou non. En effet j'ai du mal à estimer à quel niveau sera interrompu le code en cas d'exception eAccessViolation dans un programme multitâches si les nombreux blocs "try .. except .. end" placés dans chaque tâche n'arrêtent pas la propagation de l'exception.

    J'ignorais que certaine fonctions de conversion n'étaient pas adaptées aux threads. Peut-être que pour l'instant je n'ai pas eu de problèmes de ce côté car elles sont synchronisées ? J'effectuerais néanmoins une recherche dans le code pour voir s'il n'y en a pas une qui se cache dans du code non synchronisé.

    Je vous tiendrai au courant lorsque j'aurai trouvé l'erreur.
    Merci encore à tous pour vos idées et vos conseils enrichissants.

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    arf, CLI/STI c'était bon à l'époque du DOS, dans un OS multitâche multicoeur on oublie !

    pour manipuler des entiers en multitaches tu as les fonctions Interlocked*,
    InterlockedIncrement, InterlockedCompareExchange etc...

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Après quelques jours de travail de sécurisation des tâches avec des instructions "try" imbriquées j'ai obtenu une version de l'application qui résiste aux exceptions.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    try
     try
       // fait quelque chose avec des ressources
     except
      // intercepte une éventuelle exception
     end
    finally
     // libère les ressources utilisées
    end
    J'ai donc pu identifer la raison de l'EAccess Violation qui se produisait sporadiquement mais toujours au même moment du cycle de la machine.
    Il s'agissait d'une erreur dans le fichier XML qui contient les traductions de tous les messages. Sur un message en espagnol, le texte "%1:s" était remplacé par "% 1:s". L'instruction Format générait donc la fameuse EAccessViolation lorsque ce message devait être affiché. Cette partie du programme est à présent sous le contrôle d'un try except qui intercepte bien l'erreur et évite ainsi à la tâche d'être détruite.

    Encore merci à tous pour votre aide.

Discussions similaires

  1. Comment exécuter une DLL écrite en Delphi avec RunDLL32 ?
    Par Pedro dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 09/01/2008, 19h03
  2. Comment envoyer une commande UNIX par Delphi avec Indy ?
    Par Vulcanos dans le forum Web & réseau
    Réponses: 2
    Dernier message: 25/09/2007, 22h16
  3. Réponses: 2
    Dernier message: 10/11/2006, 10h26
  4. Comment éviter affichage #erreur dans un état
    Par Heureux-oli dans le forum Access
    Réponses: 2
    Dernier message: 07/06/2006, 14h31

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