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 :

my_memset segmentation fault


Sujet :

C

  1. #21
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Crackerz n'a pas mentionné un quelconque message provenant de l'assert...
    Citation Envoyé par Crackerz Voir le message
    La fonction standard memset quand à elle gére bien ce cas puisqu'elle me renvoi : abort ...
    De abort, j'ai proposé l'hypothèse d'un assert, vu qu'assert est connu pour appeler abort() en cas d'échec de l'assertion.

    Ben j'avais parlé d'une boucle de recherche. Bon je l'ai retapée car entre temps j'avais fait d'autres trucs mais je pense qu'elle devait ressembler à ceci:
    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
    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <sys/types.h>
    #include <sys/types.h>
     
    int test(char *adr, size_t i)
    {
    	uintptr_t *pt=(uintptr_t*)adr;
     
    	return ((pt + i) > pt);
    }
     
    int main(){
     
    	char pt[10];
    	size_t i;
    	for (i=1; test(pt, i); i++);
    	printf("i=%lu (%x)\n", i, i);
    }

    Sauf que là, je l'ai lancée plusieurs fois et voici ce que j'ai eu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ~/tmp$ ./essai
    i=269228476 (100c19bc)
    ~/tmp$ ./essai
    i=269393864 (100e9fc8)
    ~/tmp$ ./essai
    i=269329524 (100da474)
    ~/tmp$ ./essai
    i=268961052 (1008051c)
    ~/tmp$ ./essai
    i=268932548 (100795c4)
    Effectivement la valeur change à chaque appel puisque l'adresse de départ change aussi.


    Oui, c'est ce que j'ai eu quand j'ai passé NULL au lieu de pt
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    gcc     essai.c   -o essai
    ~/tmp$ ./essai
    i=1073741824 (40000000)
    ~/tmp$ ./essai
    i=1073741824 (40000000)
    ~/tmp$ ./essai
    i=1073741824 (40000000)
    ~/tmp$ ./essai
    Et quand j'ai remplacé ">" dans le test par ">=" (ton assert), alors je n'ai plus eu de retour pour NULL (effectivement, dans ce cas le test reste toujours vrai)...
    Pourquoi un intptr_t* (qui multiplie donc l'offset par sizeof(intptr_t) au lieu d'un char*?
    Et aussi, ça me paraît bizarre que tu n'affiches pas l'adresse de début alors que tu ne la contrôles pas.
    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.

  2. #22
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Pourquoi un intptr_t* (qui multiplie donc l'offset par sizeof(intptr_t) au lieu d'un char*?
    Ben parce que tu l'avais écrit ainsi !!!

    Citation Envoyé par Médinoc Voir le message
    Et aussi, ça me paraît bizarre que tu n'affiches pas l'adresse de début alors que tu ne la contrôles pas.
    Mon but était de voir à partir de quelle valeur positive de len ton assert renvoyait un "faux positif", empêchant alors tout programmeur de faire un memset de cette taille. Pour ça, l'adresse de pt m'importe peu...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #23
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ben parce que tu l'avais écrit ainsi !!!
    Euh non, j'ai utilisé directement un uintptr_t, pas un pointeur. Tu peux vérifier, mon message n'a pas été édité.
    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.

  4. #24
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Ah oui, tu as raison. C'est moi qui ai mal recopié (et je sais que j'avais fait aussi cette erreur dans mon code d'origine).

    Mais ça ne change pas le concept. Il existe des valeurs positives de len pour lesquelles cet assert aurait considéré un overflow et aurais refusé que memset fasse son boulot
    Tests avec le code corrigé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ~/tmp$ ./essai
    pt=0xbff09282 (3220214402), len=1074752894 (400f6d7e), 0
    ~/tmp$ ./essai
    pt=0xbfc112e2 (3217101538), len=1077865758 (403eed1e), 0
    ~/tmp$ ./essai
    pt=0xbfb6aed2 (3216420562), len=1078546734 (4049512e), 0
    ~/tmp$ ./essai
    pt=0xbfe9c2f2 (3219768050), len=1075199246 (40163d0e), 0
    Et, chose amusante, à chaque ligne, len+pt (la dernière colonne) = 0 c'est à dire 4294967296...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #25
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En effet, je l'ai remarqué dans le message #19. Il faudrait donc spécifiquement rajouter cette condition dans l'assert:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    assert((bufferStart + len) >= bufferStart || (bufferStart + len) == 0);
    (note: L'assert contient >= et non > car je considère une longueur nulle comme valide)
    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.

  6. #26
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Mouais, je crois que là je ne peux plus rien dire et que tu as définitivement résolu la question initiale.

    Allez, +1 parce que je suis sûr que tous les "+1" que j'ai vu un peu partout sur mes récents posts (même sur une question que j'ai posée hier et qui n'était franchement pas révolutionnaire) sont de toi
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Pb segmentation fault avec glutinit()
    Par pipistrelle dans le forum GLUT
    Réponses: 2
    Dernier message: 17/11/2004, 23h17
  2. [SDL_Image] Img_Load : segmentation fault ....
    Par Mathieu.J dans le forum OpenGL
    Réponses: 6
    Dernier message: 19/10/2004, 23h52
  3. [REDHAT] Segmentation fault systematique
    Par mela dans le forum RedHat / CentOS / Fedora
    Réponses: 2
    Dernier message: 21/09/2004, 06h05
  4. Réponses: 13
    Dernier message: 13/07/2004, 15h41
  5. Comment contrer la "segmentation fault" ?
    Par guillaume_pfr dans le forum C
    Réponses: 15
    Dernier message: 08/08/2003, 13h43

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