Forum Programmation.c++ memory corruption

Posté par  .
Étiquettes : aucune
0
17
sept.
2007
salut tout le monde,

apres quelques semaines de debogage desesperé, je me tourne vers vous, j'ai un prgrammes qui me fais un "memory corruption", avec DDD j'aivu que c'etait sans les ligne ou j'avais free(), alors j'ai enlevé tout les free, mais il veut rien comprendre, voila ce qu'il m'affiche :
*** glibc detected *** ./main: malloc(): memory corruption: 0x081dfb18 ***
======= Backtrace: =========
/lib/libc.so.6[0xb778e6e1]
/lib/libc.so.6[0xb7790671]
/lib/libc.so.6(__libc_malloc+0x85)[0xb77920c5]
/usr/lib/libstdc++.so.6(_Znwj+0x27)[0xb792e477]
/usr/lib/libstdc++.so.6(_ZNSs4_Rep9_S_createEjjRKSaIcE+0x6b)[0xb7909feb]
/usr/lib/libstdc++.so.6(_ZNSs4_Rep8_M_cloneERKSaIcEj+0x38)[0xb790aba8]
/usr/lib/libstdc++.so.6(_ZNSs7reserveEj+0x48)[0xb790b718]
/usr/lib/libstdc++.so.6(_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi+0xa3)[0xb7904343]
/usr/lib/libstdc++.so.6(_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKci+0x81)[0xb79091d1]
/usr/lib/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intIlEES3_S3_RSt8ios_basecT_+0x127)[0xb78f7367]
/usr/lib/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecl+0x50)[0xb78f75d0]
/usr/lib/libstdc++.so.6(_ZNSolsEi+0xcd)[0xb78ffded]
./main[0x804f7ed]
./main[0x804f092]
./main(__gxx_personality_v0+0x39f)[0x804e0b3]
/lib/libc.so.6(__libc_start_main+0xdc)[0xb773ff9c]
./main(__gxx_personality_v0+0x21d)[0x804df31]
======= Memory map: ========
08048000-0807e000 r-xp 00000000 08:02 2539727 /home/mehdi/Desktop/Racine/Developpement/PFE/kdevelopFirst/main/debug/src/main
0807e000-0807f000 r--p 00035000 08:02 2539727 /home/mehdi/Desktop/Racine/Developpement/PFE/kdevelopFirst/main/debug/src/main
0807f000-08080000 rw-p 00036000 08:02 2539727 /home/mehdi/Desktop/Racine/Developpement/PFE/kdevelopFirst/main/debug/src/main
08080000-08297000 rw-p 08080000 00:00 0 [heap]
b07f1000-b0fc3000 rw-p b07f1000 00:00 0
b0fc3000-b0fc4000 ---p b0fc3000 00:00 0
b0fc4000-b1bad000 rw-p b0fc4000 00:00 0
b1f96000-b1f97000 ---p b1f96000 00:00 0
b1f97000-b3352000 rw-p b1f97000 00:00 0
b373b000-b42f6000 rw-p b373b000 00:00 0
b46df000-b46e0000 ---p b46df000 00:00 0
b46e0000-b4ee0000 rw-p b46e0000 00:00 0
b4ee0000-b4ee1000 ---p b4ee0000 00:00 0
b4ee1000-b56e1000 rw-p b4ee1000 00:00 0
b56e1000-b56e2000 ---p b56e1000 00:00 0
b56e2000-b5ee2000 rw-p b56e2000 00:00 0
b5ee2000-b5ee3000 ---p b5ee2000 00:00 0
b5ee3000-b6acc000 rw-p b5ee3000 00:00 0
b6f1a000-b6f1b000 ---p b6f1a000 00:00 0
b6f1b000-b771d000 rw-p b6f1b000 00:00 0
b771d000-b7727000 r-xp 00000000 08:02 3866687 /lib/libgcc_s.so.1
b7727000-b7729000 rw-p 00009000 08:02 3866687 /lib/libgcc_s.so.1
b7729000-b772a000 rw-p b7729000 00:00 0
b772a000-b7852000 r-xp 00000000 08:02 3866643 /lib/libc-2.5.so
b7852000-b7853000 r--p 00128000 08:02 3866643 /lib/libc-2.5.so
b7853000-b7855000 rw-p 00129000 08:02 3866643 /lib/libc-2.5.so
b7855000-b7858000 rw-p b7855000 00:00 0
b7858000-b787c000 r-xp 00000000 08:02 3866651 /lib/libm-2.5.so
b787c000-b787e000 rw-p 00023000 08:02 3866651 /lib/libm-2.5.so
b787e000-b7957000 r-xp 00000000 08:02 558929 /usr/lib/libstdc++.so.6.0.8
b7957000-b795a000 r--p 000d9000 08:02 558929 /usr/lib/libstdc++.so.6.0.8
b795a000-b795c000 rw-p 000dc000 08:02 558929 /usr/lib/libstdc++.so.6.0.8
b795c000-b7962000 rw-p b795c000 00:00 0
b7962000-b7964000 r-xp 00000000 08:02 3866649 /lib/libdl-2.5.so
b7964000-b7966000 rw-p 00001000 08:02 3866649 /lib/libdl-2.5.so
b7966000-b7977000 r-xp 00000000 08:02 3866700 /lib/libz.so.1.2.3
b7977000-b7979000 rw-p 00010000 08:02 3866700 /lib/libz.so.1.2.3
b7979000-b79e1000 r-xp 00000000 08:02 558906 /usr/lib/libfreetype.so.6.3.10
b79e1000-b79e3000 r--p 00068000 08:02 558906 /usr/lib/libfreetype.so.6.3.10
b79e3000-b79e5000 rw-p 0006a000 08:02 558906 /usr/lib/libfreetype.so.6.3.10
b79e5000-b79e6000 rw-p b79e5000 00:00 0
b79e6000-b79fa000 r-xp 00000000 08:02 3866669 /lib/libpthread-2.5.so
b79fa000-b79fc000 rw-p 00013000 08:02 3866669 /lib/libpthread-2.5.so
b79fc000-b79fe000 rw-p b79fc000 00:00 0
b79fe000-b7a0e000 r-xp 00000000 08:02 3866708 /lib/libbz2.so.1.0.0
b7a0e000-b7a10000 rw-p 0000f000 08:02 3866708 /lib/libbz2.so.1.0.0
b7a10000-b7a14000 r-xp 00000000 08:02 558864 /bin/sh: line 1: 21805 Abandon ./main


le probleme c'est que je n'y comprend rien . La methode qui cause ça est la suivante:
BUFFER Compression::getCompressedImage(BUFFER img, long int *length)
{
char *retBuff;
Magick::Image image;
Magick::Blob blob;


blob.update(img, *length);
image.read(blob);
image.magick( "JPEG" );
image.quality(this->getQuality());
image.write(&blob);
*length = blob.length();
retBuff = (char*) malloc (*length);
memcpy(retBuff, blob.data(), *length);
return retBuff;
}


à l'aiide svp; toute remarque est la bienvenue.

merci d'avance
  • # re:

    Posté par  . Évalué à 1.

    opps j'avais oublié, la ligne responsable est la ligne

    <code>image.read(blob);</code>

    PS : je n'arrive pas à editer le premeir poste, desolé pour le double.
    • [^] # Re: re:

      Posté par  . Évalué à 2.

      C'est une interruption générique lancée par la glibc elle-même.

      En général, elle arrive lorsque l'on tente de faire un free() ou un realloc() sur un pointeur dont le contenu a été modifié de façon incorrecte.
      • [^] # Re: re:

        Posté par  . Évalué à 1.

        y a t-il un moyen de surveiller les modifications des pointeurs ? je pense que c'est difficile avec DDD non ?

        merci d'ailleurs pour la reponse rapide.
        • [^] # Re: re:

          Posté par  . Évalué à 2.

          Je ne connais pas DDD, donc je ne peux pas te donner la marche à suivre mais à vue de nez :

          - Tu peux essayer un try { } catch (...) { } autour de ton code pour essayer de rattraper quelque chose mais ça m'étonnerait que ça marche. C'est la libc qui se plaind et il est peu probable (mais pas impossible) qu'elle communique avec la libstdc++.

          - Il faudrait compiler ton affaire avec l'option -g si ce n'est pas fait par défaut (mode debug). Si la libc++ arrive à rattraper l'exception, DDD ou GDB seront capables de te montrer exactement quelles étaient les fonctions en cours d'exécution au moment du crash.

          - Je ne sais pas du tout comment fonctione la lib Magick, mais il y a des chances pour que le BLOB déclaré au dessus ait besoin d'être préalablement initialisé d'une manière ou d'une autre avant usage ... A creuser.
        • [^] # Valgrind

          Posté par  (site web personnel) . Évalué à 3.

          Tu peux exécuter ton programme avec valgrind qui t'aidera à trouver les problèmes d'utilisation de la mémoire.
          http://valgrind.org/
          • [^] # Re:

            Posté par  . Évalué à 1.

            merci tout les deux pour ces suggestions, je vais faire et je vous tiendrai au courant.

            juste une autre chose, est-ce que vous pouvais me donner un example de ce que Obsidian a dit ("modifié d'une façon incorrecte"), ça pourais m'aider a identifier l'erreur.

            merci encore
            • [^] # Re: Re:

              Posté par  . Évalué à 2.

              $ vi memcorrupt.c++

              int main (void)
              {
              delete (new char[4096]+256);
              return 0;
              }


              $ g++ memcorrupt.c++ -o memcorrupt
              $ ./memcorrupt

              *** glibc detected *** ./mai

              Même chose en C :

              #include <stdlib.h>

              int main (void)
              {
              free (malloc(4096)+256);
              return 0;
              }


              L'idée est de passer aux routines de gestion de la mémoire qui reste dans l'espace d'adressage du processus (ce qui fait que le processeur ne segfaulte pas) mais qui ne corresponde malgré tout à rien de valable.

              Si cela se produit au sein de la lib Magick, soit c'est un bug, soit la fonction incriminée essaie de faire des opérations sur un objet qu'elle suppose prêt à être utilisé et qui ne l'est pas.
              • [^] # Re: Re:

                Posté par  . Évalué à 2.

                merci infiniment pour ta precieuse aide. je vais analyser mon code au cas ou ça venait de chez moi ;

                merci encore
                • [^] # Re: Re:

                  Posté par  . Évalué à 2.

                  You're welcome.
              • [^] # Re: Re:

                Posté par  . Évalué à 1.

                merci infiniment pour ta precieuse aide. je vais analyser mon code au cas ou ça venait de chez moi ;

                merci encore
                • [^] # Re: Re:

                  Posté par  . Évalué à 2.

                  Quelqu'un reconfigure la matrice, on dirait ...
                  • [^] # Re: Re:

                    Posté par  . Évalué à 3.

                    entre 0:25 et 0:50, ce n'est pas etonnant,
                    c'est la que les gens dorment et que l'on peut donc operer discretement.
                  • [^] # Re:

                    Posté par  . Évalué à 1.

                    ATTENTION l'agent Smith arrive :D

                    faute d'inattention, mais c'est pas ça le probleme, j'ai beau essyé de trouvé l'anomalie (tiens c'est Neo) mais sans aucun resultat satisfaisant ; j'ai quand meme reussi à faire marcher le programme quelques instant avant le crash, alors je poste mon code source en attendant qu'une âme charitable (avec des yeux de faucon) y jette un coup d'oeil (ça risque d'etre long, mais je suis vraiment desesperé).
                    il s'agit d'un proxy qui compresse les images :
                    classe Server :

                    int server::start()
                    {
                    if((socket_server = socket(AF_INET, SOCK_STREAM, 0)) < 0){
                    std::cout<<"Socket creation error !\n"<<std::endl;
                    return EXIT_FAILURE;
                    }

                    if(bind(socket_server,
                    (struct sockaddr*)&sockaddr_server,
                    server_len
                    ) < 0){
                    std::cout<<"Socket bind error !\n"<<std::endl;
                    return EXIT_FAILURE;
                    }


                    if(listen(socket_server, 50) < 0){
                    std::cout<<"Socket listen error !\n"<<std::endl;
                    return EXIT_FAILURE;
                    }
                    std::string stri;

                    while (1){
                    PSOCKET_GROUP socketGroup;
                    struct sockaddr_in sockaddIn;
                    unsigned int sockaddrLen;
                    pthread_t threadSender, threadReceiver;
                    sigset_t sig_mask;

                    sockaddrLen = sizeof(sockaddIn);
                    socketGroup = (PSOCKET_GROUP) malloc ( sizeof(SOCKET_GROUP) );
                    socketGroup->socketToClient = accept(socket_server,
                    (struct sockaddr *)&sockaddIn,
                    &sockaddrLen
                    );

                    socketGroup->socketToServer=-1;
                    sigaddset(&sig_mask, SIGPIPE);
                    pthread_sigmask(SIG_BLOCK, &sig_mask, NULL);
                    pthread_create(&threadReceiver,
                    NULL,
                    proxyThread,
                    ( void* ) socketGroup
                    );
                    }
                    }

                    void* server::proxyThread( void* socketAdress )
                    {
                    BUFFER buff, buff2, tmp, allReceive;
                    int port, socketToHost, len;
                    long int receivedLen=0;
                    PSOCKET_GROUP sockG;

                    sockG = static_cast<PSOCKET_GROUP>(socketAdress);
                    buff = (BUFFER) malloc (100*MAX_RECEIVE*sizeof(char));
                    buff2 = (BUFFER) malloc (1000*MAX_RECEIVE*sizeof(char));
                    allReceive = (BUFFER) malloc (1000*MAX_RECEIVE*sizeof(char));
                    Connection* con = new Connection ();
                    len=con->receiveData( sockG->socketToClient, buff );
                    buff[len]=0;
                    shutdown(sockG->socketToClient,0);
                    if ((tmp=strstr(buff,"keep-alive\r\n"))) {
                    strncpy(tmp, "close\r\n", 7);
                    strcpy(tmp + 7, tmp + strlen("keep-alive\r\n"));
                    }
                    sockG->socketToServer =con->sendData( "",
                    3128,
                    buff,
                    len
                    );
                    free(buff);
                    while((
                    len=read(sockG->socketToServer, buff2, 100*MAX_RECEIVE*sizeof(char)))>0){
                    memcpy(allReceive+receivedLen, buff2, len);
                    receivedLen+=len;

                    }
                    free(buff2);
                    char *document=NULL, *header=NULL, *docType=NULL;
                    Text text;
                    long int docLength, i;

                    header = HTTPParser::getHeader(allReceive);
                    docLength = HTTPParser::getDocumentLength(header);
                    if (docLength>200){
                    docType = HTTPParser::getDocumentType(header);

                    if(strncmp(docType, "image/jpeg", strlen("image/jpeg"))==0||
                    strncmp(docType, "image/png", strlen("image/png"))==0||
                    strncmp(docType, "image/tiff", strlen("image/tiff"))==0
                    ){
                    Compression *comp = new Compression(1, sockG->threadContext);
                    document = HTTPParser::getDocument(allReceive);
                    int j = strlen(text.getStrInt(docLength));
                    Magick::Blob* blob = new Magick::Blob((const void *)document, docLength);
                    Magick::Blob retBlob = comp->getCompressedImage(blob);
                    i = text.getStrPos(header, "Content-Length: ", 0)+strlen("Content-Length: ");
                    char *newHeader = text.strReplace(header,
                    text.getStrInt(docLength),
                    i,
                    j
                    );
                    memset(allReceive, 0, 1000*MAX_RECEIVE*sizeof(char));
                    memcpy(allReceive,
                    newHeader,
                    strlen(header)
                    );
                    memcpy(allReceive + strlen(header), (char *)retBlob.data(), retBlob.length());
                    receivedLen = retBlob.length() + strlen(header);

                    delete comp;
                    free(newHeader);
                    free(header);
                    }
                    }

                    write(sockG->socketToClient, allReceive, receivedLen);
                    free(allReceive);
                    delete con;
                    shutdown(sockG->socketToClient, 2);
                    close(sockG->socketToClient);
                    shutdown(sockG->socketToServer, 2);
                    close(sockG->socketToServer);
                    pthread_exit(NULL);
                    }


                    classe HTTPParser

                    BUFFER HTTPParser::getDocument( BUFFER buff )
                    {
                    int taille;
                    char * ret;
                    taille = getDocumentLength( buff );
                    ret = (char *) malloc (taille*sizeof(char));
                    memcpy(ret, strstr(buff, "\r\n\r\n")+sizeof("\r\n\r\n")-1, taille);
                    return ret;
                    }

                    BUFFER HTTPParser::getHeader( BUFFER buff )
                    {
                    char * buffer;
                    int ind;

                    for (ind=0; buff[ind]!='\r'||buff[ind+1]!='\n'||buff[ind+2]!='\r'||buff[ind+3]!='\n'; ind+=1);
                    buffer = (char*) malloc ((ind+5)*sizeof(char));
                    strncpy(buffer, buff, (ind+4)*sizeof(char));
                    return buffer;
                    }

                    int HTTPParser::getDocumentLength(BUFFER header)
                    {
                    if (!strstr(header, "Content-Length: "))return -1;
                    return atoi(strstr(header, "Content-Length: ")+strlen("Content-Length: "));
                    }

                    BUFFER HTTPParser::getDocumentType( BUFFER header )
                    {
                    char *buff, *tmp;
                    int ind;
                    Text text;

                    tmp = strstr(header, "Content-Type: ")+strlen("Content-Type: ");
                    ind = text.getCharPos(tmp, '\r');
                    buff = (char*) malloc ((ind+1)*sizeof(char));
                    strncpy(buff, tmp, ind);
                    return buff;
                    }


                    classe Compression :

                    Magick::Blob Compression::getCompressedImage( Magick::Blob *blob )
                    {
                    Magick::Image* image = new Magick::Image(*blob);
                    Magick::Blob retBlob;


                    image->magick( "JPEG" );
                    image->quality(this->getQuality());
                    image->write(&retBlob);
                    delete image;
                    return retBlob;
                    }

                    classe Text :

                    int Text::getStrPos(char* str, char* c, int searchStart)
                    {
                    int i;

                    printf("getStrPos\n");
                    for ( i = searchStart; str[i]; i++)
                    if (strncmp( str+i, c, strlen(c) )==0)break;
                    if(!str[i]) return -1;
                    return i;
                    }

                    char* Text::getStrInt(int val)
                    {
                    char *retVal;

                    std::stringstream ss;
                    std::string str;
                    ss << val;
                    ss >> str;
                    retVal = (char *) calloc (str.size()+1, sizeof(char));
                    strcpy(retVal, str.c_str());
                    return retVal;


                    }

                    int Text::getCharPos(char* str, char c)
                    {
                    int i;

                    for (i=0; str[i]!=c; i++);
                    return i;
                    }

                    char* Text::strReplace(char* dest, char* replacement, int pos, int offset)
                    {
                    char* retStr;

                    retStr = (char*) calloc (strlen(dest), sizeof(char));
                    strncpy(retStr, dest, pos);
                    strncpy(retStr+pos, replacement, strlen(replacement));
                    strncpy(retStr+pos+strlen(replacement), dest+pos+offset, strlen(dest+pos+offset));
                    if (strstr(retStr, "\r\n\r\n"))
                    *(strstr(retStr, "\r\n\r\n")+strlen("\r\n\r\n"))=0;
                    return retStr;
                    }


                    voila le main contient juste un
                    Server serv=new Server(8080);
                    server->start();


                    avec ça si je configure firefox, qulques images s'affichent avant le BAM.

                    merci déja pour avoir lis le source et remerci si vous me donner une suggestion et enfin mille merci si vous me trouver l'anomalie.
                    • [^] # Re: Re:

                      Posté par  . Évalué à 1.

                      Ordoncque, après avoir lu le code , il semblerait qu'il y ait quelques fuites de mémoire qui traînent ...
                      blob, retblob, document et doctype se voient allouer de la mémoire qui n'est libérée nulle part à priori, ceci explique peut-être cela ?

                      Enfin une question qui n'a rien à voir avec le problème :
                      Pourquoi créer un blob avec le contenu de document juste pour le passer en paramètre à la fonction de compression ?
                      Pourquoi ne pas passer directement document à la fonction de compression et retourner un Magick::Blob ?
        • [^] # GDB, et donc DDD

          Posté par  (site web personnel) . Évalué à 1.

          watch

          pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

          • [^] # Re:

            Posté par  . Évalué à 1.

            merci vous deux, je vais tester dès que possible et je vous tiendrai au courant.

            a+
            • [^] # Re: Re:

              Posté par  . Évalué à 1.

              salut a nouveau,

              meme avec les free et delete j'obtient un segmentation fault.

              DDD me donne la ligne l'erreur et c'est :

              new Image(*blob);

              j'ai posté sur la liste d'imagemagick, quelqu'un m'a dit que c'etait peut etre l'image qui est foireuse, mais j'en doute bien, parceque je ne teste qu'un seule site et j'ai obtenue pratiquement toutes les images (chaque fois un peu avant le crash), donc ...

              si quelqu'un a une autre idée je prends.

              merci.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.