Précédent   Forum du club des développeurs et IT Pro > Autres langages > Autres langages > CORBA
CORBA Forum d'entraide et de discussion sur le développement distribué avec CORBA & les ORB
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 17/05/2011, 12h21   #1
L'elfe d'Azur
Futur Membre du Club
 
Inscription : octobre 2007
Messages : 56
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 56
Points : 17
Points : 17
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
L'elfe d'Azur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2011, 15h37   #2
CorbAddict
Membre éclairé
 
Homme Julien Enoch
Architecte technique
Inscription : septembre 2006
Messages : 219
Détails du profil
Informations personnelles :
Nom : Homme Julien Enoch
Âge : 37
Localisation : France

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

Informations forums :
Inscription : septembre 2006
Messages : 219
Points : 308
Points : 308
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);
}
CorbAddict est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/06/2011, 16h03   #3
L'elfe d'Azur
Futur Membre du Club
 
Inscription : octobre 2007
Messages : 56
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 56
Points : 17
Points : 17
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
L'elfe d'Azur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 13h11   #4
CorbAddict
Membre éclairé
 
Homme Julien Enoch
Architecte technique
Inscription : septembre 2006
Messages : 219
Détails du profil
Informations personnelles :
Nom : Homme Julien Enoch
Âge : 37
Localisation : France

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

Informations forums :
Inscription : septembre 2006
Messages : 219
Points : 308
Points : 308
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.
CorbAddict est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 03h12.


 
 
 
 
Partenaires

Hébergement Web