Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 4 sur 4
  1. #1
    Membre à l'essai
    Inscrit en
    octobre 2007
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : octobre 2007
    Messages : 62
    Points : 20
    Points
    20

    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 :
    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 :
    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 :
    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 éclairé
    Homme Profil pro Julien Enoch
    Architecte technique
    Inscrit en
    septembre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Nom : Homme Julien Enoch
    Âge : 38
    Localisation : France

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

    Informations forums :
    Inscription : septembre 2006
    Messages : 219
    Points : 301
    Points
    301

    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 :
    1
    2
    3
    4
    SeqCoef* Echo_i::coef(){
      return new SeqCoef(liste);
    }

  3. #3
    Membre à l'essai
    Inscrit en
    octobre 2007
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : octobre 2007
    Messages : 62
    Points : 20
    Points
    20

    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 :
    1
    2
    3
    4
    5
    ...
    SeqCoef *test= e->coef();
    ...
    delete test;
    Merci de ton aide

  4. #4
    Membre éclairé
    Homme Profil pro Julien Enoch
    Architecte technique
    Inscrit en
    septembre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Nom : Homme Julien Enoch
    Âge : 38
    Localisation : France

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

    Informations forums :
    Inscription : septembre 2006
    Messages : 219
    Points : 301
    Points
    301

    Par défaut

    Bonjour,

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

    Code :
    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.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •