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 :

Bug avec les variables fichiers Text


Sujet :

Free Pascal

  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
    Points : 493
    Points
    493
    Par défaut Bug avec les variables fichiers Text
    Bonsoir,

    Ca fait longtemps que je n'étais pas revenu dans cette zone du forum....

    Je viens de découvrir un bug de l'unité System aujourd'hui. Le bug s'exprime avec les variable de type Text, et qu'on a deux variables Text associé au même fichier.

    Si l'on fait par exemple

    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    VAR
       F1 : Text;
       F2 : Text;
     
    BEGIN
       Assign (F1, 'fichier.txt');
       Rewrite (F1);
       F2 := F1;
       Write (F2, '...');
       Rewrite (F1);
       Write (F2, '...');
       Close (F1);
    END.
    Le contenu de « fichier.txt » peut être tronqué (et il l'est même souvent). Il manque environ de 200 à 300 caractère dans « fichier.txt »

    Le code donné en exemple peut parraître d'une utilité douteuse, mais il arrive que dans des applications complexe, un fichier soit créé, puis que celui ci soit passer à une autre procédure, par l'intermédiaire d'une variable. Tout autant qu'il se peut qu'un fichier doivent être réinitialisé, pour en reprendre la constrution depuis le début (d'où le second rewrite). Et dans ces circonstances, ce bug s'exprime.

    Si avant de fermer le fichier on, fait
    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       Flush (F1);
       Close (F1);
    Le problème n'est pas résolu. Mais si on fait
    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       Flush (F2);
       Close (F1);
    Alors le problème est résolu.

    Ceci laisse penser que les variable de type Text ne peuvent pas être copier d manière sûre, et que leurs copie ne sont pas strictement des alias du même fichier. Elle se réfère plutôt chacune au même fichier, mais semble disposé de leur propre buffer.

    Ceci n'est pas sans poser de soucis, si deux processus différents écrivent dans un même fichier tour-à-tour, en employant des variables différentes.

    J'espère ne pas être trop confus dans la manière d'exposer ce bug.

    Bonne soirée
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 945
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 945
    Points : 5 659
    Points
    5 659
    Par défaut
    Kao,

    Pour moi, ce n'est pas un bug, mais une mauvaise utilisation.

    C'est au programmeur de savoir ce qu'il fait.
    Si les cons volaient, il ferait nuit à midi.

  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
    Points : 493
    Points
    493
    Par défaut
    Citation Envoyé par droggo
    Kao,

    Pour moi, ce n'est pas un bug, mais une mauvaise utilisation.

    C'est au programmeur de savoir ce qu'il fait.
    Salut,

    Etaye tes propos please, dis-en plus.... je savais ce que je faisais justement : F1 et F2 sont associés au même fichier. Le premier rewrite cré le fichier, le deuxième rewrite réinitialise le fichier (vide son contenu), et ce, normalement pour les deux F1 et F2 (normal, elles sont associées au même fichier). Mais aprés ces opérations, tout se passe comme si F2 était détaché de « fichier.txt », ce qui est ouvertement anormal. Alors si ce n'est pas un bug ça, je ne sais pas ce que c'est

    C'est une mauvaise implémentation de l'unité System à mon avis, et j'ai une petite théorie sur son origine (théorie à vérifier).

    Les variables de type Text ou FILE, sont associées à une implémentation, disont un objet S, prennant en charge les appels système pour les accès aux fichiers.

    F1 est associé à S
    F2 est associé à S

    S contient par exemple un handle fichier, ou toute autre représentation faisant le lien avec le système.

    F1 et F2 peuvent correspondrent à deux positions différentes dans le fichier, et ont donc chacun leurs buffer de lecture/écriture associés à leur positions respectives dans le fichier. Mais apparement l'unité Système associe ces buffer directement au variable Text et FILE, alors que les buffers devraient êtres associés à l'objet S. Il s'en suit une erreur de synchronisation, et l'unité System s'emmèle les pinceaux avec deux buffers que de toute évidence elle n'arrive pas à synchroniser.

    C'est une hypothèse sur l'origine du problème, mais l'echec de synchronisation des buffers est certain lui.
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  4. #4
    Responsable Pascal, Lazarus et Assembleur


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

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

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 944
    Points : 59 431
    Points
    59 431
    Billets dans le blog
    2
    Par défaut
    Bonjour !

    Il est à noter que l'assignation
    est illégale pour les compilateurs Turbo Pascal, Virtual Pascal et même Delphi.

    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]

  5. #5
    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
    Points : 493
    Points
    493
    Par défaut
    Alut,
    Citation Envoyé par Alcatîz
    Il est à noter que l'assignation
    est illégale pour les compilateurs Turbo Pascal, Virtual Pascal et même Delphi.

    Pour Turbo Pascal je ne me souviens plus ce qu'il en était (possible que c'était interdit, mais ça date, j'ai oublié), et je ne connais pas les deux autres. Mais FreePascal ne m'a renvoyé aucun message d'erreur. S'il autorise ces assignations, alors ils doit les prendre en charge normalement. Mais c'est vrai que ce serait une bonne alternative aussi que de tout simplement interdit F2 := F1, même si ça peut être pratique dans certains cas.

    Merci pour l'info sur ces trois autre compilateurs, j'en tiens compte pour me faire une raison

    @+
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  6. #6
    Membre habitué

    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 192
    Points : 176
    Points
    176
    Par défaut
    bonjour,



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    VAR
       F1 : Text;
       F2 : Text;
     
    BEGIN
       Assign (F1, 'fichier.txt');
       Rewrite (F1);
       F2 := F1;
       Write (F2, '...');
       Rewrite (F1);
       Write (F2, '...');
       Close (F1);
    END.

    j'ai regardé en diagonale ... mais il ne manque pas un close(F2) ? (ce qui pourrait expliquer que le buffer ne se vide pas ? )

    en tous cas c'est un peu dangereux comme méthode ...

    bonne continuation
    Un bon exemple vaut mieux qu'une longue explication confuse...

  7. #7
    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
    Points : 493
    Points
    493
    Par défaut
    Bonsoir,

    Citation Envoyé par JoseF
    j'ai regardé en diagonale ... mais il ne manque pas un close(F2) ? (ce qui pourrait expliquer que le buffer ne se vide pas ? )
    F1 et F2 sont le même fichier, et la fermeture de F1 doit être aussi la fermeture de F2 (F2 devient invalide). Buffer, oui, buffer... c'est là qu'est le problème, ou le bug selon les points de vus. En tous cas, F1 et F2 sont nécéssairement associés au même handle (même si strictement parlant ce détail d'implémentation est censé être transparent, il est universel), et donc encore une fois, la fermeture de F1 suffit... normalement.

    Citation Envoyé par JoseF
    en tous cas c'est un peu dangereux comme méthode ...
    C'est drôle que vous ayez l'air de le penser (en tous cas vous êtes au moins trois), et je suis sûre que vous pratiquer peut-être régulièrement ce type de jeux d'alias avec d'autres types d'objets, sans pour autant que cela ne vous parraissent étrange. C'est le cas fréquent ou un aspect de la manipulation d'un objet et traité par un processus, et ou un autre aspect est traité par un autre processus, et l'un des processus est censé ne pas devoir se soucier de « quel est l'objet actif en cours ». L'exemple que je donnais dans le premier post n'est pas l'exemple concret, mais un exemple similaire.

    Je ne sais pas si je dois marquer résolu ou pas, vu que Alcatiz à apporté une réponse pertinente, mais que en même temps la question demeure. Alors je laisse comme ça. Mais bon, j'ai modifié mon code pour tenir compte des remarques d'Alcatiz (je ne fais plus d'alias).

    Bonne nuit (heure tardive )
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  8. #8
    Membre éclairé

    Inscrit en
    Avril 2003
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 284
    Points : 773
    Points
    773
    Par défaut
    Pour avoir debuggué ce morceau de code compilé, et fait quelques modification puis re-compilé et débuggué d'autres bouts de code j'en arrive aux conclusions suivantes:

    Le programme compilé utilise un seul buffer pour y ecrire.
    malheureusement, si on a deux handle de fichiers, il utilise un indice de position courante pour chaque handle, et un indice correspondant à la longueur de fichier pour chaque handle...
    L'instruction close copie dans le fichier sur le disque dur le nombre d caractères propre au handle passé en paramètre...

    voici deux exemples qui vont illustrer ce que j'avance :

    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
    PROGRAM TEST;
    VAR
       F1 : Text;
       F2 : Text;
     
    BEGIN
       Assign (F1, 'fichiertest.txt');
       Rewrite (F1);
       F2 := F1;
       Write (F2, '1234'); // on ecrit 1234 dans le buffer à partir de l'indice 0
       Write (F1, '56');    // on ecrit 56 dans le buffer à partir de l'indice 0
       Close (F2);          // on ferme F2 donc on ecrit 4 caractères
    // le résultat est 5634
     
    END.
    autre 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
    PROGRAM TEST2;
    VAR
       F1 : Text;
       F2 : Text;
     
    BEGIN
       Assign (F1, 'fichiertest2.txt');
       Rewrite (F1);
       F2 := F1;
       Write (F1, '56');     //on écrit 56 dans le buffer à partir de la position 0
       Write (F2, '1234');  //on écrit 1234 dans le buffer à partir de la position 0
       Close (F1);           // On ferme F1 donc on ecrit 2 caractères dans le fichier
    // on obtient 12
    END.
    ton code commenté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    VAR
       F1 : Text;
       F2 : Text;
     
    BEGIN
       Assign (F1, 'fichier.txt');
       Rewrite (F1);
       F2 := F1;
       Write (F2, '...'); // on ecrit ... depuis la position 0 dans le buffer
       Rewrite (F1);    // on met à zero l'indice de position dans le buffer pour F1 et à 0 le nombre de caractères. le buffer n'est pas effacé
       Write (F2, '...'); // on ecrit ... dans le buffer à la position 2 (après les ... précédents)
       Close (F1);  // on ferme F1 donc on ecrit 0 caractères dans le fichier...
    //resultat fichier vide...
    END.
    la solution que tu proposes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       Flush (F2);
       Close (F1);
    fonctionne dans ton cas mais n'est pas correcte :

    en effet Flush(F2) ecrit le nombre de caractères contenu dans l'indice de F2 (ici 6) dans le fichier) puis close (F1) ecrit le nombre de caractères contenus dans l'ndice de F1 dans le ficheir, tu as de la chance, c'est ici zéro....

    Un exemple final pour bien comprendre :
    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
    program test;
    VAR
       F1 : Text;
       F2 : Text;
     
    BEGIN
       Assign (F1, 'fichiertest3.txt');
       Rewrite (F1);
       F2 := F1;
       Write (F1,'ab');  // on ecrit ab dans le buffer à la position 0
       Write (F2, '123'); // on ecrit 123 dans le buffer à la position 0, ab a été écrasé
       Rewrite (F1); // Pour F1 position=0 longueur = 0
       Write (F2, '456'); // on ecrit 456 à la position 2, le buffer contient 123456
       write (F1,'cd'); // on ecrit cd à la position 0, le buffer contient cd3456
       flush(F2); // on ecrit 6 caractères dans le fichier, soit cd3456
       Close (F1); // on ecrit 2 caractères dans le fichier (après cd3456), ici cd
    // résultat cd3456cd
    END.
    Avec ça j'espère que tu as compris le fonctionnement du tout et que tu mettras un tag résolu à ce post....

    Bonne prog

    Clandestino

  9. #9
    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
    Points : 493
    Points
    493
    Par défaut
    Clandestino, tu m'as éppaté avec tout ça.

    Je n'ai malheureusement pas de debugger, alors je ne pourrai pas essayer, mais si tu comme tu l'avance, il y a un buffer et deux handles, alors c'est tout à fait le contraire de ce que je pensais. Mais est-ce bien normal qu'il y ait deux handles ?

    Une petite note : donc mon programme, je n'écrivais jamais avec F1, mais seulement avec F2, et le close n'était que sur F1, et même sans flush sur F2, le fichier résultant n'était jamais vide... non, mais il manquait parfois (et même pas toujours), environ 200 à 300 octets.

    Merci quand-même pour ton analyse, mais au final je m'en tiens pour le moment à ne plus copier de variables fichier text.

    Et puis non, je ne marque pas encore résolu, parce que comme je l'ai expliqué, cela ne répond encore pas aux questions (parce que mon fichier n'était jamais vide, mais seulement tronqué d'une longeur à peu-prêt constante)

    Quand j'aurais le temps (ce qui pourrait bien tarder), j'irai fouiner dans la librairie System pour voir ce qu'il en est.

    Merci encore pour tes analyses Clandestino, c'était magnifique
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  10. #10
    Membre éclairé

    Inscrit en
    Avril 2003
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 284
    Points : 773
    Points
    773
    Par défaut
    Citation Envoyé par Hibou57
    Je n'ai malheureusement pas de debugger
    Cette analyse a été effectuée avec ollydbg (shareware gratuit): http://www.ollydbg.de/
    Un bon outil....

  11. #11
    Membre éclairé

    Inscrit en
    Avril 2003
    Messages
    284
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 284
    Points : 773
    Points
    773
    Par défaut
    Citation Envoyé par Hibou57
    Et puis non, je ne marque pas encore résolu, parce que comme je l'ai expliqué, cela ne répond encore pas aux questions [I](parce que mon fichier n'était jamais vide, mais seulement tronqué d'une longeur à peu-prêt constante)
    ZUT !

    Vérifie, ton fichier faisait une taille d'exactement le nombre d'octets ecrits avec le handle F1 à cet instant... Dans ton code, ce dernier n'était pas forcément égal à zéro contrairement à l'exemple que tu nous donnes...

  12. #12
    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
    Points : 493
    Points
    493
    Par défaut
    Salut,

    Citation Envoyé par Clandestino
    ZUT !
    Pas grave ... ton intervention m'a bien fait plaisir quand-même

    Citation Envoyé par Clandestino
    Vérifie, ton fichier faisait une taille d'exactement le nombre d'octets ecrits avec le handle F1 à cet instant...
    Justement, aucune donnée n'était écrite avec F1. J'avais peut-être mal formulé l'idée l'architecture, mais voilà en quelques mots : le control de la création, réinitialisation et fermeture du fichier était à la charge d'un processus, et l'écriture dans le fichier, à la charge d'un autre processus (notez que les processus appartiennent à la même tâche). C'est cette séparation des contrôls qui était à l'origine de la séparation en deux variables (ou plus). Chaque processus ignorant ce que l'autre faisait.

    Donc aucune écriture avec F1, et seulement avec F2.
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

Discussions similaires

  1. bug avec les fichiers CHM
    Par Lorenzo77 dans le forum Windows
    Réponses: 5
    Dernier message: 13/09/2008, 12h19
  2. [Sécurité] bug avec les variables de session!
    Par ozzmax dans le forum Langage
    Réponses: 7
    Dernier message: 09/12/2005, 19h41
  3. Problèmes avec les variables final
    Par casolaro dans le forum Langage
    Réponses: 7
    Dernier message: 09/12/2004, 14h29
  4. Réponses: 6
    Dernier message: 28/05/2004, 09h39
  5. [CR9] Bug avec les champs à valeur vide ?
    Par Djob dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 15/07/2003, 21h21

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