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 :

SIGABRT sur un fclose()


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut SIGABRT sur un fclose()
    Bonjour,
    je code un projet d'intelligence artificielle en C.
    Dans une fonction, j'ouvre un fichier de mots considérés comme inutiles (pronoms, déterminants...) et je mets chaque mot dans un tableau de chaines. D'un moment à l'autre, mon programme ne marche plus : sigabrt lorsque je fais le fclose... je ne suis pas débutant et je ne vois pas d'où ca peut venir. Je sais que fopen fais des malloc et que fclose des free et qu'il y a des soucis la dedans car ca plante sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *** Error in `./jacek': free(): invalid next size (normal): 0x00000000024b9130 ***
    mais je ne vois pas ou.. voici le coeur de ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    if(fichier != NULL){
      i = 0;
      while(fgets(buff,TAILLE_MOT,fichier) != NULL){
        strcpy(tab_char[i] , buff);
        i++;
      }
      fclose(fichier);
    }else{
      fprintf(stdout, "Erreur du chargement du fichier liste_useless.txt\n");
      exit(EXIT_FAILURE);
    }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Bonjour et bienvenue,

    SIGABRT (« Abort ») est un signal émis assez rarement, soit directement avec l'appel abort(), soit par des bibliothèques qui y font appel dans le cas d'exceptions. En particulier les exceptions C++ non rattrapées mais également dans le cas d'erreurs fatales rencontrées par les bibliothèques système (donc faisant partie du processus, et pas du noyau).

    Ici, c'est free() qui pose problème, vraisemblablement parce que le descripteur de la zone à libérer a été corrompu. Cela peut arriver parfois quand on tente de libérer deux fois le même espace, mais également si le pointeur que l'on passe à free() est invalide.

    En réalité, il est fort probable que le problème soit provoqué par ton appel à strcpy() qui ne s'arrête pas à temps, dépasse les limites de ton buffer et va écraser ce qui se trouve juste après, c'est-à-dire tes autres variables et, parmi elles, le pointeur vers le descripteur de fichier. Ici, typiquement, tu incrémentes i à chaque nouveau mot et tu contrôles la taille des buffers, mais tu ne poses pas de limite quant au nombre maximum de mots. Il suffit alors d'en rajouter quelques uns dans le fichier à lire pour faire planter ton programme.

    Les dépassements de tampon sont un problème extrêmement fréquent en C. Tu devrais également jeter un œil à la fonction strncpy().

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Merci et merci de votre réponse.

    Merci pour les précisions, j'en ai appris pas mal c'est cool !

    Sans vouloir vous contredire, j'ai quelques petites précisions à apporter par rapport à votre message :
    - tab_char est défini comme char tab_char[NB_MOTS_INUTILES][TAILLE_MOT] où à ce jour c'est [250][20]. Dans mon fichier j'ai 134 lignes de mots, chacun font moins de 11 lettres (oui, ce n'est pas optimisé, mais la flemme de prendre la tete avec des mallocs et des frees pour ce projet...bref)
    - l'erreur est survenue d'un moment à l'autre, sans re compilation... en fait je dispose d'un fichier contenant des questions, que j'etais en train de modifier. Pour voir le nouveau resultat, j'ai tout simplement lancé le programme et crack... après compilation même chose. Le programme marchait très bien cet après-midi
    - mes questions sont, elles, stockées dans une structure allouée dynamiquement qui donc normalement évite les problèmes de dépassement de buffers

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Voici le retour de gdb si ca peut aider :

    #0 0x00007ffff7a4bcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
    #1 0x00007ffff7a4f0d8 in __GI_abort () at abort.c:89
    #2 0x00007ffff7a88394 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff7b96b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
    #3 0x00007ffff7a9466e in malloc_printerr (ptr=<optimized out>, str=0x7ffff7b96ca0 "free(): invalid next size (normal)", action=1) at malloc.c:4996
    #4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
    #5 0x00007ffff7a82ae5 in _IO_new_fclose (fp=0x606130) at iofclose.c:85
    #6 0x000000000040113b in charger_liste_mots_inutiles (tab_char=0x7fffffffae30) at analyse_reponse.c:42
    #7 0x000000000040119c in est_a_supprimer (token=0x7fffffffd6f0 "oui\n") at analyse_reponse.c:58
    #8 0x00000000004014d0 in decoupe_reponse_token (q=..., reponse_brute=0x7fffffffdbe0 "oui\n") at analyse_reponse.c:128
    #9 0x0000000000400ecd in main (argc=1, argv=0x7fffffffdfb8) at main.c:61

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par Dayan42 Voir le message
    #6 0x000000000040113b in charger_liste_mots_inutiles (tab_char=0x7fffffffae30) at analyse_reponse.c:42
    #7 0x000000000040119c in est_a_supprimer (token=0x7fffffffd6f0 "oui\n") at analyse_reponse.c:58
    #8 0x00000000004014d0 in decoupe_reponse_token (q=..., reponse_brute=0x7fffffffdbe0 "oui\n") at analyse_reponse.c:128
    #9 0x0000000000400ecd in main (argc=1, argv=0x7fffffffdfb8) at main.c:61
    Il faudrait que l'on sache si l'extrait que tu nous montres correspond bien à la ligne, au fichier et à la fonction décrits en tête de ce bloc.

    Ensuite, il faudra continuer à déboguer ton programme. Le fait qu'il se mette à planter sans recompilation est tout-à-fait compatible avec ce que l'on a dit au-dessus : soit le bug était latent (et peut-être provoqué par une autre partie du programme) et ton application ne fonctionnait que par chance, soit les données du fichier d'entrée ont varié et sont devenues invalides. C'est possible par exemple s'il y a des espaces en fin de ligne après tes mots.

    La première chose à faire dans un premier temps est de placer des breakpoints aux lignes 3 et 8 de l'exemple que tu nous donnes dans ton premier commentaire. À la ligne 3, examine la valeur de « fichier ». À la ligne 8, vérifie qu'elle est restée inchangée (donc pas écrasée) puis examine à son tour la valeur de « i » pour être sûr qu'elle n'a pas dépassé les limites de ton tableau (pour quelque raison que ce soit). Si tout est OK de ce côté-là, c'est que la corruption a eu lieu plus tôt dans l'exécution de ton programme et il va falloir « remonter le fil » pour savoir où exactement.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    J'ai trouve !
    Merci, c'est votre histoire d'espaces en fin de ligne qui m'as mis la puce à l'oreille...
    Pour plus de rapidité j'ai édité mon fichier de questions sous Windows (mea culpa) car j'utilise Dragon Naturally Speaking, et les \r de fin de ligne en plus des \n faisait tout planter ! Merci Windows encore une fois...
    J'ai débogué et aucun mauvais signe, j'ai fait aussi tourné valgrind, qui ne me dit rien de bien inquiétant.
    En tous cas merci merci je vais pouvoir continuer à travailler !

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par Dayan42 Voir le message
    En tous cas merci merci je vais pouvoir continuer à travailler !
    À ton service mais n'oublie pas le bouton « résolu » en bas de page pour signaler la discussion comme telle (il est possible de la faire repasser à l'état non résolu si nécessaire).
    Je l'ai fait pour toi cette fois-ci.

    Bon courage.

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

Discussions similaires

  1. Seg Fault sur un fclose
    Par XstasY dans le forum Débuter
    Réponses: 8
    Dernier message: 31/03/2010, 00h11
  2. Documentation gratuite sur l'API Windows, COM, DCOM, OLE, etc.
    Par Community Management dans le forum Windows
    Réponses: 1
    Dernier message: 16/11/2006, 15h28
  3. Segmentation Fault sur un fclose
    Par Beush dans le forum C
    Réponses: 9
    Dernier message: 30/11/2005, 19h30
  4. [Kylix] Kylix embarqué sur PDA ?
    Par Anonymous dans le forum NoSQL
    Réponses: 10
    Dernier message: 29/11/2002, 13h59
  5. F.A.Q, Doc, cours, tutoriels sur JBuilder
    Par Ricky81 dans le forum JBuilder
    Réponses: 0
    Dernier message: 14/03/2002, 15h28

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