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 :

Segfault sur Linux mais par sur Mac


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut Segfault sur Linux mais par sur Mac
    Bonjour,

    Je solicite a nouveau votre aide pour un probleme que je n arrive pas a expliquer.
    Le code ci-dessous fonctionne parfaitement sur un Mac x64 bit, mais si je lexecute sur une Debian x32 bit il segfault a la ligne suivante:
    Quelqu un a-t-il une explication?

    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
     
            int		x;
    	 int		y;
    	 int		i;
    	 int	 	fd;
    	 char	buf[LENX * 11];
    	 t_case	**map;
     
    	 if ((fd = open("test.map", O_RDONLY)) == -1)
    		 return ;
     
    	 map = malloc(sizeof(t_case *) * LENY);
    	 y = 0;
    	 while (y < LENY)
    	 {
    		 map[y] = malloc(sizeof(t_case) * LENX);
    		 y++;
    	}
    	y = 0;
    	x = 0;
    	bzero(buf, (LENX * 11) + 1);
    	while (read(fd, buf, (LENX * 11) + 1))
    	{
    		i = 0;
    		while (i < LENX * 11)
    		{
    			if (buf[i] == '[')
    			{
    				map[y][x].unit = NULL; // Segfault
    				x++;
    				if (x == LENX)
    				{
    					x = 0;
    					y++;
    				}
    			}
    			i++;
    		}
    		bzero(buf, (LENX * 11) + 1);
    	}

  2. #2
    Membre éprouvé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Points : 917
    Points
    917
    Par défaut
    salut,

    Il manque des infos à ton exemple pour qu'on puisse t'aider, reproduire le bug. Par exemple la structure t_case ou les macro LENX LENY...

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    oups desole

    Voici les infos manquante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #define LENX      80
    #define LENY     40
     
    typedef struct      s_case
    {
         wchar_t          elem;
         char               *fg;
         char               *bg;
         t_unit             *unit;
    }                         t_case;

  4. #4
    Membre éprouvé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Points : 917
    Points
    917
    Par défaut
    Salut,

    Le segfault se produit lors de l'accès map[y][x].unit.
    Ceci nous indique que tu accèdes à de la mémoire qui ne t'appartient pas.
    En fonction du contenu du fichier que tu lis, celà peut être causé par beaucoup de raisons :

    par exemple un fichier remplie de "[[[[[[[[[[[[[[[[[[[[[[[[[[", y sera incrémenté jusqu'à être supérieur à LENY.

    La meilleur façon de debugger ce programme est de suivre les variables x et y, soit en mettant un point d'arrêt sur la ligne qui segfault, soit, dans le pire des cas, en affichant la valeur de x et de y dans tes boucles (avec un printf pourquoi pas).

    Après pour ce qui est de "ça marche sur mac pas sur linux". Ca peut s'expliquer par beaucoup de chose. Dans certains contexte, en fonction du système d'exploitation et de comment est ta mémoire, tu peux dépasser de quelques octets sans avoir de Segfault. Mais dans tous les cas, un outils comme valgrind sur mac/linux te dira qu'effectivement, tu as un dépassement de mémoire. (Je ne croit pas à la thèse du bug compilo )

  5. #5
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 434
    Points : 43 068
    Points
    43 068
    Par défaut
    Déja, du mac en adressage 64 bits au debian en adressage 32 bits, l'adressage change, ce qui peut justifier le non segfault sur Mac. Par ailleurs, je crois que mac OS X utilise LLVM/CLang à la place de gcc. Donc le code généré peut avoir un comportement différent. Tu ne testes pas le retour de malloc dans la ligne map=malloc. C'est pas bon ça.

    Je ne suis pas développeur donc pas super bon en C mais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    t_case	**map;
    map = malloc(sizeof(t_case *) * LENY);
    pourquoi ** pour t_case **map et * pour malloc(sizeof(t_case *) * LENY);

    Ensuite tu fais une boucle while pour faire des malloc, tu le fais avec une constante connue LENY, je pense qu'ilo vaut mieux faire un malloc(sizeof(element)*LENY).
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  6. #6
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour
    Je doute que votre instruction fonctionne correctement sur un système Mac.
    il y a certaine instruction bizarre voir peut être inutile ( surligné en rouge ).
    Attention un programme fait exactement ce qui est écrit par forcément ce que vous souhaitez qu'il fasse et les bogue ne disparaisse pas non plus tous seule. Dans votre cas il s'agit (pour moi) une incohérence due peut-être à des faux accès à un tableau, pointeur, erreur d'indice ou de comparaison qui sont des sources de bogue majeur .


    Citation Envoyé par punkydev Voir le message
    Bonjour,

    Je solicite a nouveau votre aide pour un probleme que je n arrive pas a expliquer.
    Le code ci-dessous fonctionne parfaitement sur un Mac x64 bit, mais si je lexecute sur une Debian x32 bit il segfault a la ligne suivante:
    Quelqu un a-t-il une explication?

    Code C : 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
            char	buf[LENX * 11];
    	 t_case	**map;
    	
    	 if ((fd = open("test.map", O_RDONLY)) == -1)
    		 return ; // return quoi ? 
    	 map = malloc(sizeof(t_case *) * LENY);
    	 y = 0;
    	 while (y < LENY)
    	 {
    		 map[y] = malloc(sizeof(t_case) * LENX);
    		 y++;	}
    	y = 0;
    	x = 0;
    	bzero(buf, (LENX * 11) + 1);
    	while (read(fd, buf, (LENX * 11) + 1))
    	{
    		i = 0;
    		while (i < LENX * 11)
    		{
    			if (buf[i] == '[')			{
    				map[y][x].unit = NULL; // Segfault
    				x++;
    				if (x == LENX)
    				{
    					x = 0;
    					y++;
    				}
    			}
    			i++;		}
    		bzero(buf, (LENX * 11) + 1);	}
    Dans votre exemple il y a un peu du laisser aller. Quand on n'arrive pas à ouvrir un fichier qui est une des pièces master du programme ( lecture de la carte) faut explicitement afficher les causes de l'erreur et faire remonter l'information exemple:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     FILE *pFile = NULL;
       pFile = fopen( "carte.map", "r" );
       if( (NULL) == pFile ){
     
           /*   Free les allocations 
            *   afficher le message ( la cause )
            *   faire remonter l'information au système
            */
           perror("Erreur ouverture du fichier\n"); 
           return ( EXIT_FAILURE );
       }

    Quand en fait une allocation on n'est pas à l'abri d'un échec alors, toujours vérifier si tout c'est bien passer dans le cas contraire faire le nécessaire.
    Je me suis pas penché en profondeur j'ai lu comme t'elle votre code source (mise à part si je me trompe dans ce cas, d'autre volontaire pour nous éclairer).
    Le soucie vient de votres variables X elle crée une espèce de court-circuit qui crée un segment défaut (préférer une boucle pour qu'une boucle tant que dans cette situation) pour essayer de comprendre voici un code de rien du tout
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    unsigned int x = 5;
       unsigned int y = 5;
       unsigned int r = 0;
     
       r = (x++) * 5; /*    En s'attend a 30*/
     
       printf( "T(1) >>\t:%d\n", r );
       printf( "T(1) (after X) = %d\n", x );
     
       r = (++y) * 5; /*    idem    */ 
       printf( "T(2) >>\t:%d\n", y );
       printf( "T(2) (after y) = %d\n", y );
       return( EXIT_SUCCESS );

    Pour faire simple votre variable X est toujours à zéro et il est comparé avec une constante pour quelle raison je ne sais point, la seule variable qui a ceux niveaux devrait logiquement être évalué est I.
    Ceci dit, même après deux itérations (si je me trompe pas) vous avez les deux variables (X,Y) qui sont à zéro sauf peut-être Y un peut plus tard.
    Mais il se peut que je me trompe complètement.

    Citation Envoyé par EpiTouille Voir le message
    salut,

    Il manque des infos à ton exemple pour qu'on puisse t'aider, reproduire le bug. Par exemple la structure t_case ou les macro LENX LENY...
    Vous avez bien raison de plus il manque des informations concernant les types "t_unit"[/QUOTE]
    Il manque également des informations sur t_unit *unit;
    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  7. #7
    Membre éprouvé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Points : 917
    Points
    917
    Par défaut
    pourquoi ** pour t_case **map et * pour malloc(sizeof(t_case *) * LENY);

    Ensuite tu fais une boucle while pour faire des malloc, tu le fais avec une constante connue LENY, je pense qu'ilo vaut mieux faire un malloc(sizeof(element)*LENY).
    c'est logique en fait, pas d'erreur la dedans. On malloc d'ailleur les colonnes qui sont des t_case* puis enfin, on boucle sur les colonnes afin d'allouer les lignes. Après pour ce genre de cas, on peut aussi faire un gros malloc, mais ce n'est pas la question.

    Pour faire simple votre variable X est toujours à zéro
    Euh non il y a bien un "x++" dans son code

    Vous avez bien raison de plus il manque des informations concernant les types "t_unit"
    Non plus, on sait que c'est un pointeur, donc on a pas besoin de chercher plus loin étant donné que la seul chose qu'on fasse c'est lui assigné la valeur NULL.

    Après pour ce qui est de la gestion d'erreur, ce n'est pas la question. Même si vous avez parfaitement raison.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    J'ai fini par trouver, l'erreur venait d'une mauvaise taille du buffer.
    Et mon Linux n'aimait pas le fait que je n'initialisait pas map[y] juste après avoir fait malloc.
    Ci-dessous le code fonctionnel :

    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
             int		x;
    	 int		y;
    	 int		i;
    	 int	 	fd;
    	 char	        buf[LENX * 11 + 1];
    	 t_case	**map;
     
    	 if ((fd = open("test.map", O_RDONLY)) == -1)
    		 return ;
     
            y = 0;
    	map = malloc(sizeof(t_case *) * LENY);
    	while (y < LENY)
    	{
                    x = 0;
    		bzero(buf, (LENX * 11) + 1);
                    read(fd, buf, (LENX * 11) + 1)
                    map[y] = malloc(sizeof(t_case) * LENX);
    		x = 0;
                    i = 0;
    		while (x < LENX * 11)
    		{
    			if (buf[i] == '[')
    			{
    				map[y][x].unit = NULL;
                                    map[y][x].elem = buf[i + 1];
    				x++;
    				if (x == LENX)
    				{
    					x = 0;
    					y++;
    				}
    			}
    			i++;
    		}
    	}

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

Discussions similaires

  1. [Lazarus] Curseur en couleur : fonctionne sur Windows mais pas sur Linux
    Par ChPr dans le forum Lazarus
    Réponses: 1
    Dernier message: 26/09/2014, 14h43
  2. [XL-MAC 2011] Probleme macro fonctionnant sur PC mais pas sur MAC
    Par mikabop dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 21/01/2012, 17h25
  3. Réponses: 5
    Dernier message: 23/12/2009, 11h31
  4. Réponses: 6
    Dernier message: 28/05/2007, 10h26

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