Discussion:
[omniORB] problem with server memory deallocation
risc risc
2010-04-12 14:32:09 UTC
Permalink
Hi All,

I have a problem with a server deallocation. I alloc a object in the server
routine and return the ogbect with obj._retn();

when the client destruct the orb, the object allocating in the server
routine is not be deallocated.

the idl is:

module test
{
interface p1
{
attribute string name;
};
interface p2
{
p1 function();
};
};

Server Routine relative P2 interface

test_p2_i::test_p2_i(){
// add extra constructor code here
cout<<"Constructor p2"<<endl;
}
test_p2_i::~test_p2_i(){
// add extra destructor code here
cout<<"destructor p2"<<endl;
}
// Methods corresponding to IDL attributes and operations
test::p1_ptr test_p2_i::function(){
// insert code here and remove the warning
test_p1_i * n=new test_p1_i;
------------------------------> HERE ALLOC THE OBJECT
n->name("ALEX");
test::p1_var ret=n->_this();
return ret._retn();
}


Server Routine relative P1 interface:

test_p1_i::test_p1_i(){
// add extra constructor code here
cout<<"constructor Call"<<endl;
}
test_p1_i::~test_p1_i(){
// add extra destructor code here
cout<<"Destructor Call"<<endl;
}
// Methods corresponding to IDL attributes and operations
void test_p1_i::nome(const char*){
// insert code here and remove the warning

}

char* test_p1_i::nome(){
// insert code here and remove the warning

}




CLIENT:

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]);



test::p2_var p2=test::p2::_narrow(obj);

if( CORBA::is_nil(p2) ) {
cerr << "Can't narrow reference to type Echo (or it was nil)." <<
endl;
return 1;
}



test::p1_ptr l=p2->function();
l->nome();
CORBA::release(l);

orb->destroy();



AFTER the client run the destruct of p1 object is it not be called why?
there is a bug or i make an error on implementing server/client?


Thanks
R!SC
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100412/8d60c505/attachment.htm
Luke Deller
2010-04-12 14:57:54 UTC
Permalink
Hi R!SC,
Post by risc risc
test::p1_var ret=n->_this();
return ret._retn();
Your servant object (whose class descends from PortableServer::ServantBase) is reference counted. When you call n->_this() there will be *two* outstanding references to the servant: one held by the POA (because the object has been automatically activated) and another whose ownership is returned to the caller. The first reference will be removed when the object is deactivated (which would happen when you shut down the ORB unless you explicitly deactivate it earlier), but you need to remove the second reference yourself or it will leak as you have observed.

The easiest thing to do here is to call n->_remove_ref() in between the two lines quoted above. This way the object will be deleted when the ORB shuts down.

Regards,
Luke.

**********************************************************************************************
Important Note
This email (including any attachments) contains information which is confidential and may be subject to legal privilege. If you are not the intended recipient you must not use, distribute or copy this email. If you have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this email are not necessarily the views of IRESS Market Technology Limited.

It is the duty of the recipient to virus scan and otherwise test the information provided before loading onto any computer system.
IRESS Market Technology Limited does not warrant that the information is free of a virus or any other defect or error.
**********************************************************************************************
Luke Deller
2010-04-12 15:22:50 UTC
Permalink
Hi R!SC,

Sorry my explanation was not entirely accurate (though the solution was correct). Here is an amended explanation.
Post by risc risc
test_p1_i * n=new test_p1_i;
TThe above line constructs your servant, whose class is descended from whose class descends from PortableServer::ServantBase which supports reference counting. At this point there is one outstanding reference to the servant.
Post by risc risc
test::p1_var ret=n->_this();
TThe above line will implicitly activate a CORBA object, so now there is a second reference to your servant owned by the POA.
When you shut down the ORB or explicitly deactivate the object, the POA will release its reference to your servant. However there is still the original reference outstanding, so the servant will leak as you have observed.

My suggestion is to call n->_remove_ref() immediately after activating the object so that it will be deleted upon deactivation.

Regards,
Luke.
**********************************************************************************************
Important Note
This email (including any attachments) contains information which is confidential and may be subject to legal privilege. If you are not the intended recipient you must not use, distribute or copy this email. If you have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this email are not necessarily the views of IRESS Market Technology Limited.

It is the duty of the recipient to virus scan and otherwise test the information provided before loading onto any computer system.
IRESS Market Technology Limited does not warrant that the information is free of a virus or any other defect or error.
**********************************************************************************************
risc risc
2010-04-12 16:04:17 UTC
Permalink
Hi Luke,

thanks for your reply and support. Yes i understand the concept thanks, but
i have tryed to add e remove reference after the object Activation POA
with

test_p1_i * n=new test_p1_i;
n->name("Alex");
test::p1_var ret=n->_this();
n->remove_ref();
return ret._retn();

in the client:

test::p1_var l=login->function();
l->nome();
orb->destroy();

also if i make :

test::p1_ptr l=login->function();
l->nome();
CORBA::release(l);
orb->destroy();

the object allocated from server is not be deallocated. however if in the
server add another one n->_remove_ref();
it be deallocated before return to client.
seem for the passing the object to client is added the reference another
one... :(

maybe i had mistake in client caller?

Thanks
Regard
R!SC
Post by Luke Deller
Hi R!SC,
Sorry my explanation was not entirely accurate (though the solution was
correct). Here is an amended explanation.
Post by risc risc
test_p1_i * n=new test_p1_i;
TThe above line constructs your servant, whose class is descended from
whose class descends from PortableServer::ServantBase which supports
reference counting. At this point there is one outstanding reference to the
servant.
Post by risc risc
test::p1_var ret=n->_this();
TThe above line will implicitly activate a CORBA object, so now there is a
second reference to your servant owned by the POA.
When you shut down the ORB or explicitly deactivate the object, the POA
will release its reference to your servant. However there is still the
original reference outstanding, so the servant will leak as you have
observed.
My suggestion is to call n->_remove_ref() immediately after activating the
object so that it will be deleted upon deactivation.
Regards,
Luke.
**********************************************************************************************
Important Note
This email (including any attachments) contains information which is
confidential and may be subject to legal privilege. If you are not the
intended recipient you must not use, distribute or copy this email. If you
have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this email
are not necessarily the views of IRESS Market Technology Limited.
It is the duty of the recipient to virus scan and otherwise test the
information provided before loading onto any computer system.
IRESS Market Technology Limited does not warrant that the information is
free of a virus or any other defect or error.
**********************************************************************************************
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100412/089099fb/attachment.htm
risc risc
2010-04-12 16:09:01 UTC
Permalink
Hi Luke,

thanks for your reply and support. Yes i understand the concept thanks, but
i have tryed to add e remove reference after the object Activation POA
with

test_p1_i * n=new test_p1_i;
n->name("Alex");

test::p1_var ret=n->_this();
n->remove_ref();
return ret._retn();

in the client:

test::p1_var l=login->function();
l->nome();
orb->destroy();

also if i make :

test::p1_ptr l=login->function();

l->nome();
CORBA::release(l);
orb->destroy();

the object allocated from server is not be deallocated. however if in the
server add another one n->_remove_ref();
it be deallocated before return to client.
seem for the passing the object to client is added the reference another
one... :(

maybe i had mistake in client caller?

Thanks
Regard
R!SC
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100412/ec8b5d40/attachment.htm
risc risc
2010-04-15 15:11:01 UTC
Permalink
Hi Luke,

I have read on omniOrb.pdf in omniOrb doc reference :

Once you have called CORBA::release() on an object reference, you must
no longer use that reference. This is because the associated resources may
have
been deallocated. Notice that we are referring to the resources associated
with
the object reference and not the servant object. Servant objects are not
affected
by the lifetimes of object references. In particular, servants are not
deleted when
all references to them have been released?CORBA does not perform distributed
garbage collection.


that is my case? so there isn't any mechanism to deallocated object created
into a servant routine?

thanks so Much
Best Regards
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100415/b3c57094/attachment.htm
Wernke Zur Borg (external)
2010-04-15 17:09:37 UTC
Permalink
Read again what Luke wrote and forget about CORBA::release() on
servants.

Your call to remove_ref() after creating and activating the servant is
correct but not enough. The memory will only be deallocated when you
deactivate the servant.

Regards, Wernke




________________________________

From: omniorb-list-***@omniorb-support.com
[mailto:omniorb-list-***@omniorb-support.com] On Behalf Of risc risc
Sent: 15 April 2010 11:10
To: omniorb-***@omniorb-support.com
Subject: Re: [omniORB] problem with server memory deallocation


Hi Luke,

I have read on omniOrb.pdf in omniOrb doc reference :

Once you have called CORBA::release() on an object
reference, you must
no longer use that reference. This is because the associated
resources may have
been deallocated. Notice that we are referring to the resources
associated with
the object reference and not the servant object. Servant objects
are not affected
by the lifetimes of object references. In particular, servants
are not deleted when
all references to them have been released-CORBA does not perform
distributed
garbage collection.


that is my case? so there isn't any mechanism to deallocated
object created into a servant routine?

thanks so Much
Best Regards




-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100415/b26a89a7/attachment.htm
risc risc
2010-04-15 18:55:47 UTC
Permalink
Hi Wernke,

thanks for your reply, i have inserted the _remove_ref() after the
activation with _this(); but the leak is the same observed after called
orb->destroy(); in the client also.

Is possible that there is a bug in the ORB?

thanks
Best Regards
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100415/b31f0f83/attachment.htm
Duncan Grisby
2010-04-18 03:29:25 UTC
Permalink
Post by risc risc
thanks for your reply, i have inserted the _remove_ref() after the
activation with _this(); but the leak is the same observed after
called orb->destroy(); in the client also.
Is possible that there is a bug in the ORB?
It is very unlikely that there is a bug in omniORB to do with reference
counting.

You should come up with a minimal example that shows the problem you are
seeing and post it. Without seeing your complete code, nobody can do
much to help.

How are you detecting the leak? Some memory leak detectors are not very
smart, and can report leaks where there are none.

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
risc risc
2010-04-18 15:32:33 UTC
Permalink
Hi Duncan,

thanks for your reply. I see the leak because i don't see the print of
object destructor when the object is cancelled. I try to post a minimal
example

IDL FILE:


module test
{
interface p1
{
attribute string name;
};
interface p2
{
p1 function();
};

};


CLIENT:



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]);



test::p2_var pd=test::p2::_narrow(obj);

if( CORBA::is_nil(pd) ) {

cerr << "Can't narrow reference to type Echo (or it was nil)." <<
endl;
return 1;
}


test::p1_var l=pd->function();

l->name();

orb->destroy();

}





SERVER:


class test_p1_i: public POA_test::p1 {
private:

public:
// standard constructor
test_p1_i();
virtual ~test_p1_i();

// methods corresponding to defined IDL attributes and operations
void name(const char*);
char* name();

};

//
// Example implementational code for IDL interface test::p1
//

test_p1_i::test_p1_i(){
// add extra constructor code here
cout<<"constructor Call"<<endl;
}
test_p1_i::~test_p1_i(){
// add extra destructor code here
cout<<"Destructor Call"<<endl;
}
// Methods corresponding to IDL attributes and operations
void test_p1_i::nome(const char*){
// insert code here and remove the warning

}

char* test_p1_i::name(){

// insert code here and remove the warning

}



class test_p2_i: public POA_test::p2 {
private:

public:
// standard constructor
test_p2_i();
virtual ~test_p2_i();

// methods corresponding to defined IDL attributes and operations
test::p1_ptr function();

};

//
// Example implementational code for IDL interface test::p2
//

test_p2_i::test_p2_i(){

cout<<"Constructor p2"<<endl;
}
test_p2_i::~test_p2_i(){

cout<<"destructor p2"<<endl;
}
// Methods corresponding to IDL attributes and operations

test::p1_ptr test_p2_i::function(){
// insert code here and remove the warning
test_p1_i * n=new test_p1_i;

n->name("Alfred");


test::p1_var ret=n->_this();

n->_remove_ref();

return ret._retn();
}



// End of example implementational code



int main(int argc, char** argv)
{
try {
// Initialise the ORB.

CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

// Obtain a reference to the root POA.
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
poa = PortableServer::POA::_narrow(obj);

// We allocate the objects on the heap. Since these are reference
// counted objects, they will be deleted by the POA when they are no
// longer needed.
test_p2_i* mytest_p2_i = new test_p2_i();


// Activate the objects. This tells the POA that the objects are
// ready to accept requests.
PortableServer::ObjectId_var mytest_p2_iid =
poa->activate_object(mytest_p2_i);


// Obtain a reference to each object and output the stringified
// IOR to stdout
{
// IDL interface: test::p2
CORBA::Object_var ref = mytest_p2_i->_this();
CORBA::String_var sior(orb->object_to_string(ref));
std::cout << "IDL object test::p2 IOR = '" << (char*)sior << "'" <<
std::endl;
}



// Obtain a POAManager, and tell the POA to start accepting
// requests on its objects.
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();

orb->run();
orb->destroy();
}
....


I See after the client make orb->destroy() the cout in the P1 destroctor is
not be called.

Thanks
Best Regards
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100418/610e46fe/attachment.htm
risc risc
2010-04-18 15:47:38 UTC
Permalink
Hi Duncan,

thanks for your reply. I see the leak because i don't see the print of
object destructor when the object is cancelled. I try to post a minimal
example

IDL FILE:


module test
{
interface p1
{
attribute string name;
};
interface p2
{
p1 function();
};

};


CLIENT:



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]);



test::p2_var pd=test::p2::_narrow(obj);

if( CORBA::is_nil(pd) ) {

cerr << "Can't narrow reference to type Echo (or it was nil)." <<
endl;
return 1;
}


test::p1_var l=pd->function();

l->name();

orb->destroy();

}





SERVER:


class test_p1_i: public POA_test::p1 {
private:

public:
// standard constructor
test_p1_i();
virtual ~test_p1_i();

// methods corresponding to defined IDL attributes and operations
void name(const char*);
char* name();

};

//
// Example implementational code for IDL interface test::p1
//

test_p1_i::test_p1_i(){
// add extra constructor code here
cout<<"constructor Call"<<endl;
}
test_p1_i::~test_p1_i(){
// add extra destructor code here
cout<<"Destructor Call"<<endl;
}
// Methods corresponding to IDL attributes and operations
void test_p1_i::nome(const char*){
// insert code here and remove the warning

}

char* test_p1_i::name(){

// insert code here and remove the warning

}



class test_p2_i: public POA_test::p2 {
private:

public:
// standard constructor
test_p2_i();
virtual ~test_p2_i();

// methods corresponding to defined IDL attributes and operations
test::p1_ptr function();

};

//
// Example implementational code for IDL interface test::p2
//

test_p2_i::test_p2_i(){

cout<<"Constructor p2"<<endl;
}
test_p2_i::~test_p2_i(){

cout<<"destructor p2"<<endl;
}
// Methods corresponding to IDL attributes and operations

test::p1_ptr test_p2_i::function(){
// insert code here and remove the warning
test_p1_i * n=new test_p1_i;

n->name("Alfred");


test::p1_var ret=n->_this();

n->_remove_ref();

return ret._retn();
}



// End of example implementational code



int main(int argc, char** argv)
{
try {
// Initialise the ORB.

CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

// Obtain a reference to the root POA.
CORBA::Object_var obj = orb->resolve_initial_
references("RootPOA");
poa = PortableServer::POA::_narrow(obj);

// We allocate the objects on the heap. Since these are reference
// counted objects, they will be deleted by the POA when they are no
// longer needed.
test_p2_i* mytest_p2_i = new test_p2_i();


// Activate the objects. This tells the POA that the objects are
// ready to accept requests.
PortableServer::ObjectId_var mytest_p2_iid =
poa->activate_object(mytest_p2_i);


// Obtain a reference to each object and output the stringified
// IOR to stdout
{
// IDL interface: test::p2
CORBA::Object_var ref = mytest_p2_i->_this();
CORBA::String_var sior(orb->object_to_string(ref));
std::cout << "IDL object test::p2 IOR = '" << (char*)sior << "'" <<
std::endl;
}



// Obtain a POAManager, and tell the POA to start accepting
// requests on its objects.
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();

orb->run();
orb->destroy();
}
....


I See after the client make orb->destroy() the cout in the P1 destroctor is
not be called.

Thanks
Best Regards
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100418/a32279ed/attachment.htm
Wernke Zur Borg (external)
2010-04-20 12:19:36 UTC
Permalink
The call to _this() implicitly activates the object and increments the
reference count. As I already posted, you have to deactivate the object
in order to get it destructed properly.

Wernke



________________________________

From: omniorb-list-***@omniorb-support.com
[mailto:omniorb-list-***@omniorb-support.com] On Behalf Of risc risc
Sent: 18 April 2010 11:47
To: omniorb-***@omniorb-support.com
Subject: Re: [omniORB] problem with server memory deallocation


Hi Duncan,

thanks for your reply. I see the leak because i don't see the
print of object destructor when the object is cancelled. I try to post a
minimal example

IDL FILE:


module test
{
interface p1
{
attribute string name;
};
interface p2
{
p1 function();
};

};



CLIENT:



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]);




test::p2_var pd=test::p2::_narrow(obj);

if( CORBA::is_nil(pd) ) {

cerr << "Can't narrow reference to type Echo (or it was
nil)." << endl;
return 1;
}



test::p1_var l=pd->function();

l->name();

orb->destroy();

}





SERVER:


class test_p1_i: public POA_test::p1 {
private:

public:
// standard constructor
test_p1_i();
virtual ~test_p1_i();

// methods corresponding to defined IDL attributes and
operations
void name(const char*);
char* name();

};

//
// Example implementational code for IDL interface test::p1
//

test_p1_i::test_p1_i(){
// add extra constructor code here
cout<<"constructor Call"<<endl;
}
test_p1_i::~test_p1_i(){
// add extra destructor code here
cout<<"Destructor Call"<<endl;
}
// Methods corresponding to IDL attributes and operations
void test_p1_i::nome(const char*){
// insert code here and remove the warning

}


char* test_p1_i::name(){

// insert code here and remove the warning

}




class test_p2_i: public POA_test::p2 {
private:

public:
// standard constructor
test_p2_i();
virtual ~test_p2_i();

// methods corresponding to defined IDL attributes and
operations
test::p1_ptr function();

};

//
// Example implementational code for IDL interface test::p2
//

test_p2_i::test_p2_i(){


cout<<"Constructor p2"<<endl;
}
test_p2_i::~test_p2_i(){


cout<<"destructor p2"<<endl;
}
// Methods corresponding to IDL attributes and operations

test::p1_ptr test_p2_i::function(){
// insert code here and remove the warning

test_p1_i * n=new test_p1_i;


n->name("Alfred");


test::p1_var ret=n->_this();


n->_remove_ref();

return ret._retn();
}




// End of example implementational code



int main(int argc, char** argv)
{
try {
// Initialise the ORB.

CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);


// Obtain a reference to the root POA.
CORBA::Object_var obj = orb->resolve_initial_
references("RootPOA");
poa = PortableServer::POA::_narrow(obj);

// We allocate the objects on the heap. Since these are
reference
// counted objects, they will be deleted by the POA when
they are no
// longer needed.
test_p2_i* mytest_p2_i = new test_p2_i();


// Activate the objects. This tells the POA that the
objects are
// ready to accept requests.
PortableServer::ObjectId_var mytest_p2_iid =
poa->activate_object(mytest_p2_i);


// Obtain a reference to each object and output the
stringified
// IOR to stdout
{
// IDL interface: test::p2
CORBA::Object_var ref = mytest_p2_i->_this();
CORBA::String_var sior(orb->object_to_string(ref));
std::cout << "IDL object test::p2 IOR = '" << (char*)sior
<< "'" << std::endl;
}



// Obtain a POAManager, and tell the POA to start accepting
// requests on its objects.
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();

orb->run();
orb->destroy();
}
....


I See after the client make orb->destroy() the cout in the P1
destroctor is not be called.

Thanks
Best Regards



-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100420/b3194527/attachment.htm
risc risc
2010-04-20 15:12:07 UTC
Permalink
Excuse me for my bit experience with omniOrb, how i deactivate the object?
from client or server side?

thanks
Best Regards
Post by Wernke Zur Borg (external)
The call to _this() implicitly activates the object and increments the
reference count. As I already posted, you have to deactivate the object in
order to get it destructed properly.
Wernke
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20100420/333dcf31/attachment.htm
Duncan Grisby
2010-04-20 22:14:54 UTC
Permalink
On Sun, 2010-04-18 at 11:47 +0200, risc risc wrote:

[...]
Post by risc risc
I See after the client make orb->destroy() the cout in the P1
destroctor is not be called.
I think this last comment reveals the issue. You are saying that you are
calling orb->destroy() on the client, and you expect to see the
destructor on the server called automatically. That is not the way that
CORBA works. You have to explicitly deactivate the object in the server
if you want your servant to be deleted.

I strongly recommend that you get a good book on CORBA and read all
about object lifetimes.

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Loading...