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

Delphi Discussion :

Thread ?Débordement de pile? et bloc de 32 nulls écrits dans un fichier


Sujet :

Delphi

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 190
    Points : 218
    Points
    218
    Par défaut Thread ?Débordement de pile? et bloc de 32 nulls écrits dans un fichier
    Bonjour

    Dans le cadre d'une application multi thread de transfert de fichiers vers des machines à Commande Numérique (par RS232) de temps en temps sur de très "gros" fichiers 200 Ko (copier X fois en mémoire au cours du traitement) mon programme remplace une ou plusieurs parties du fichier par des blocs de 32 caractères null consécutifs

    Est il possible qu'un débordement de pile dans un thread puisse générer ce type d'erreur (remplacement d'une partie du fichier par des blocs de 32 octets null) ?

    Quel est la taille de la pile, et au fait qu'est ce que c'est et à quoi cela sert t'il ?

    Merci

  2. #2
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    je sais pas, mais je pence que tu dois changé ton algo de transfer:
    comme le port série est un peut lent par raport au lecture a partir DD, alors , pourqoi pas lire simlement le bloc à envoyé et attendre l'evenement "le registre d'envoit est vide"

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 190
    Points : 218
    Points
    218
    Par défaut
    Merci pour ta proposition

    mais le probleme se produit de manière aléatoire et il concerne principalement la reception de données de la machine vers le pc et non l'envoi

    lors de la reception un thread tourne en continu pour lire les données du port com les ajoutent aux données déjà recues puis au bout d'un timeout de 5 sec sans récéption il transmet le fichier recu "complet" au thread de la machine

    qui lui devrait supprimer les nulls du fichier le probleme est qu'il en reste dans le fichier mais dans la ligne avant d'enregistrer le fichier je supprime les nulls , et c'est la que je comprends plus rien , d'ou ma question est ce qu'un debordement de pile peux massacrer un emplacement memoire genre le contenu du fichier avant enregistrement en écrivant des blocs de 32 nulls dans le fichier

  4. #4
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    pour j'ai jamais eu de probléme de ce genre, toujour j'envoit en début la taille de fichier à envoyé puis le fichier lui meme
    lis: sa et sa de nono40,, et en parlant de nono où est il, sava bien, tu nous manque ici, j'éspére que tt va bien pour toi

  5. #5
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    alors??
    si oui donne la solution

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 190
    Points : 218
    Points
    218
    Par défaut
    helas non ce n'est pas resolu du tout

    je te remercie encore pour ton idée, mais je parle de communication via le port serie RS232 et pas via le réseau de plus j'ai déjà fait l'envoi du fichier morceau par morceau car certaine machine numérique sont très très lentes à la récéption mais ma question est plutôt

    Quelles sont les conséquences possibles d'un débordement de pile dans un thread ?

    Si j'utilise memproof il indique des erreurs de type memory overrun, mais qu'est ce que cela veux dire exactement, sachant que cela survient de manière totalement aleatoire et a des endroit ou ce n'est pas possible !!!

  7. #7
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    laquestion est pourqoi sa arive? pas les consecances pous vs au moins
    donne le code incriminé

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 190
    Points : 218
    Points
    218
    Par défaut
    voici une partie du code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
     
     
    //cette fonction est appelée pour tous les retours de programme provenant des machines CN
     
    function TSandraSrvMachine.TraitementFichier_Retour_Programme(
      LeContenuDuFichier, ReferenceSandra: string): boolean;
    var
      LeNomDuProgramme,NomProgDos:string;
      Prog:TProgCN;
    begin
      Result:=false;
      addMessage(Sandra_DEMANDE_RECEPTION,sstr_receptionRetour+ReferenceSandra);
      LeNomDuProgramme:= MachineCn.getCheminCompletProgramSandraRetour(ReferenceSandra);
      if LeNomDuProgramme='' then begin
        addMessage(Sandra_MESSAGE,format(sstr_EchecEneteteSandraNonTrouve,[ReferenceSandra]));
        envoyerMessage(format(sstr_EchecEneteteSandraNonTrouve,[ReferenceSandra]));
        MajFlagErreur(format(sstr_EchecEneteteSandraNonTrouve,[ReferenceSandra])); 
        exit ;
      end ;
      NomProgDos:=ExtractFileName(LeNomDuProgramme);
      PROG:=TProgCN.create(ReferenceSandra,MachineCn.CAT_ID);
      remplace_string (LeContenuDuFichier,#0,'');
      if EnregistrementProgrammeCorrecteurRetour(
         NomProgDos,LeNomDuProgramme,LeContenuDuFichier,'P',MachineCn,PROG
         )then begin
        addMessage(Sandra_MESSAGE,sstr_EnregistrementOK+LeNomDuProgramme+' dos '+nomprogdos);
     
    //partie qui supprime les nulls
     
      remplace_string (LeContenuDuFichier,#0,'');
      if EnregistrementProgrammeCorrecteurRetour(
         NomProgDos,LeNomDuProgramme,LeContenuDuFichier,'P',MachineCn,PROG
         )
     
    //detail procedure enregistrement fichier
     
    function EnregistrementProgrammeCorrecteurRetour(NomFichier,
                                                     CheminCompletFichier,
                                                     ContenuFichier,TypeProgCorr:string;
                                                     Machine:TMachineCn;
                                                     Prog:TProgCN
                                                                 ):boolean;
    var
      PrgMac:TPRGMAC;
      LeFichier:TFileStream;
      nb:Longint;
      cpyContenuFichier:string;
    begin
      Result:=false;
      if not assigned(machine) then exit;
      if not assigned(prog) then exit;
      if NomFichier='' then exit;
      if CheminCompletFichier='' then exit;
      if ContenuFichier='' then exit;
     
      try
        if (Machine.estComparaisonValidationAutomatiqueRetourActiver) and (TypeProgCorr='P') then begin
          if Machine.isProgrammeRetourIdentiques(ContenuFichier, Prog.prg_nom) then begin   
            Prog.PRG_COMMENT := 'IDEM' ;
            result := false ;
            exit ;
          end ;
        end ;
      except
     
      end;
      //enregistrement du fichier
      LeFichier:=TFileStream.Create(CheminCompletFichier,fmcreate or fmOpenReadWrite );
     
      supprimerCarNullDebutEtFinPGM(ContenuFichier); //wn040209
     
      nb:=LeFichier.write((@contenufichier[1])^,length(contenufichier));
     
      LeFichier.free;
     
    //detail de la procedure remplace string
     
    procedure remplace_string(var s : string ; str_anc, str_nouv: string);
      var pos_ : integer;
      begin
        if str_anc=str_nouv then exit ;
        pos_ := pos ( str_anc , s ) ;
        while pos_ > 0 do begin
          s := copy (s,1,pos_-1)+str_nouv + copy (s,pos_+length(str_anc),length (s));
          pos_ := pos ( str_anc , s ) ;
        end ;
      end;
     
    //detail procedure suppression de nulls au debut et en fin de programme
     
    Procedure SupprimerCarNullDebutEtFinPGM(var lePGM:string);
    var
      i,nbNull:integer;
      suite:boolean;
      cpyStr:string;
    begin
      //suppression des null en debut de PGM
      i:=1;
      nbNull:=0;
      suite:=true;
      while suite and (i<Length(lePGM)) do begin
        suite:=true;
        if lePGM[i]=#0 then begin
          inc(i);
          inc(nbnull);
        end else begin
          suite:=false;
        end;
      end;
      if nbNull>0 then begin
        lePGM:=copy(lePGM,i,length(lePGM));
      end;
      //suppression des null en fin de PGM
      i:=length(lePGM);
      nbNull:=0;
      suite:=true;
      while suite and (i>0) do begin
        suite:=true;
        if lePGM[i]=#0 then begin
          dec(i);
          inc(nbnull);
        end else begin
          suite:=false;
        end;
      end;
      if nbNull>0 then begin
        lePGM:=copy(lePGM,1,length(lePGM)-nbNull);
      end;
    end;

  9. #9
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    j'ai pas compris vraiment tt votre code, tu as trop de variable et les nom sont leng un peut (comme des procedure ),
    en plus tu n'as pas donnée la procedure de réception (port série)
    voilà une suggestion pour tes 2 dérnier proc
    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
    procedure remplace_string(var s : string ; str_anc, str_nouv: char);
      var i : integer;
      begin
        if str_anc=str_nouv then exit ;
        for i:=1 to length(s) do
          if s[i]=str_anc then s[i]:=str_nouv;
      end;
     
    //detail procedure suppression de nulls au debut et en fin de programme
     
    Procedure SupprimerCarNullDebutEtFinPGM(var lePGM:string);
    var
      i:integer;
    begin
      //suppression des null en debut de PGM
      i:=1;
      while (lePGM[i]<>#0) and (i<Length(lePGM)) do inc(i);
      if (i>1) and (i<Length(lePGM) then
        lePGM:=copy(lePGM,i,length(lePGM)-i+1);
     
      //suppression des null en fin de PGM
      i:=length(lePGM);
      while (lePGM[i]<>#0) and (i>1) do  dec(i);
      if (i>1) and (i<Length(lePGM) then
        lePGM:=copy(lePGM,1,length(lePGM)-i);
    end;

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 190
    Points : 218
    Points
    218
    Par défaut
    pour la reception

    c'est un thread qui est dédié à la récéption des données sur le port série, je n'utilise pas les evenement de reception du composants RS232 car si le PC est "chargé" car il est possible qu'il ne soit pas traités correctement
    (genre 2 evt reception manqués sur 100 si plusieurs envoi/reception en simultanées sur plusieurs comport)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
     
    procedure TThreadReceptionSandraSrv.Execute;
    var
      TheBuffer:string;
      FNbSecondeEntreDeuxReception:integer;
      FDateReception:tdatetime;
      FDateLastReception:tdatetime;
      LineErreur : integer ;
    begin
      //DEMARRAGE
      FFileEventSandra.Empiler_Event(C_Evt_THREAD_Reception_START,'');
      FMainThreadWakeEvent.SetEvent;
      //Boucle Thread
      while not terminated do begin
        //On attend 100 ms sinon trop usage CPU
        sleep(100);//wn061123
        try
          //Activation test time out reception
          FVerificationTimeOutReception:=FDebutReceptionEvtDone;
          //On verifie si le port com est ouvert
          if FApdComPort.Open then begin
            //Verification si des données sont disponnibles en RECEPTION
            if FApdComPort.CharReady then begin
              if not FDebutReceptionEvtDone then begin
                FDebutReceptionEvtDone:=true;
                LineErreur := 0 ; 
                //Evt Debut Reception
                FFileEventSandra.Empiler_Event(C_Evt_Thread_Reception_Debut_Reception,'');
                //Reveil thread principal
                FMainThreadWakeEvent.SetEvent;
              end;
              //Reception
              TheBuffer:='';
              while FApdComPort.CharReady do begin
                TheBuffer:=TheBuffer+FApdComPort.GetChar;
              end;
              if LineErreur=0 then LineErreur :=FApdComPort.lineerror ; //lc050803
              //Maj du buffer de RECEPTION
              FFichierRecu:=FFichierRecu+TheBuffer;
              //Evt Reception dans le buffer
              FFileEventSandra.Empiler_Event(C_Evt_Thread_Reception_Buffer_Reception,FFichierRecu);
              //Reveil thread principal
              FMainThreadWakeEvent.SetEvent;
     
     
    //en plus résumé
     
              //Reception
              TheBuffer:='';
              while FApdComPort.CharReady do begin
                TheBuffer:=TheBuffer+FApdComPort.GetChar;
              end;

  11. #11
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    Là, mon petit; chapeau à l'inverse
    Je redis ce que j'ai déjà dis un jour
    Tu utilises un Bulldozer pour casser un petit mur
    tcomport utlise déjà un thréad, est la V3 de cport est super surtout la prpriété
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ComPort1.SyncMethod type [TSyncMethod = (smThreadSync, smWindowSync, smNone);]
    pour moi je l'utilise smThreadSync ;;revoit ton code
    à prpos tu dis:
    (genre 2 evt reception manqués sur 100 si plusieurs envoi/reception en simultanées sur plusieurs comport)
    combient de comport tu utilise ??

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 190
    Points : 218
    Points
    218
    Par défaut
    j'utilise 14 port RS232 en simultanés (les envois et receptions de machines peuvent survenir n'importe quand et sur plusieurs machines différentes en même temps)

    1 sur le PC
    8 a travers un adaptateur specialisés reseau RS232 MOXA NPORT 5610 (les produits moxa tu connais ?)
    5 autres adpatateurs specialisés reseau RS232 MOXA DE-211

    pas de TCOMPORT -> ASYNCPRO de turbo power

    avec pour chaque port

    un thread machine
    qui communique avec la base de données
    utilise des fichiers programmes
    qui gère un port com
    qui gère des threads d'envoi sur ce port com (envoi par morceau,envoi avec des pauses entres les envois de blocs,taille des blocs,protocole spécifique ...)
    qui contient un thread reception
    qui contient lui même contient un thread de timeout

    le tous à la fois sous la forme de service et d'exe windows standard

    (et encore la je te fais grace de la partie communication service interface utilsateur par le reseau)

    tous ces thread communiquent entre eux par files de messages protégées par des sections critiques

    Merci tout de même

  13. #13
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    oiiiiiiiiiiiiiiioi, tt sa est ban;; désoler
    mais n'oublie pas qu'on même que la vitesse du port série quelque soit est vraiment négligeable, on plus augmente la taille du buffer de réception (8192 oct.) pour chaque port,,
    utilise les événements,
    utilise le thréad de comport ou crée tt de 0. Mais pas les 2 comme tu fais
    les données reçu< au taille du buffer ne seront pas volatilisé; alors pas de panique
    je crois que tu reçoit tes données par les port série et les envoyé quelque part (serveur)
    Trop de section créatique ralentie sûrement votre post,
    Quelque fois en peut court-circuité deux composant sans passé par un intermédiaire (fichier, BD,...)
    Bon dev, si décide de passé à comport je suis là pour vs donnée un coud de mains

  14. #14
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    alors où en est tu???

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 190
    Points : 218
    Points
    218
    Par défaut
    en fait je n'ai plus trop le temps de m'en occuper j'ai 3 autres tres gros projets en ce moment

    je vais mettre ce sujet en delestage

    merci

Discussions similaires

  1. [WIN32][D7][DLL] Erreur: débordement de pile !
    Par hepha1970 dans le forum Débuter
    Réponses: 5
    Dernier message: 17/12/2007, 01h41
  2. [Threads] Implémenter une pile de processus
    Par Invité dans le forum Général Java
    Réponses: 7
    Dernier message: 30/07/2007, 12h14
  3. Débordement de pile
    Par litlebasic dans le forum Delphi
    Réponses: 11
    Dernier message: 29/06/2006, 11h48
  4. Débordement de pile
    Par portu dans le forum Delphi
    Réponses: 9
    Dernier message: 28/06/2006, 13h58
  5. Réponses: 7
    Dernier message: 10/01/2006, 20h58

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