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 :

Erreur de segmentation tardive


Sujet :

C

  1. #1
    Nouveau candidat au Club
    Étudiant
    Inscrit en
    Janvier 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2
    Par défaut Erreur de segmentation tardive
    Bonsoir,
    pour commencer, voici le 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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main () {
      int* foo = NULL;
      int i = 0;
     
      foo = malloc(sizeof(int));
     
      while (1) {
        foo[i] = i;
        printf("%i\n", foo[i]);
        i++;
      }
     
      return 0;
    }
    l'oeil du programmeur avisé y voit normalement une magnifique erreur de segmentation, dès la seconde itération, puisque l'on tente d'accéder à un bout de mémoire non alloué par le programme... or celle-ci ne survient qu'après... 262111 itérations !!

    Je me doute qu'il ne s'agit pas d'un bug, mais est-ce dû au compilateur effectue quelques tests préliminaires pour définir une taille suffisante (ou pas) lors de l'allocation, ou est-ce le gestionnaire de mémoire de mon OS qui a tendance à être laxiste ? À moins que cela-soit un comportement tout à fait normal, auriez-vous davantage d'informations ?

    Voici ma commande de compilation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -02 -Wall -W -Werror -pedantic -ansi main.c -o out
    Merci d'avance !

    Ps: je sors de plusieurs mois d'OCaml et de Pascal, quel choc !

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 071
    Billets dans le blog
    144
    Par défaut
    Bonjour,

    Question que je retourne souvent dans ma tête ( bien que maintenant je pense être assez proche de la solution ).

    Pourquoi peut on faire des accès lectures de la mémoire, même si celle ci n'est pas à nous? C'est ce qui se passe dans votre code, j'ai juste reformuler la problématique.
    Et surtout pourquoi un nombre tel que 26211.
    En fait, le nombre 26211, n'est pas aléatoire ( par pour la machine du moins ), est dépend de tout ce qui se passe ( ou c'est passé dans la machine ).

    En fait, l'erreur de segmentation arrivera lorsque le programme commencera à lire de la mémoire qui appartient à quelqu'un d'autre. Je veux dire que par là, si les 26211 blocs de mémoire n'appartienne à aucun processus, le système ne lancera pas d'erreur de segmentation.

    Tout cela dépend aussi du système. Je connais un système ultra strict qui plantera dès le premier mauvais accès en mémoire.

    Maintenant, il faut savoir que pour Linux nous avons valgrind.
    Valgrind est une merveille de la techonogie ( peut être pas, mais il est très bien ), il permet de voir les fuites de mémoires, mais aussi tous les erreurs d'accès mémoire ( comme celui de votre programme ).
    Pour chaque mauvais accès, il va reporter une erreur ( qui peut se reveler très précise, avec l'option de compilation -g ( pour le programme à debugguer )).

    Voilà, je crois que j'ai tout dit
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    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 452
    Par défaut
    Bonsoir,

    Citation Envoyé par Sheelda Voir le message
    l'oeil du programmeur avisé y voit normalement une magnifique erreur de segmentation, dès la seconde itération, puisque l'on tente d'accéder à un bout de mémoire non alloué par le programme... or celle-ci ne survient qu'après... 262111 itérations !
    Pour compléter ce que dit LittleWhite, la segfault n'est pas un code d'erreur de la bibliothèque C. C'est une exception qui est levée par le micro-processeur lui-même, électroniquement, lorsque qu'une instruction tente de faire un accès mémoire en dehors du segment qui a été défini au préalable par le système. Cela peut se passer avec n'importe quel langage.

    À dire vrai, sur les machines qui ne disposent pas d'un mode protégé (ce qui fut le cas des PC pendant relativement longtemps), aucun contrôle n'est effectué et le programme fou peut très bien aller écraser les autres programmes voire le système d'exploitation lui-même. Pour autant, ça n'a pas empêché l'informatique de se développer.

    Dans le cas présent, la mémoire est généralement allouée par blocs au processus qui en fait la demande et même si la quantité de mémoire utilisée tombe juste, il y a toujours des données en plus de ton tableau (cadre de pile, autres variables, etc.) ce qui explique que tu peux parcourir beaucoup de chemin avant d'atteindre la limite imposée. Tu risques également de faire beaucoup de dégats, mais seulement dans ton propre processus. :-)

    Citation Envoyé par LittleWhite Voir le message
    En fait, l'erreur de segmentation arrivera lorsque le programme commencera à lire de la mémoire qui appartient à quelqu'un d'autre. Je veux dire que par là, si les 26211 blocs de mémoire n'appartienne à aucun processus, le système ne lancera pas d'erreur de segmentation.
    Es-tu sûr de ce que tu avances ? Il me semble qu'à partir du moment où tu sors de ton propre segment, l'erreur de segmentation se déclenche. En revanche, le segment de mémoire couvre tout ce qui est alloué au processus.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Ça fait longtemps que les systèmes 32 bits travaillent en modèle "plat" (où les segments couvrent toute la mémoire).

    Ici, c'est une plutôt un histoire de page, je pense.
    Le malloc() débloque une page et écrit des données au début, puis quand on sort de la page, on a une Access Violation ou une SegFault selon l'OS...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Nouveau candidat au Club
    Étudiant
    Inscrit en
    Janvier 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2
    Par défaut
    Merci pour vos réponses ! À choisir, je dois avouer que je préfère les langages comme OCaml où ce type de programme déclencherait un "index out of bounds" dès la seconde itération.

    J'en étais arrivé plus ou moins à la même conclusion que toi, LittleWhite, j'ai donc essayé de lancer plusieurs autres programmes après avoir déclenché mon bout de code... l'erreur survient toujours après le mm nombre d'itérations. Idem après un reboot de la machine, pourtant je suppose que l'état de la mémoire est totalement différent !

    Je suis donc plutôt de l'avis d'Obsidian, à savoir qu'il est possible de faire n'importe quoi dans la mémoire du moment que l'on reste dans l'espace alloué au programme.

    En tout cas merci pour vos réponses !
    (et je vais de ce pas chercher ce "Valgrind" )

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Citation Envoyé par Sheelda Voir le message
    l'erreur survient toujours après le mm nombre d'itérations. Idem après un reboot de la machine, pourtant je suppose que l'état de la mémoire est totalement différent !
    C'est normal: L'OS donne la mémoire page par page, donc ce qui se passe au sein d'une page ne dépend que du programme et de ses entrées. Pas de changement dans le programme, pas de changement dans le comportement.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 071
    Billets dans le blog
    144
    Par défaut
    Je reviens, pour rajouter que je me range de l'avis de Médinoc. ( J'ai demandé à un collègue qui connait mieux que moi ), et il m'a parlait des pages ( truc que j'oublie toujours ).

    Donc l'erreur de segmentation arrive au moment ou l'on commence à sortir de la page mémoire utilisé par le processus. La taille des pages dépendent du système ( kernel ? ).

    @Obsidian, ce que j'ai dit est surement faux. Ce que je disais, partait de simple hypothèses ... ( désolé ). ( j'avais écrit en première phrase de ma réponse, que c'est un truc que je retourne dans tout les sens dans ma tête )

    Par contre, ( je ne sais pas si c'est possible ), je dirai que si deux processus se partage la même page, je pense que le système va arrêter le processus qui va tenter de toucher à la mémoire de l'autre. ( Cas surtout présent en écriture ).

    Par contre, dire que la seg fault est un évènement electronique me semble faux. C'est juste le système d'exploitation qui va complètement stoppé l'execution du processus pour dire toi, tu fais une chose nuisible à ma stabilité ( ou a celle de mes processus ) je te grille la face ( et on en parle plus ).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    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 452
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Par contre, dire que la seg fault est un évènement electronique me semble faux. C'est juste le système d'exploitation qui va complètement stoppé l'execution du processus pour dire toi, tu fais une chose nuisible à ma stabilité ( ou a celle de mes processus ) je te grille la face ( et on en parle plus ).
    Oui, mais pour cela, il faut qu'il ait la main. Si c'est ton programme qui est en train de s'exécuter à un moment t, ce n'est donc pas les routines de l'O.S. qui sont interprétées. Ton programme a donc le temps, en théorie, d'aller effacer toute la mémoire avant que le timer déclenche une interruption et que l'O.S., qui n'existera probablement plus à ce stade, ne reprenne la main pour la donner à un autre processus.

    Pour être sûr qu'un programme compilé en langage machine (cas des exécutables en C) − et directement exécuté par le micro-processeur − n'aille pas faire des folies un peu partout dans la mémoire, c'est le micro-processeur lui-même qui doit être pourvu d'un système déclenchant une exception plutôt que laissant l'exécution suivre son déroulement quand ce programme dépasse son rayon d'action. Une fois l'exception déclenchée, elle est redirigée vers une routine de l'O.S. qui, ensuite, prendra les mesures nécessaires.

    Le principe est le même pour les instructions privilégiées, au demeurant.

Discussions similaires

  1. Erreurs de segmentation !
    Par anti-conformiste dans le forum Applications et environnements graphiques
    Réponses: 16
    Dernier message: 18/10/2005, 11h11
  2. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 18h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 13h42
  4. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18

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