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 dans fread


Sujet :

C

  1. #21
    Membre expérimenté
    Avatar de Strab
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    338
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 338
    Par défaut
    Citation Envoyé par Trap D
    Pour plus de précaution, fait un fseek(f, 0l, SEEK_SET); qui te remet en début de fichier.
    Tu fais du C ou du C++ ?
    Normalement, fsize s'en charge car le fichier n'est pas lu avant l'appel de calculerHash, mais j'essaierai.
    Je fais du C, sur Linux 2.6.9

  2. #22
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 947
    Par défaut
    Citation Envoyé par Strab
    Normalement, fsize s'en charge car le fichier n'est pas lu avant l'appel de calculerHash, mais j'essaierai.
    C'était effectivement celà que j'évoquais. Il faudrait voir le code en entier, tu dois avoir une erreur avant.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  3. #23
    Membre expérimenté
    Avatar de Strab
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    338
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 338
    Par défaut
    Je ne comprends rien à ce qui se passe.

    Apparemment, le seg fault ne vient pas d'une lecture de src, mais dans f. En effet, d'après gdb, le seg fault survient à une adresse a, et f = a+1 (alors que src est plus "loin"). C'est louche.

    Voulant contourner le problème, je décide de passer par read au lieu de fread. Il y a alors encore un seg fault, mais au moment de l'ouverture cette fois, lorsque je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int fd = open(f, O_RDONLY);
    f est le nom du fichier, issu de la ligne de commande. Que ce soit directement argv[i] ou une copie, le segfault est là...

    Le C m'étonnera toujours par ses erreurs incompréhensibles

  4. #24
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Comme jte dis, c'est un depassement mémoire, et j'ai remarqué que les allocations qui suivent plantent.
    Il se peut que le open fasse un malloc qui plante.
    Faut voir ce qu'il ya avant

  5. #25
    Membre expérimenté
    Avatar de Strab
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    338
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 338
    Par défaut
    Voici le code se déroulant avant le open problématique :
    main.c
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #include "valid.h"
    #include "keygen.h"
    #include "config.h"
    #include "crypt.h"
     
    /* Donne la valeur d'une option, NULL si elle est absente
     * str1 est la version courte de l'argument, str2 est la version longue
     */
    char * valArg(char * str1, char * str2, int argc, char ** argv)
    {
        int i;
        char * result;
        for(i=1; i<argc; i++){
            if( !strcmp(str1, argv[i]) || !strcmp(str2, argv[i]) ){
                if(i<argc-1){
                  result = malloc(strlen(argv[i+1]) + 1);
                  strcpy(result, argv[i+1]);
                  return result;
                } else {
                    fprintf(stderr, "Erreur : la valeur de l'option n'a pas été précisée\n");
                    return NULL;
                }
            }
        }
        return NULL;
    }
     
    /* Indique si un argument est présent */
    int estPresent(char * str1, char * str2, int argc, char ** argv)
    {
        int i;
        for(i=1; i<argc; i++){
            if( !strcmp(str1, argv[i]) || !strcmp(str2, argv[i]) ){
                return 1;
            }
        }
        return 0;
    }
     
    int main(int argc, char ** argv)
    {
        char * progName = valArg("-f", "--fich", argc, argv);
        char * privFile = valArg("-p", "--priv", argc, argv);
        char * pubFile  = valArg("-P", "--pub",  argc, argv);
        char * user     = valArg("-u", "--user", argc, argv);
        int added   = estPresent("-a", "--ajout", argc, argv);
        int deleted = estPresent("-s", "--suppr", argc, argv);
        int crypted = estPresent("-c", "--crypt", argc, argv);
     
        if(progName && privFile){ //Validation d'un programme
     
            cle * c;
            FILE * cle = fopen(privFile, "r");
            if(!cle){
                fprintf(stderr, "Erreur : "
                     "le fichier %s n'a pu être ouvert en lecture.\n", privFile);
                exit(1);
            }
            if(crypted){
                int s = fsize(cle);
                char * msg = malloc(sizeof(char) * (s+1));
                fgets(msg, s+1, cle);
                *c = decrypter(msg, demanderPass());
                //free(msg); le free provoque un segfault (?!?)
            } else {
                c = file2cle(cle);
                if(!c){
                    fprintf(stderr, "Erreur : la clé n'a pu être lue dans %s\n", privFile);
                    exit(1);
                }
            }
     
            if(valider(progName, *c)){
                fprintf(stderr, "Erreur lors de la validation de %s.\n", progName);
                exit(1);
            }
            fclose(cle);
            exit(0);
     
        }
         ... //Autres options
    }
    valid.c
    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
     
    long  size(int fd)
    {
       long savepos, size;
       savepos = lseek(fd, 0, SEEK_CUR);    /* sauvegarder la position  */
       size = lseek(fd, 0, SEEK_END);       /* aller en fin */
       lseek(fd, savepos, SEEK_SET); /* rétablir la position */
       return size;
    }
     
    hash calculerHash(int fd)
    {
        hash h = malloc(sizeof(char)*17);
        if(!h){
          return NULL;
        }
        //long s = fsize(f);
        long s = size(fd);
        char * str = malloc(sizeof(char) * (s+1));
        if(!str){
          return NULL;
        }
        //int lu = fread(str, sizeof(char), s, f);
        int lu = read(fd, str, s);
        if(lu != s){
            fprintf(stderr, "Erreur lors de la lecture du programme.\n");
            return NULL;
        }
        str[s] = '\0';
        hasher(str, h);
        free(str);
        return h;
    }
     
     
    /**
     * Calcule la signature d'un fichier et la concatène à la fin du fichier.
     * @param f - fichier à signer
     * @param p - clé privée 
     */
    int valider(char * f, cle p)
    {
        hash h;
        signature s;
        FILE * stream;
     
        int fd = open(f, O_RDONLY);
        if(fd==-1){
            fprintf(stderr, "Erreur : impossible d'ouvrir %s en lecture.\n", f);
            return -1;
        }
     
        h = calculerHash(fd);
     
       ... //la suite
    }
    Merci à ceux qui auront le courage de lire

  6. #26
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par jamalmoundir
    au lieu
    char * str = malloc(sizeof(char) * (s+1)); il faut mettre
    char * str = malloc(sizeof(char *) * (s+1)); je suis pas sur ,essaye on sait jamais .
    Il faut arréter de programmer au hasard.

    "engage your brain"...

  7. #27
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Il faut arréter de programmer au hasard.
    C'est pas ca qu'on appelle la programmation genetique ?

  8. #28
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Strab
    Voici le code se déroulant avant le open problématique :
    Code incomplet impossible à compiler. Poste le code réduit au minimum qui montre le défaut.

  9. #29
    Membre expérimenté
    Avatar de Strab
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    338
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 338
    Par défaut
    Je commence à avoir une lueur d'espoir (c'est pas mal au bout de 10h...).
    On dirait que le programme arrête de faire des seg faults à des moments arbitraires lorsque je retire l'appel à cette fonction :

    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
     
    char * demanderPass()
    {
        char * pass1 = malloc(sizeof(char) * 32);
        char pass2[32];
     
        printf("Veuillez entrez votre mot de passe (8-31 caractères).\n");
     
        do{
            printf("Password : ");
            fgets(pass1, 32, stdin);
            while(strlen(pass1) < 9){
                printf("Entre 8 et 31 carcactères svp...\n");
                printf("Password : ");
                fgets(pass1, 32, stdin);
            }
     
            printf("Confirm : ");
            fgets(pass2, 32, stdin);
        }while(strcmp(pass1, pass2));
     
        pass1[9] = '\0'; //Je n'ai besoin que des 8 premiers pour l'instant
        return pass1;
    }
    Une idée ?

  10. #30
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Citation Envoyé par Strab
    On dirait que le programme arrête de faire des seg faults à des moments arbitraires lorsque je retire l'appel à cette fonction :
    Surement une coïncidence

  11. #31
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                fgets(msg, s+1, cle);
                *c = decrypter(msg, demanderPass());
                //free(msg); le free provoque un segfault (?!?)
    Si le free plantait c'est peut être que le défaut est dans decrypter()

  12. #32
    Membre expérimenté
    Avatar de Strab
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    338
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 338
    Par défaut
    Je ne trouve toujours pas l'erreur, et je suis de moins en moins sûr que celà de vienne de demanderPass() ou decrypter(). Voici en pièce jointe un code compilable (sous linux), qui seg fault à l'instruction de retour et qui se termine sans problème si je retire l'appel à demanderPass() (sur ma machine de test tout du moins).

    Pour compiler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc (-g) -o valider main.c -lcrypt
    Pour exécuter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./valider -c -f hello -p priv.txt
    où hello est un hello world compilé, et priv.txt un fichier contenant le cryptage DES de la chaine "341&29&0" avec la clé "azertyui" (c'est donc le mot de passe à rentrer lorsqu'il est demander). Je mets aussi le fichier en pièce jointe, car il contient peut-être des caractères non imprimables.

    Je remercie d'avance les bonnes volontés.
    main.c

    priv.txt

  13. #33
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    J'ai compilé, il manquait
    Bon, chuis en train d'installer gdb

  14. #34
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Moi ça plante là, si je met pas le mot de passe que tu as donné
    Sinon, si je mets le bon mot de passe ça plante ici

  15. #35
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    J'ai trouvé
    c'était plus évident que je pensais (mais j'ai pas trouvé desuite cela dit)

    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
    int main(int argc, char ** argv)
    {
        char * progName = valArg("-f", "--fich", argc, argv);
        char * privFile = valArg("-p", "--priv", argc, argv);
        int crypted = estPresent("-c", "--crypt", argc, argv);
    
        if(progName && privFile){ //Validation d'un programme
    
    	cle * c;
    	FILE * cle = fopen(privFile, "r");
    	if(!cle){
    	    fprintf(stderr, "Erreur : "
    		 "le fichier %s n'a pu être ouvert en lecture.\n", privFile);
    	    exit(1);
    	}
    
    	if(crypted){
    	    int s = fsize(cle);
    	    char * msg = malloc(sizeof(char) * (s+1));
    	    fgets(msg, s+1, cle);
    	    *c = decrypter(msg, demanderPass());
    	    free(msg);
    	} 
    
    	if(valider(progName, *c)){
    	    fprintf(stderr, "Erreur lors de la validation de %s.\n", progName);
    	    exit(1);
    	}
    	fclose(cle);
    	exit(0);
    
        } else { //Options incohérentes
    	fprintf(stderr, "Erreur, les arguments sont incohérents\n");
    	fprintf(stderr, USAGE, argv[0], argv[0], argv[0]);
        }
        return 0;
    }
    Ca plantait sur le return du decrypter() par ce qu'il essayait d'ecrire dans *c, alors que c pointe dans l'espace intersidéral.

  16. #36
    Membre expérimenté
    Avatar de Strab
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    338
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 338
    Par défaut
    AAAAAAAARRRGGHHHHHHHH

    une journée entière pour une erreur aussi stupide !

    Merci beaucoup Gruik, grâce à toi ce 24h-debug s'est transformé en relais-debug .

    C'est décidé, je hais le C. J'ai beau avoir acquis pas mal de réflexes, je retombe toujours sur des erreurs incompréhensibles à cause de ces pointeurs à la noix. Oh j'arrête de me plaindre et je retourne coder, ou dormir plutôt, c'est que je passe le toeic demain .

    Encore merci gruik, et tous ceux qui m'ont donné un peu de leur temps.
    Strab

  17. #37
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Strab
    C'est décidé, je hais le C.
    Si tu n'aimes pas les pointeurs, ne fait pas de C.

    Il y a quand même des regles de bon sens, comme donner tout de suite une valeur cohérente à un pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    T *p = NULL;
    T *p = malloc(...)
    T *p = f(...)
    mais jamais
    tout seul comme ça. C'est la porte ouvert à la catastrophe... Mais bon quand on fait du C, on jongle avec ça. Sinon, on fait autre chose...

    Pas de quoi 'hair le C'. C'est pas un instrument de débutant. On est d'accord. C'est un outil tranchant...

  18. #38
    Membre expérimenté
    Avatar de Strab
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    338
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 338
    Par défaut
    Hola, je ne voulais pas blesser les adeptes du C, je plaisantais.
    Si je haissais le C, je ne me serais pas lancé dans ce projet où la plus grande partie consiste en des modifications du noyau...

    Les règles de bon sens que tu donnes ne s'appliquent pas lorsque c'est le pointeur ou son contenu qui sont initialisés suivant les cas (cela ne se voit pas ici car j'ai retiré beaucoup de code pour le poster), surtout lorsqu'on ces différents cas ont été implentés à des intervalles de temps assez espacés.

    Et oui, C est un outil puissant mais tranchant, mais les langages qui font presque autant de chose à un niveau beaucoup plus haut (cf ma signature )sont tellement pratiques qu'on en perd certaines habitudes...

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. [Tomcat] configuration d'une page d'erreur dans web.xml
    Par Super Castor dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 08/04/2009, 15h58
  2. [Thread] Erreur dans une classe interne
    Par totof2308 dans le forum Général Java
    Réponses: 5
    Dernier message: 03/06/2004, 08h15
  3. [Lien]erreur dans mon programme python
    Par durnambule dans le forum Général Python
    Réponses: 11
    Dernier message: 29/01/2004, 14h59
  4. [Erreur dans la lib...]
    Par Gonath dans le forum OpenGL
    Réponses: 3
    Dernier message: 22/12/2003, 09h02
  5. Erreur dans l'utilisation de SWAP
    Par mire dans le forum Langage
    Réponses: 12
    Dernier message: 15/03/2003, 21h39

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