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 :

Problème librairie statique


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Points : 124
    Points
    124
    Par défaut Problème librairie statique
    Bonjour à tous,

    Je peux compiler mon programme avec la commande suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g++ -DSERVEUR -o pcserv $(shell find ../Outils -name "*.cpp") PcServeur.cpp -lpthread -ljpeg -lX11
    L'exécutable compile, link et marche sans problèmes.
    Mais le répertoire Outils ayant pas mal de fichiers sources, j'ai voulu en faire une librairie statique pour accélérer la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SRC_OUTILS=$(shell find ../Outils -name "*.cpp")
    #la listes des .o sans les chemins (uniquement les noms)
    OBJ_OUTILS=$(notdir $(subst .cpp,.o,$(SRC_OUTILS)))
    liboutils:
    	g++ -DSERVEUR -Wall -O0 -ggdb -c $(SRC_OUTILS)
    	ar -q liboutils.a $(OBJ_OUTILS)

    et je compile maintenant avec la commande suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g++ -Wall -O0 -ggdb -o pcserv PcServeur.cpp -L../Outils -loutils -lX11 -lpthread -ljpeg
    Mon exécutable compile et link sans problème mais ne marche plus :
    j'ai l'erreur suivante à l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    *** glibc detected *** ./pcserv: munmap_chunk(): invalid pointer: 0x09404038 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7bd0454]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7dad0b1]
    /usr/lib/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1d)[0xb7d898bd]
    /usr/lib/libstdc++.so.6(_ZNSsD1Ev+0x51)[0xb7d8b271]
    ./pcserv[0x804b711]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7b77685]
    ./pcserv[0x804aad1]
    ....
    ...
    D'où cela peut-il venir ???

  2. #2
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    À vue de nez, je verrais que tu alloues une variable dans la lib compilée en release, et que tu la libères dans ton programme compilé en debug (ou l'inverse).

    Ce qui serait très mal, d'ailleurs, il faut toujours libérer la mémoire dans le composant qui l'a allouée (pour éviter ce genre de problèmes, justement !).

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Points : 124
    Points
    124
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    À vue de nez, je verrais que tu alloues une variable dans la lib compilée en release, et que tu la libères dans ton programme compilé en debug (ou l'inverse).

    Ce qui serait très mal, d'ailleurs, il faut toujours libérer la mémoire dans le composant qui l'a allouée (pour éviter ce genre de problèmes, justement !).
    Heu non, je ne pense pas avoir ce genre de problème. Mes objets ont leur constructeur et destructeur.
    En plus pour le moment la lib et le programme sont compilés tout les deux en débug : -Wall -O0 -ggdb

    Voici le fichier PcServeur.cpp, il n'est pas très long :
    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
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
     
    #include "PcServeur.h"
     
    using namespace std;
    using namespace Outils;
    using namespace cimg_library;
     
     
    ReceiveImages::ReceiveImages(std::string p_nom, IProtocole *p_p,
            unsigned long intsize, unsigned int p_width, unsigned int p_height, 
            ITache *p_tacheSendMessages){
        nom=p_nom;
        assert(p_p!= NULL && p_tacheSendMessages!= NULL);
        p=p_p;
        width=p_width;
        height=p_height;
        tacheSendMessages=p_tacheSendMessages;
        this->intsize=intsize;
        reception = new JOCTET[CENT_KILO];
        if (reception == NULL) 
            throw COutOfMemory("L'allocation du buffer de reception des images a échouée.");
    }
     
     
    ReceiveImages::~ReceiveImages(){
        delete[] reception;
    }
     
     
    void ReceiveImages::toDo(){ 
        const unsigned char red[] = { 255,0,0 };
        const unsigned char blue[] = { 0,155,255 };
        int i=0;
        size_t sz=0;
        int jpegfilesize=0, datesize=0;
        char date[50];
        unsigned int dimX = width, dimY = height;
        CImg<unsigned char> imageCourante, affichage(dimX, dimY, 1, 3, 255);
        CImgDisplay disp(affichage,"Live view : ");
        disp.close();
        while(1){
            //On attend des données pendant une 300 milliseconde. Si on a pas de 
            //données, on ferme la fenêtre d'affichage
            if ( ! p->waitData(0,300) ) disp.close();
            //et on attend infiniment des données :
            if (p->waitData(-1) ){
                disp.show();
                //reception de la taille du fichier jpeg :
                jpegfilesize=0;
                p->receiveInteger( intsize, &jpegfilesize, &sz);
            }
            //reception du fichier :
            if ( p->waitData(1) ){
                p->receive(jpegfilesize, reception , &sz);
                cout << "Image n°"<< i++ <<"  Taille reçue : "<< sz <<
                    "     Taille attendue : "<<  jpegfilesize << endl;
                //chargement de l'image jpeg recu, grace au plugin jpeg_buffer :
                imageCourante.load_jpeg_buffer( reception, jpegfilesize);
            }
     
            //on passe l'image en 3 channels (RGB) pour avoir les couleurs..... :
            affichage = imageCourante;
            affichage.resize(dimX,dimY,1,3);
     
            //affichage du nb de frames par secondes :
            affichage.draw_text(5,5,"%u frames/s",red,0,1,18,
                            (unsigned int)disp.frames_per_second());
     
            disp << affichage;
     
        }  
    }
     
     
    SendMessages::SendMessages(std::string p_nom, IProtocole *p_p, unsigned long intsize){
        nom=p_nom;
        assert(p_p != NULL );
        p=p_p;
        this->intsize=intsize;
    }
     
     
    void SendMessages::toDo(){
        string mess;
        do{
            //tache d'envois des messages au client
            cin >> mess;
            p->sendInteger( mess.size(), intsize);
            p->send( (const char *) mess.c_str(), mess.size() );
        }
        while(mess != "exit");
    }
     
     
     
    int main(int argc, char* argv[]) {
     
        if (argc!=2) {
            printf("Usage : %s <port>",argv[0]);
            exit(EXIT_FAILURE);
        }
     
        ILogger *logger = new CLoggerConsole();
        ILogger::SetLogger(logger);
     
        //Etablissement du serveur
        IProtocole *p = new ProtocoleTCP();
        p->connect(std::string("tagada"), atoi(argv[1]) ,false);
        p->printInfo();
     
     
        //Attente de données pendant 30 secondes
        p->waitData(30);
        int  width=0, height=0;
        unsigned long intsize=0;
        size_t recu=0;
     
        //Reception de la taille d'un int, en octet
        p->receive( sizeof(char), (unsigned char*) &intsize, &recu);
        std::cout	<< "Taille d'un int en octets : " << intsize << std::endl;
        recu=0;
     
        //Reception de largeur des images:
        p->waitData(1);
        p->receiveInteger( intsize, &width, &recu);
        std::cout	<< "Largeur des images à recevoir : " << width<< std::endl;
        recu=0;
     
        //Reception de hauteur des images :
        p->waitData(1) ;
        p->receiveInteger( intsize, &height, &recu);
        std::cout	<< "Hauteur des images à recevoir : " << height<< std::endl;
        recu=0;
     
        /*-------------------------------------------------------------------------
         *  Création et lancement des deux taches :
         *-------------------------------------------------------------------------*/
        ITache *tacheStdin = new SendMessages("Tâche d'envois des messages", 
                p, intsize);
        ITache *tacheReception = new ReceiveImages("Tâche de réception des images.", 
                p, intsize, width, height, tacheStdin);
     
        tacheStdin->start();
        tacheReception->start();
     
        do {
            MSLEEP(300);
        }
        while( tacheStdin->isRunning() );
     
        tacheReception->stop();
     
        delete tacheReception;
        delete tacheStdin;
     
        //laisse le tps au client de se déconnecter
        sleep(2);
        //fermer le serveur
        p->disconnect();
        delete p;
        delete logger;
     
        return EXIT_SUCCESS;
    }
    Enfin un autre programme (le client) utilise la même librairie (enfin, cross-compilée) sans aucun problèmes....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    libcrossoutils:
    	mips-linux-gnu-g++ -DCLIENT -Wall -O0 -ggdb -c $(SRC_OUTILS)
    	mips-linux-gnu-ar -q libcrossoutils.a $(OBJ_OUTILS)
    puis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mips-linux-gnu-g++ -Wall -O0 -ggdb -o camclient JPEGImage.cpp PGMImage.cpp CameraCliente.cpp -I/opt/excite-tools/mips-linux-gnu/sys-root/opt/excite/include -L/opt/excite-tools/mips-linux-gnu/sys-root/opt/excite/lib -L../Outils -L../Outils/Video -lxcam -ljpeg -lcrossavi -lcrossoutils

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    A partir du moment où tu as un message commençant par
    *** glibc detected *** ./pcserv: munmap_chunk(): invalid pointer: 0x09404038 ***
    (C'est comme le marcassou, c'est marqué dessus )

    Il n'y a rien à faire, tu as fait des spagettis avec tes pointeurs
    • Soit tu travaille avec un pointeur mal initialisé
    • Soit tu travailles avec un pointeur qui a été invalidé (dont la mémoire pointée aurait déjà été libérée par exemple)
    • Soit tu essaye de libérer deux fois de la mémoire allouée dynamiquement

    La grosse difficulté, c'est qu'il est particulièrement difficile de déterminer le point de code qui pose problème, car il peut se passer très longtemps entre le moment où un pointeur est devenu invalide et le moment où tu essaye à nouveau d'y accéder

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Points : 124
    Points
    124
    Par défaut
    C'est bon, j'ai trouvé aujourd'hui...

    Je compilais la librairie statique en mode serveur comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    g++ -DSERVEUR -Wall -O0 -ggdb -c $(SRC_OUTILS)
    	ar -q liboutils.a $(OBJ_OUTILS)
    et j'ai oublié de remettre le define au moment de l'edition des liens, ce qui faisait que certains .h, à cause des directives pré-processeurs ne correspondaient pas à la librairie compilée.....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g++ -Wall -O0 -ggdb -DSERVEUR -o pcserv PcServeur.cpp -L../Outils -loutils -lX11 -lpthread -ljpeg
    D'où l'erreur de pointeur...

    C'est c**, hein ?
    Merci quand même pour votre aide !

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

Discussions similaires

  1. librairie statique et problème d'initialisation
    Par vingt sens dans le forum Bibliothèques
    Réponses: 7
    Dernier message: 06/06/2010, 16h25
  2. Réponses: 2
    Dernier message: 09/12/2009, 18h54
  3. Problème avec une librairie statique
    Par flo_k dans le forum C
    Réponses: 2
    Dernier message: 21/09/2009, 21h50
  4. Problème de Librairie statique
    Par TNT89 dans le forum C++
    Réponses: 8
    Dernier message: 24/12/2007, 18h18
  5. Réponses: 5
    Dernier message: 08/03/2006, 22h37

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