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

Free Pascal Discussion :

RunError/Runtime-error handler ? [FAQ]


Sujet :

Free Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Par défaut RunError/Runtime-error handler ?
    Bonjour touti li moundi,

    Une question de fiabilité : existe -til un moyen de définir un traitement personalisé de RunError ? Est-il possible de définir un handler spécifique, ou n'y at-il pas d'autres moyen que AddExitProc ?

    AddExitProc ne convient pas tout à fait, parce que je suis pas certain que l'on puisse tester si l'arrêt du programme est dût à RunError ou à Halt/Exit. Et de plus, un handler passé à AddExitproc risque d'être appelé aprés le traitement par défaut de RunError. Sans compter qu'en plus, si un RunError se produit pendant l'initialisation d'une unit, alors il se peut qu'un handler censé être fixé par AddExitProc n'ait pas encore été mis en place.

    Dans l'idéal, pour être certain que le bon handler soit toujours appelé, il faudrait même qu'il puisse être spécifié dans une directive de compilation (au niveau d'une unit ou du programme principal).

    Mais peut-être n'y a t-il pas d'autres solutions à cela que de compiler une version personalisée de la unit System ?

    Je sais bien qu'il y a d'autres choses à faire un premier mai... mais que voulez-vous, il n'y a pas de muguets dans les bois chez moi (j'ai déjà cherché).

    Allez... bon week-end prolongé à tous/toutes

  2. #2
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    8 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 8 038
    Billets dans le blog
    2
    Par défaut
    Bonjour !

    Je pense qu'il est possible, dans une routine installée par AddExitProc, de tester la valeur des variables ErrorAddr et ErrorCode de l'unité System.
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  3. #3
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Par défaut
    Citation Envoyé par Alcatîz
    Bonjour !

    Je pense qu'il est possible, dans une routine installée par AddExitProc, de tester la valeur des variables ErrorAddr et ErrorCode de l'unité System.
    Waaaw... assidu Toujours là tous les jours... bien le bonjour Alcatîz

    Je confirme ce que tu dis, et j'ajoute un complément aprés avoir lus le fichier system.inc (source de la RTL) : il n'existe pas d'handler utilisateur pour RunError, et le traitement d'erreur par défaut (celui qui affiche le petit message suivit du contenu de la pile) est effectué aprés que toutes les procédures enregistrées par AddExitProc aient été exécutées.

    Pour les applications qui ne peuvent pas se permettre d'accepter ce comportement (applications systèmes par exemple, ... là où ça ne le fait pas trop d'avoir une sortie parasite sur une flux de sortie, même redirigé), il faut modifier la procédure Do_Exit définie dans system.inc, et recompiler la unit System.

    Je cherchais aussi un moyen d'intercepter les exceptions à l'initilisation de l'application.

    Une construction comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Program XXX;
     
    BEGIN
       TRY
          ...
       EXCEPT
          ...
       END;
    END.
    ne convient pas, parce que l'execution de ce bloque ne commence pas avant que l'initilisation de toutes les unités ne soit achevée.

    J'avais naïvement pensé à une construction comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Program XXX;
     
    TRY
       ...
    EXCEPT
       ...
    END.
    mais cette construction est refusée par le compilateur.

    Là encore, il faut se reporter sur une prise en charge de RunError, et donc en revenir à la modification de la unit System indiquée plus haut.

    C'est passionant la question du traitement des erreurs

    Annexe :

    Source FreePascal 2.0.4 -> fpcsrc/rtl/inc/system.inc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    procedure RunError(w : word);[alias: 'FPC_RUNERROR'];
    begin
      errorcode:=w;
      erroraddr:=get_caller_addr(get_frame);
      errorbase:=get_caller_frame(get_frame);
      if errorcode <= maxExitCode then
        halt(errorcode)
      else
        halt(255)
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Procedure Halt(ErrNum: Byte);
    Begin
      ExitCode:=Errnum;
      Do_Exit;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Procedure do_exit;[Public,Alias:'FPC_DO_EXIT'];
    begin
      InternalExit;
      System_exit;
    end;
    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
     
    Procedure InternalExit;
    var
      current_exit : Procedure;
    Begin
      while exitProc<>nil Do
       Begin
         InOutRes:=0;
         current_exit:=tProcedure(exitProc);
         exitProc:=nil;
         current_exit();
       End;
      { Finalize units }
      FinalizeUnits;
      { Show runtime error and exit }
      If erroraddr<>nil Then
       Begin
         Writeln(stdout,'Runtime error ',Errorcode,' at $',hexstr(PtrInt(Erroraddr),sizeof(PtrInt)*2));
         { to get a nice symify }
         Writeln(stdout,BackTraceStrFunc(Erroraddr));
         dump_stack(stdout,ErrorBase);
         Writeln(stdout,'');
       End;
      { Make sure that all output is written to the redirected file }
      Flush(Output);
      Flush(ErrOutput);
      Flush(StdOut);
      Flush(StdErr);
    End;
    La partie à modifier, est celle se trouvant dans le bloque « If erroraddr<>nil Then .... end; »

    Note: ne modifiez surtout pas l'appel à System_Exit qui se trouve dans Do_Exit.

  4. #4
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Par défaut Détail technique pour la recompilation de System.pp et ObjPas.pp
    Ah, je me sent quand même beaucoup plus léger : j'ai modifié System.inc, pour que l'unité System sache si l'application a put être initialisé, et pour qu'un handler spécifique soit appelé en cas d'echec de l'initialisation de l'application. C'est beaucoup plus propre comme ça (d'où mon sentiment de légéreté).

    Un petit détail important (une erreur à ne pas faire) : pour recompiler System.pp, il faut utiliser les options « -Us » et « -Ur » (attention à la casse des options). L'option « -Ur » n'est pas obligatoire, mais recommandée. L'option « -Us », elle, est obligatoire, mais ne doit pas être utilisée pour la compilation des autres unités.

    L'erreur à ne pas faire, et de ne pas utilisé « -Us » pour compiler l'unité ObjPas.pp (bien que ObjPas soit une sorte d'unité system... qui override l'unité System standard). Aprés avoir recompilé System.pp, la recompilation de ObjPas.pp est nécéssaire si vous travaillez en mode ObjFpc ou en mode Delphi.

    Si quelqu'un(e) rencontre des problèmes en modifiant System.pp ou System.inc, ou en les recompilant, n'hésitez pas à demander ici

    Portez vous bien

  5. #5
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    8 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 8 038
    Billets dans le blog
    2
    Par défaut
    Merci pour tous ces détails, qui ont leur place d'ores et déjà réservée dans la FAQ !
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

Discussions similaires

  1. Runtime error avec UDF/DLL
    Par pram dans le forum SQL
    Réponses: 6
    Dernier message: 22/04/2005, 10h30
  2. [LG]Runtime Error lors d'une recherche dans un fichier
    Par Fraynor dans le forum Langage
    Réponses: 2
    Dernier message: 15/03/2005, 22h51
  3. [TP]Runtime error 106 à l'exécution
    Par BlackTiger dans le forum Turbo Pascal
    Réponses: 2
    Dernier message: 25/01/2004, 21h50
  4. [LG]runtime error 202
    Par picsou123 dans le forum Langage
    Réponses: 2
    Dernier message: 14/11/2003, 22h53
  5. [Kylix] Runtime error 230 avec INDY
    Par Anonymous dans le forum EDI
    Réponses: 2
    Dernier message: 23/03/2002, 11h51

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