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

C Discussion :

Pb coredump dans boucle en 64 bits


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 126
    Par défaut Pb coredump dans boucle en 64 bits
    Bonjour,

    J'utilise un AIX 5.3 et compile mes programmes C avec Visual Age 6.0

    Dans un programme C le code suivant fonctionne très bien lorsque mon programme est compilé en 32 bits :

    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
    
    ...
    
    /* The path must be removed from the file name */
       for (i_id=0, i_lg=strlen(s_namfile); s_namfile[i_lg] != '/'; i_lg--)
         {
         i_id = i_id + 1;
         }
    
       for (i_id=0, i_lg=i_lg+1; s_namfile[i_lg] != '\0'; i_lg++)
         {
         s_parfile[i_id] = s_namfile[i_lg];
         i_id = i_id + 1;
         }
       s_parfile[i_id] = '\0';
    
    ...
    Mais une fois compilé en 64 bits j'ai un coredump qui apparait lors de son exécution.
    Un dépassement de mémoire j'imagine...
    La partie du code qui pose pb est celle en gras.

    Comment ne plus avoir ce dépassement de mémoire en 64 bits ? Il faut jouer avec les \0 je pense, mais je n'y connait rien en C.

    Pouvez-vous m'aider svp ?

    Merci

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Il faudrait d'abord que tu lances le programme en mode debug avec un debugger ou alors que tu analyses la stack du core généré (toujours avec le debugger) afin de voir où cela se crash vraiment et à cause de quoi (indice hors bande, mauvais pointeur, string mal terminées, ...).

    Ensuite, on verra ...
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    On part du principe que ta chaîne est bien une réelle chaîne (c'est-à-dire terminée par un '\0'). Il faut bien vérifier dans ton code si c'est le cas, sinon c'est crash assuré.

    Ensuite, es-tu certaine que ta chaîne s_namfile comporte bien un slash à l'intérieur ? Car si ce n'est pas le cas, on court à la catastrophe. Il faut gérer cette possibilité.
    En outre, je ne comprends pas l'utilité d'incrémenter i_id dans ta première boucle puisque au lancement de la seconde, tu mets cette variable à 0.

    J'ai modifié un peu ton code, cela fonctionne chez moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	for (i_lg=strlen(s_namfile) ; i_lg>=0 && s_namfile[i_lg] != '/'; i_lg--) ;
     
    	i_id=0;
    	if (s_namfile[i_lg] == '/') /* sommes-nous bien sortis de la boucle par la présence du slash ? */
    		for (i_lg++ ; s_namfile[i_lg] != '\0'; i_lg++, i_id++)
    			s_parfile[i_id] = s_namfile[i_lg];
     
    	s_parfile[i_id] = '\0';
    Si la chaîne ne contient pas de slash ou que ce slash est le dernier caractère, alors s_partfile sera une chaîne vide (constituée d'un '\0' seulement). Dans le cas contraire, s_partfile contiendra tout ce qui est situé après le dernier slash (au cas où la chaîne s_namfile en contiendrait plusieurs) jusqu'au '\0' final (inclus, donc).

    Je précise (c'est important !) que i_lg>=0 ne sera correct que si i_lg est un type signé. Il faudra sinon manoeuvrer autrement.
    Je ne sais pas quel type tu utilises pour cette variable dans ton programme, j'ai fait au plus simple dans un premier temps.

  4. #4
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 126
    Par défaut
    Merci pour vos réponse...

    Jeroman,

    La chaine s_namfile vaut : /home/rep/toto_20090724_104950_676032

    je ne sais pas si elle se termine par un '\0'

    Je sais que le programme marche en 32 bits donc j'imagine que oui, mais admettons que ça ne soit pas le cas, est-ce que je peux faire ça au début :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    i_id=strlen(s_namfile)+1;
    s_namfile[i_id] = '\0';
    Donc ici, si je comprends bien, là je rajoute '\0' à la fin de ma variable s_namfile


    sinon la déclaration de i_lg est faite comme ça :

    Je vais essayer ton code avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int signed i_lg;
    int i_id;

  5. #5
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 126
    Par défaut
    Bon, j'ai toujours mon erreur...

    Par contre j'ai compilé avec l'option -g et exécuté mon programme avec dbx et voici l'erreur que j'obtiens :

    Segmentation fault in strlen.strlen [/lib/libc.a] at 0x90000000003b024 ($t1)
    0x90000000003b024 (strlen+0x24) 88ac0000 lbz r5,0x0(r12)
    Je ne comprends pas ce que ça veut dire. Quelqu'un peut m'aider pour décrire ce résultat svp ?

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    soit tu mesures la longueur d'une chaine de caractères qui n'est pas finie par un 0
    soit tu mesures la longueur d'une chaine de caractère et le pointeur de cette chaine de caractères est "fou" (valeur aléatoire qui pointe n'importe où)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Citation Envoyé par Cathy Voir le message
    Bon, j'ai toujours mon erreur...

    Par contre j'ai compilé avec l'option -g et exécuté mon programme avec dbx et voici l'erreur que j'obtiens :



    Je ne comprends pas ce que ça veut dire. Quelqu'un peut m'aider pour décrire ce résultat svp ?
    relance ton programme en ayant tappé 'ulimit -c unlimited' avant

    quand tu vas relancer tu aura un fichier coredump qui sera généré.

    ensuite lance le debugger avec ton programme et le fichier coredump en paramètre

    si c'est gdb tu peux faire comme ça

    gdb mon_programe fichier_core

    un fois dans gdb tappe "where" ou "bt" normalement cela te donnera la ligne ou ton programme a crashé


    petit lien utile
    http://www.ibm.com/developerworks/library/l-gdb/


    Segmentation fault in strlen.strlen [/lib/libc.a] at 0x90000000003b024 ($t1)
    0x90000000003b024 (strlen+0x24) 88ac0000 lbz r5,0x0(r12)
    Normalement avec ces information et ton exécutable tu peux retrouver la ligne ou ça a planté grace a un petit calcul sur les adresse et la table des symboles de ton exe, mais je ne sais plus le faire :'(

  8. #8
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    le but de ton algo est de récupérer le nom du fichier?

    tu peux eventuellement regarder si cette fonction existe sur AIX
    http://docs.sun.com/app/docs/doc/816...name-3c?a=view

  9. #9
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    reading symbolic information ...warning: no source compiled with -g
    visiblement ton debugger semble penser que ton exe n'a pas été compilé avec -g

    Autrement ici il y'a une aide pour AIX
    http://publib.boulder.ibm.com/infoce..._coredump.html

  10. #10
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 126
    Par défaut
    Oh non !!

    Je suis désolée, je viens de faire plusieurs tests et il se trouve que lorsque j'exécute :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    fprintf(f_hdr_file, "%s%s %s%s\n", 
               "FUNCTION:", "MAILPOST", s_parfile, ".ack");
    Au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    fprintf(f_hdr_file, "%s%s %s %s %s %s %s%s\n", 
               "FUNCTION:", "MAILPOST", getenv("TOTO_NODE"),
               getenv("UID_UNIX"), getenv("PWD_UNIX"),  
               getenv("Pin"), s_parfile, ".ack");
    ça fonctionne donc mon pb n'est pas du tout lié à s_parfile ni au code servant à l'alimenter

    Je vais chercher quelle variable d'environnement pose pb et pourquoi...

    Merci à tous pour vos conseils, ça m'a bcp servi notamment à comprendre où se trouvait l'erreur.

  11. #11
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Met un point d'arrêt dans fprintf (break in fprintf), et quand tu tombes dessus regarde les arguments du fprintf. Il y en a certainement un qui n'est pas bon (certainement s_parfile).

    En passant, ce n'est pas propre de mettre un getenv() directement dans un printf comme tu le fais. Si la variable d'environement n'existe pas, getenv() retourne NULL, et donc printf va déréfencer le pointeur NULL. Sous AIX ça ne devrait pas poser trop de problème parce que tu as toujours un 0 à l'adresse 0, mais c'est quand même une erreur.

  12. #12
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 126
    Par défaut
    Pb résolu

    Voilà ce que j'ai fait...

    1 - Définir les variables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char acmm_node[200];
    char uid_unix[200];
    char pwd_unix[200];
    char in_directory[200];
    2 - Récupérer les paramètres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    strcpy(acmm_node, getenv("ACMM_NODE"));
    strcpy(uid_unix, getenv("UID_UNIX"));
    strcpy(pwd_unix, getenv("PWD_UNIX"));
    strcpy(in_directory, getenv("IN_DIRECTORY"));
    3 - Ecrire dans le fichier en utilisant les variables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       fprintf(f_hdr_file, "%s%s %s %s %s %s %s%s\n", 
               "FUNCTION:", "MAILPOST", acmm_node,
               uid_unix, pwd_unix,  
               in_directory, s_parfile, ".ack");
    Donc visiblement en copilation 32 bits je peux directement faire un getenv dans un fprintf mais en 64 bits il faut passer par une variable.

    Le mieux étant de toujours passer par une variable

    Encore merci à tous pour votre aide.

    Cat

  13. #13
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Cathy Voir le message
    Donc visiblement en copilation 32 bits je peux directement faire un getenv dans un fprintf mais en 64 bits il faut passer par une variable.

    Le mieux étant de toujours passer par une variable
    Je doute fortement que ton problème vienne réellement de là.
    A priori, je dirais plutôt que tu as un comportement indéterminé quelque part dans ton code et que, manque de chance, le programme semble fonctionné correctement en 32 bits.
    La manipulation que tu as faite a masqué le problème mais ne l'a pas corrigé.

    Au passage, getenv() peut renvoyer NULL si la variable n'est pas trouvé. Il faut tester ce cas.

  14. #14
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Tu as très certainement oublié d'inclure stdlib.h. Donc getenv() n'a pas de prototype, le compilo suppose que ça renvoie un int, et il passe donc un pointeur foireux (tronqué) à printf.

  15. #15
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Chose à savoir, d'expérience, les archi 64 bits sont plus chiantes et laissent moins bien passer les bétises....

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

Discussions similaires

  1. [FLASH MX2004 PRO] Ciblage dynamique dans boucle
    Par guy2004 dans le forum Flash
    Réponses: 8
    Dernier message: 28/02/2006, 10h04
  2. [Ajax] Prob passage de param. dans boucle [DOM]
    Par narnou dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 27/02/2006, 16h54
  3. [JLabel] JLabel dans boucle for
    Par clairenes dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 06/01/2006, 00h47
  4. Réponses: 12
    Dernier message: 10/11/2005, 09h05
  5. Réponses: 3
    Dernier message: 23/06/2004, 21h17

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