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

Linux Discussion :

Message d'erreur en plein programme


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut Message d'erreur en plein programme
    Bonjour tout le monde,

    J'ai un arrêt brutal de mon programme avec ce message d'erreur suivi d'un rapport sur l'état de la mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *** glibc detected *** ./miksh: double free or corruption (fasttop): 0x00000000000603010***
    Apparemment je libère deux fois une allocation mais je ne vois rien dans le programme qui cloche...

    si quelqu'un sait ce que ça veut dire il est le bienvenu...

    Merci d'avance pour les réponses

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 315
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 315
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par PyNub Voir le message
    ...Apparemment je libère deux fois une allocation...
    Tu as tout dit . Maintenant sans code à nous mettre sous la dent on ne peut pas faire grand chose...

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut
    En fait je libère une variable que j'ai créée auparavant sur la pile du coup c'est sûr ça ne marche pas....

    En fait je suis en train de faire un shell. J'ai résolu le problème de la libération.
    Mais j'ai des problèmes avec certains enchainements de commande.
    Par exemple un : cat fichier
    apres un : ps
    Cela vient de ma fonction lecture que j'ai fait un peu vite... Il faut que je revois ça...
    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
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #define MAX_SAIS 50
    #define TRUE 1
     
    void prompt();
    void lecture(char * cmd,char ** params);
     
    char * cmd;
    char ** params;
     
    void clean_stdin(void){
    	int c;
    	do{
    		c=getchar();
    	} while(c!='\n' && c!=EOF);
    }
     
    int main(){
    	int statut;
    	int i=0;
    	pid_t child_pid;
    	while (TRUE){
    		params=(char**)malloc(10);
    		cmd=(char*)malloc(MAX_SAIS);
    		prompt();
    		lecture(cmd,params);
    		child_pid=fork();
    		if (child_pid !=0){
    			printf("%d\t%d\n",getpid(),child_pid);
    			waitpid(-1,&statut,0);
    		}
    		else {
    			printf("%d\n",getpid());
    			execvp(cmd,params);
    			printf("%s\n",cmd);
    			i=-1;
    			do {
    				i++;
    				printf("%s\t",params[i]);
    			}while(params[i]!=NULL);
    			printf("\n");
    		}
    		free(cmd);
    		i=0;
    		do{	
    			free(*(params+i));
    			i++;
    		}while(*(params+i)!=NULL);
    		free(params);
    		i=0;
    		clean_stdin();
    	}
    }
     
    void prompt(){
    	printf("MiKaShEll>> ");
    }
     
    void lecture(char * cmd, char ** params){
    	int i=0;
    	int j=0;
    	int k=0;
    	char tmp[MAX_SAIS];
    	scanf("%[^\n]",tmp);
    	printf("%s\n",tmp);
    	while((tmp[i]!='\0')&&(tmp[i]!='\n')&&(tmp[i]!=' ')&&(i<MAX_SAIS)){
    		*(cmd+i)=*(tmp+i);
    		i++;
    	}
    	*(cmd+i)='\0';
    	*(params+j)=(char*)malloc(MAX_SAIS);
    	while((cmd[k]!='\0')&&(cmd[k]!='\n')&&(cmd[k]!=' ')&&(k<MAX_SAIS)){
    		*(*(params+j)+k)=*(cmd+k);
    		k++;
    	}
    	k=0;
    	j++;
    	if (*(tmp+i)==' ') i++;
    	while((tmp[i]!='\0')&&(tmp[i]!='\n')&&(i<MAX_SAIS)){
    		*(params+j)=(char*)malloc(MAX_SAIS);
    		while((tmp[i]!='\0')&&(tmp[i]!='\n')&&(tmp[i]!=' ')&&(i<MAX_SAIS)){
    			*(*(params+j)+k)=*(tmp+i);
    			i++;
    			k++;
    		}
    		*(*(params+j)+k)='\0';
    		if (tmp[i]=='\n') break;
    		i++;
    		j++;
    		k=0;
    	}
    	*(params+j)=(char*)malloc(MAX_SAIS);
    	*(params+j)=NULL;
    }
    Merci !

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut comprends pas
    Bon j'ai un peu modifié 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
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #define MAX_SAIS 50
    #define TRUE 1
     
    void prompt();
    void lecture(char * cmd,char ** params);
     
    char * cmd;
    char ** params;
     
    void clean_stdin(void){
    	int c;
    	do{
    		c=getchar();
    	} while(c!='\n' && c!=EOF);
    }
     
    int main(){
    	int statut;
    	int i=0;
    	pid_t child_pid;
    	while (TRUE){
    		params=(char**)malloc(10);
    		printf("alloue params : %p\n",params);
    		cmd=(char*)malloc(MAX_SAIS);
    		printf("alloue cmd : %p\n",cmd);
    		prompt();
    		lecture(cmd,params);
    		child_pid=fork();
    		if (child_pid !=0){
    			printf("%d\t%d\n",getpid(),child_pid);
    			waitpid(-1,&statut,0);
    		}
    		else {
    			printf("exécute : %d\n",getpid());
    			execvp(cmd,params);
    			printf("%s\n",cmd);
    			i=-1;
    			do {
    				i++;
    				printf("%s\t",params[i]);
    			}while(params[i]!=NULL);
    			printf("\n");
    		}
    		i=0;
    		do{	
    			printf("libère %p : %s\n",*(params+i),*(params+i));
    			free(*(params+i));
    			printf("libéré\n");
    			i++;
    		}while(*(params+i)!=NULL);
    		printf("libère NULL : %p\n",*(params+i));
    		free(*(params+i));
    		printf("libéré\n");
    		printf("Libère cmd : %p\n",cmd);
    		free(cmd);
    		printf("libéré\n");
    		printf("libère params : %p\n",params);
    		free(params);
    		printf("libéré\n");
    		i=0;
    		clean_stdin();
    	}
    }
     
    void prompt(){
    	printf("MiKaShEll>> ");
    }
     
    void lecture(char * cmd, char ** params){
    	int i=0;
    	int j=0;
    	int k=0;
    	char tmp[MAX_SAIS];
    	scanf("%[^\n]",tmp);
    	printf("%s\n",tmp);
    	*(params+j)=(char*)malloc(MAX_SAIS);
    	while((tmp[i]!='\0')&&(tmp[i]!='\n')&&(tmp[i]!=' ')&&(i<MAX_SAIS)){
    		*(cmd+i)=*(tmp+i);
    		*(*(params+j)+i)=*(tmp+i);
    		i++;
    	}
    	*(cmd+i)='\0';
    	*(*(params+j)+i)='\0';
    	k=0;
    	j++;
    	if (*(tmp+i)==' ') i++;
    	while((tmp[i]!='\0')&&(tmp[i]!='\n')&&(i<MAX_SAIS)){
    		*(params+j)=(char*)malloc(MAX_SAIS);
    		printf("params[%d] alloué %p\n",j,*(params+j));
    		while((tmp[i]!='\0')&&(tmp[i]!='\n')&&(tmp[i]!=' ')&&(i<MAX_SAIS)){
    			*(*(params+j)+k)=*(tmp+i);
    			i++;
    			k++;
    		}
    		*(*(params+j)+i)='\0';
    		printf("params[%d]:\t%s\n",j,*(params+j));
    		if (tmp[i]=='\n') break;
    		i++;
    		j++;
    		k=0;
    	}
    	*(params+j)=(char*)malloc(MAX_SAIS);
    	*(params+j)=NULL;
    	printf("params[%d]:\t%s\n",j,*(params+j));
    }
    J'ai fait en sorte que les allocations et libération mémoire apparaissent. Le programme fonctionne bien avec une commande dès que l'on en place trois c'est la cata... Voici ce que j'obtiens en sortie du programme :
    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
    alloue params : 0x603010
    alloue cmd : 0x603030
    MiKaShEll>> ls -l
    ls -l
    params[1] alloué 0x6030b0
    params[1]:      -l
    params[2]:      (null)
    7982    7984
    exécute : 7984
    total 44
    -rwxr-xr-x 1 mik users 16625 nov. 20 01:51 miksh
    -rw-r--r-- 1 mik users  2179 nov. 20 01:51 miksh.c
    -rwxr-xr-x 1 mik users 12142 sept. 12 23:21 p109
    -rw-r--r-- 1 mik users   842 nov. 12 17:31 p109.c
    -rw-r--r-- 1 mik users   481 nov.  3 19:04 te.c
    libère 0x603070 : ls
    libéré
    libère 0x6030b0 : -l
    libéré
    libère NULL : (nil)
    libéré
    Libère cmd : 0x603030
    libéré
    libère params : 0x603010
    libéré
    alloue params : 0x603010
    alloue cmd : 0x603030
    MiKaShEll>> cp p109.c kk
    cp p109.c kk
    params[1] alloué 0x603070
    params[1]:      p109.c
    params[2] alloué 0x603130
    params[2]:      kk
    params[3]:      (null)
    7982    7986
    exécute : 7986
    libère 0x6030b0 : cp
    libéré
    libère 0x603070 : p109.c
    libéré
    libère 0x603130 : kk
    libéré
    libère NULL : (nil)
    libéré
    Libère cmd : 0x603030
    *** glibc detected *** ./miksh: free(): invalid pointer: 0x0000000000603030 ***
    ======= Backtrace: =========
    etc ...
    A l'aide !

  5. #5
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 315
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 315
    Billets dans le blog
    5
    Par défaut
    Puisque tu limites la longueur de "cmd" tu peux très bien t'éviter une allocation dynamique. Je ferais ce genre de chose:
    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
    int
    main(int argc, char *argv[])
    {
      int statut;
      int i=0;
      pid_t child_pid;
      char cmd[MAX_SAIS];  // Déclaration en locale d un tableau de char.
    
      while (TRUE)
      {
        params=(char**)calloc(10, sizeof(char));
        printf("alloue params : %p\n",params);
    
        // nettoyage de cmd
        for (i=0;i<MAX_SAIS; i++) cmd[i]=' ';
    
    //    cmd=(char*)calloc(MAX_SAIS, sizeof(char));  // Allocation inutile
    //    printf("alloue cmd : %p\n",cmd);
        prompt();
        lecture(cmd,params);  // La transmission du tableau se fait toujours par le pointeur du premier élément.
    ...
    Tu supprimes le free(cmd); devenu lui aussi inutile et le tour et joué .

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut
    Oui je peux essayer, c'est ce que j'ai fait en premier... Mais je ne pense pas que ça résolve mon problème. Le fait d'allouer dynamiquement me permet par la suite de ne pas limiter justement la saisie. Ce que je ne comprends pas c'est que ça marche très bien avec une commande et un argument alors que deux arguments me déclenche une erreur.

    Merci

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

Discussions similaires

  1. Message d'erreur "Fin du programme Member Window"
    Par Ouiwe dans le forum Windows XP
    Réponses: 2
    Dernier message: 13/12/2010, 19h24
  2. Désactiver les messages d'erreur de Fin de programme
    Par spynux dans le forum Windows XP
    Réponses: 4
    Dernier message: 12/09/2007, 20h03
  3. Réponses: 3
    Dernier message: 16/04/2007, 17h01
  4. Afficher un message d'erreur dans un programme !
    Par hadid dans le forum Delphi
    Réponses: 14
    Dernier message: 30/10/2006, 17h32
  5. Help - plein de messages d'erreur après avoir installé Free
    Par fute dans le forum Autres Logiciels
    Réponses: 1
    Dernier message: 18/12/2005, 14h33

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