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

CORBA Discussion :

CORBA - C++ - Probleme avec les sequences


Sujet :

CORBA

  1. #1
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 66
    Points : 50
    Points
    50
    Par défaut CORBA - C++ - Probleme avec les sequences
    Bonjour,

    j'ai besoin dans le cadre de mon projet d'inserer a mon interface une sequence<double> (pour avoir une liste de coefficients dynamique)

    J'ai repris l'exemple de base et comme je veux eviter au maximum les new (qui entraine souvent des fuites memoires), j'ai essaye d'utiliser des references sauf qu'au 2nd appel de ma sequence, j'ai droit a Caught a CORBA::COMM_FAILURE chez le client et pour le serveur un erreur de plusieurs pages commencant par :

    Upcall Hello!
    2
    *** glibc detected *** ./Server: double free or corruption (fasttop): 0x0000000001e022d0 ***
    ======= Backtrace: =========


    Voici mon code :
    Tout d'abord Echo.idl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef sequence<double> SeqCoef;
    
    interface Echo{
      string echoString(in string mesg);
    
      attribute SeqCoef coef;
    };
    Ensuite le serveur
    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
    #include "Echo.hh"
    #include <stdlib.h>
    
    #ifdef HAVE_STD
    # include <iostream>
    using namespace std;
    #else
    # include <iostream.h>
    #endif
    class Echo_i : public POA_Echo
    {
    public:
      inline Echo_i() {liste.length(0);}
      virtual ~Echo_i() {}
      virtual char* echoString(const char* mesg);
      virtual SeqCoef* coef();
      virtual void coef(const SeqCoef&);
    
      SeqCoef liste;
    };
    char* Echo_i::echoString(const char* mesg)
    {
      cout << "Upcall " << mesg << endl;
      cout << liste.length()<<endl;
      string tmp = std::string(mesg)+ "toto";
      return CORBA::string_dup(tmp.c_str());
    }
    
    SeqCoef* Echo_i::coef(){
      return &liste;
    }
    void Echo_i::coef(const SeqCoef& val){
      /*liste->length(val.length());
      for(int i=0 ; i<val.length();i++){
        (*liste)[i]=val[i];
        }*/
      liste = val;
    }
    //////////////////////////////////////////////////////////////////////
    int main(int argc, char** argv)
    {
      try {
        CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
        CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
        PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
        Echo_i* myecho = new Echo_i();
    
        SeqCoef test;
        test.length(2);
        test[0]=108;
        test[1]=64;
        myecho->coef(test);
        PortableServer::ObjectId_var myechoid = poa->activate_object(myecho);
        // Obtain a reference to the object, and print it out as a
        // stringified IOR.
        obj = myecho->_this();
        CORBA::String_var sior(orb->object_to_string(obj));
        cout << (char*)sior << endl;
        myecho->_remove_ref();
        PortableServer::POAManager_var pman = poa->the_POAManager();
        pman->activate();
        orb->run();
      }
      catch(CORBA::SystemException& ex) {
        cerr << "Caught CORBA::" << ex._name() << endl;
      }
      catch(CORBA::Exception& ex) {
        cerr << "Caught CORBA::Exception: " << ex._name() << endl;
      }
      catch(omniORB::fatalException& fe) {
        cerr << "Caught omniORB::fatalException:" << endl;
        cerr << " file: " << fe.file() << endl;
        cerr << " line: " << fe.line() << endl;
        cerr << " mesg: " << fe.errmsg() << endl;
      }
      return 0;
    }
    Enfin le client
    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
    #include "Echo.hh"
    #ifdef HAVE_STD
    # include <iostream>
    # include <fstream>
    using namespace std;
    #else
    # include <iostream.h>
    #endif
    static void hello(Echo_ptr e)
    {
      CORBA::String_var src = (const char*) "Hello! ";
      CORBA::String_var dest = e->echoString(src);
      cout << "I said, \"" << (char*)src << "\"." << endl
           << "The Echo object replied, \"" << (char*)dest <<"\"." << endl;
      SeqCoef *test= e->coef();
      cout <<"test ="<<test->length()<<endl;
    
      SeqCoef *test2= e->coef();
      cout <<"test2 ="<<test2->length()<<endl;
    }
    //////////////////////////////////////////////////////////////////////
    int main(int argc, char** argv)
    {
      try {
        CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
        if( argc != 2 ) {
          cerr << "usage: eg2_clt <object reference>" << endl;
          return 1;
        }
        CORBA::Object_var obj = orb->string_to_object(argv[1]);
        Echo_var echoref = Echo::_narrow(obj);
        if( CORBA::is_nil(echoref) ) {
    
          cerr << "Can’t narrow reference to type Echo (or it was nil)." << endl;
          return 1;
        }
        for (CORBA::ULong count=0; count<10; count++)
          hello(echoref);
        orb->destroy();
      }
      catch(CORBA::TRANSIENT&) {
        cerr << "Caught system exception TRANSIENT -- unable to contact the "
    	 << "server." << endl;
      }
      catch(CORBA::SystemException& ex) {
        cerr << "Caught a CORBA::" << ex._name() << endl;
      }
      catch(CORBA::Exception& ex) {
        cerr << "Caught CORBA::Exception: " << ex._name() << endl;
      }
      catch(omniORB::fatalException& fe) {
        cerr << "Caught omniORB::fatalException:" << endl;
        cerr << " file: " << fe.file() << endl;
        cerr << " line: " << fe.line() << endl;
        cerr << " mesg: " << fe.errmsg() << endl;
      }
      return 0;
    }
    Est-ce que le probleme ne viendrait pas des "deep copy"?

    Merci de votre aide

  2. #2
    Membre averti
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 219
    Points : 302
    Points
    302
    Par défaut
    Bonjour,

    Le problème vient de l'implémentation de l'opération coef() côté serveur.
    Par convention CORBA laisse à l'appelant (le client) la responsabilité la gestion mémoire de l'objet retourné par l'opération du serveur. Il faut donc lui renvoyer une copie de la liste.
    L'ORB du serveur va ensuite détruire l'objet retourné par l'opération coef() juste après envoi de la requête retour au client. Donc ton cas liste est détruit au 1er appel. Au 2e appel, il est par chance encore accessible en mémoire, mais en fin de requête un 2e delete est fait (d'où le "double free").

    Une implémentation correcte serait celle-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SeqCoef* Echo_i::coef(){
      return new SeqCoef(liste);
    }

  3. #3
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 66
    Points : 50
    Points
    50
    Par défaut
    Donc je suis oblige de faire appel a new.

    Je dois donc ensuite faire dans mon client pour liberer ma memoire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    SeqCoef *test= e->coef();
    ...
    delete test;
    Merci de ton aide

  4. #4
    Membre averti
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 219
    Points : 302
    Points
    302
    Par défaut
    Bonjour,

    Le mieux c'est d'utiliser un type _var côté client.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ...
    {
        SeqCoef_var test= e->coef();
        ...
    }
    // en fin de scope l'objet SeqCoef_var est détruit 
    // et le pointeur qu'il encapsule aussi.

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

Discussions similaires

  1. Help!! Probleme avec les dates sur SQL SERVER
    Par Nadaa dans le forum MS SQL Server
    Réponses: 16
    Dernier message: 03/08/2006, 16h55
  2. PROBLEME AVEC LES REQUETES IS NULL / NOT EXISTS
    Par sylvaine dans le forum Langage SQL
    Réponses: 5
    Dernier message: 04/06/2004, 13h26
  3. [langage] probleme avec les listes dans des listes
    Par pqmoltonel dans le forum Langage
    Réponses: 7
    Dernier message: 27/04/2004, 12h32
  4. Problem avec les *.AVI sur les panels
    Par NaDiA_SoFt dans le forum C++Builder
    Réponses: 3
    Dernier message: 31/08/2003, 22h50
  5. probleme avec les processus
    Par saidi dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 05/02/2003, 00h18

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