Discussion:
[omniORB] Memory leak
Tatiana Lazareva
2012-01-17 16:17:19 UTC
Permalink
Hi all,
It seems that I find some memory leak bugs in omni4.1.6 code. These memory
leak bugs were detected using the purify tool on the Solaris10 OS.
*1) /omniORB-4.1.6/src/lib/omniORB/orbcore/tcp/tcpTransportImpl.cc: line
426:*
while ( 1 ) {
// There is no way to know for sure the buffer is big enough to get
// the info for all the interfaces. We work around this by calling
// the ioctl 2 times and increases the buffer size in the 2nd call.
// If both calls return the info with the same size, we know we have
// got all the interfaces.
char* buf = (char*) malloc(len); [*TLazareva]: this is 426 line.*
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if ( ioctl(sock, OMNI_SIOCGIFCONF, &ifc) < 0 ) {
if ( errno != EINVAL || lastlen != 0 ) {
if ( omniORB::trace(1) ) {
omniORB::logger log;
log << "Warning: ioctl SIOCGICONF failed.\n"
<< "Unable to obtain the list of all interface addresses.\n";
} *[TLazareva]: I think that "buf" variable should be cleaned before
"return": "free buf;" *
return;
}
}
else {
if ( ifc.ifc_len == lastlen )
break; // Success, len has not changed.
lastlen = ifc.ifc_len;
}
len += 10 * sizeof(struct ifreq);
free(buf);
}
*2) /omniORB-4.1.6/src/lib/omnithread/posix.cc: line 376*
omni_thread* t = new omni_thread; *[TLazareva]: This is 376 line. "t"
object was not deleted at the end of function. Is it correct? Purify detect
the memory leak for this object.*

t->_state = STATE_RUNNING;

t->posix_thread = pthread_self ();

DB(cerr << "initial thread " << t->id() << endl);

THROW_ERRORS(pthread_setspecific(self_key, (void*)t));

#ifdef PthreadSupportThreadPriority

#if (PthreadDraftVersion == 4)

THROW_ERRORS(pthread_setprio(t->posix_thread,
posix_priority(PRIORITY_NORMAL)));

#elif (PthreadDraftVersion == 6)

pthread_attr_t attr;
pthread_attr_init(&attr);

THROW_ERRORS(pthread_attr_setprio(&attr,
posix_priority(PRIORITY_NORMAL)));

THROW_ERRORS(pthread_setschedattr(t->posix_thread, attr));

#else

struct sched_param sparam;

sparam.sched_priority = posix_priority(PRIORITY_NORMAL);

THROW_ERRORS(pthread_setschedparam(t->posix_thread, SCHED_OTHER,
&sparam));
*[TLazareva]: I think that "t" object should be cleaned before the end of
function: "delete t;"*
#endif /* PthreadDraftVersion */

#endif /* PthreadSupportThreadPriority */
}

*3) /omniORB-4.1.6/src/lib/omniORB/orbcore/portableserver.cc: line 320*
void*
PortableServer::ServantBase::_do_this(const char* repoId)
{
OMNIORB_ASSERT(repoId);

if (!omni::internalLock) {
// Not initalised yet
OMNIORB_THROW(OBJ_ADAPTER,OBJ_ADAPTER_POANotInitialised,
CORBA::COMPLETED_NO);
}

omniCurrent* current = omniCurrent::get(); *[TLazareva]: This is 320
line. This object is created in
/omniORB-4.1.6/include/omniORB4/internal/omniCurrent.h file at the 92 line
using "new" operator and this object is not cleaned in the code.*
if (current) {
omniCallDescriptor* call_desc = current->callDescriptor();
if (call_desc &&
call_desc->localId()->servant() == (omniServant*)this) {

// In context of an invocation on this servant
omniObjRef* ref = omniOrbPOACurrent::real_get_reference(call_desc);
OMNIORB_ASSERT(ref);*[TLazareva]: I think that "current" object
should be cleaned before the "return": "delete current;"*
return ref->_ptrToObjRef(repoId);
}
}

{
omni_tracedmutex_lock sync(*omni::internalLock);

if (_activations().size() == 1) {
// We only have a single activation -- return a reference to it.
omniObjTableEntry* entry = _activations()[0];
omniOrbPOA* poa = omniOrbPOA::_downcast(entry->adapter());
omniIORHints hints(poa ? poa->policy_list() : 0);
omniObjRef* ref = omni::createLocalObjRef(_mostDerivedRepoId(),
repoId,
entry, hints);
OMNIORB_ASSERT(ref);
return ref->_ptrToObjRef(repoId);
}
}
*
*
PortableServer::POA_var poa = this->_default_POA();

if( CORBA::is_nil(poa) )
OMNIORB_THROW(OBJ_ADAPTER,OBJ_ADAPTER_POANotInitialised,
CORBA::COMPLETED_NO);

return ((omniOrbPOA*)(PortableServer::POA_ptr) poa)->
servant__this(this, repoId);
}

*4) /omniORB-4.1.6/src/lib/omnithread/threaddata.cc: line 51*
omni_thread::value_t*
omni_thread::set_value(key_t k, value_t* v)
{
if (k == 0) return 0;
if (k > _value_alloc) {
next_id_mutex->lock();
key_t alloc = allocated_keys;
next_id_mutex->unlock();

if (k > alloc) return 0;

value_t** nv = new value_t*[alloc]; *[TLazareva]: This is 51 line. "nv"
object is not cleaned in the code.*
key_t i = 0;
if (_values) {
for (; i < _value_alloc; i++)
nv[i] = _values[i];
delete [] _values;
}
for (; i < alloc; i++)
nv[i] = 0;

_values = nv;*[TLazareva]: As I understand "nv" object is not needed
after this line, so it should be deleted: "delete [] nv;"*
_value_alloc = alloc;
}
if (_values[k-1]) delete _values[k-1];
_values[k-1] = v;
return v;
}

5) /omniORB-4.1.6/build/src/lib/omniORB/omniORB4/Naming.hh: line 404
static inline _ptr_type _unmarshalObjRef(cdrStream& s) {
omniObjRef* o = omniObjRef::_unMarshal(_PD_repoId,s); *[TLazareva]:
This is 404 line.The object "o" is created using "new" operator in
/omniORB-4.1.6/build/src/lib/omniORB/omniORB4/NamingSK.cc file at the 2746
line (full stack you can find below). I think that "o" object should be
deleted before the "return" like this:*
*if (o) {*
* _ptr_type ptrObj = (_ptr_type) o->_ptrToObjRef(_PD_repoId);*
* delete o;*
* return ptrObj;*
*}*
*else ...*
if (o)
return (_ptr_type) o->_ptrToObjRef(_PD_repoId);
else
return _nil();
}
*Full stack:*
PLK: 1152 bytes potentially leaked in 18 blocks
* This memory was allocated from:
malloc [rtlib.o]
operator new(unsigned) [libCrun.a]
void*operator new(unsigned) [rtlib.o]
* omniObjRef*CosNaming::_pof_NamingContextExt::newObjRef(omniIOR*,omniIdentity*)
[NamingSK.cc:2746]*
* omniObjRef*omni::createObjRef(const char*,omniIOR*,bool,omniIdentity*)
[omniInternal.cc:1069]*
* omniObjRef*omniObjRef::_unMarshal(const char*,cdrStream&)
[omniObjRef.cc:990]*
* CosNaming::_objref_NamingContext*CosNaming::NamingContext::_unmarshalObjRef(cdrStream&)
[Naming.hh:404]*
void _0RL_cd_69CECA6A39F685B5_e0000000::unmarshalReturnedValues(cdrStream&)
[NamingSK.cc:1334]
void omniRemoteIdentity::dispatch(omniCallDescriptor&)
[remoteIdentity.cc:188]
void omniObjRef::_invoke(omniCallDescriptor&,bool) [omniObjRef.cc:783]
CosNaming::_objref_NamingContext*CosNaming::_objref_NamingContext::bind_new_context(const
CosNaming::Name&) [NamingSK.cc:1426]
_CORBA_ObjRef_Var<CosNaming::_objref_NamingContext,CosNaming::NamingContext_Helper>corba::Orb::_bindNewContext(_CORBA_ObjRef_Var<CosNaming::_objref_NamingContext,CosNaming::NamingContext_Helper>,const
CosNaming::Name&) [Orb.cc:154]
* Block of 64 bytes (18 times); last block at 0x27e8948


Could you please check the code above on the memory leak issue?
--
Cheers,

*T*atiana *L*azareva**

e-mail (regular): ****@gmail.com*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20120117/8e441f07/attachment.htm
Tatiana Lazareva
2012-01-23 14:32:32 UTC
Permalink
Post by Tatiana Lazareva
Hi all,
It seems that I find some memory leak bugs in omni4.1.6 code. These memory
leak bugs were detected using the purify tool on the Solaris10 OS.
*1) /omniORB-4.1.6/src/lib/omniORB/orbcore/tcp/tcpTransportImpl.cc: line
426:*
while ( 1 ) {
// There is no way to know for sure the buffer is big enough to get
// the info for all the interfaces. We work around this by calling
// the ioctl 2 times and increases the buffer size in the 2nd call.
// If both calls return the info with the same size, we know we have
// got all the interfaces.
char* buf = (char*) malloc(len); [*TLazareva]: this is 426 line.*
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if ( ioctl(sock, OMNI_SIOCGIFCONF, &ifc) < 0 ) {
if ( errno != EINVAL || lastlen != 0 ) {
if ( omniORB::trace(1) ) {
omniORB::logger log;
log << "Warning: ioctl SIOCGICONF failed.\n"
<< "Unable to obtain the list of all interface addresses.\n";
} *[TLazareva]: I think that "buf" variable should be cleaned before
"return": "free buf;" *
return;
}
}
else {
if ( ifc.ifc_len == lastlen )
break; // Success, len has not changed.
lastlen = ifc.ifc_len;
}
len += 10 * sizeof(struct ifreq);
free(buf);
}
*2) /omniORB-4.1.6/src/lib/omnithread/posix.cc: line 376*
omni_thread* t = new omni_thread; *[TLazareva]: This is 376 line. "t"
object was not deleted at the end of function. Is it correct? Purify detect
the memory leak for this object.*
t->_state = STATE_RUNNING;
t->posix_thread = pthread_self ();
DB(cerr << "initial thread " << t->id() << endl);
THROW_ERRORS(pthread_setspecific(self_key, (void*)t));
#ifdef PthreadSupportThreadPriority
#if (PthreadDraftVersion == 4)
THROW_ERRORS(pthread_setprio(t->posix_thread,
posix_priority(PRIORITY_NORMAL)));
#elif (PthreadDraftVersion == 6)
pthread_attr_t attr;
pthread_attr_init(&attr);
THROW_ERRORS(pthread_attr_setprio(&attr,
posix_priority(PRIORITY_NORMAL)));
THROW_ERRORS(pthread_setschedattr(t->posix_thread, attr));
#else
struct sched_param sparam;
sparam.sched_priority = posix_priority(PRIORITY_NORMAL);
THROW_ERRORS(pthread_setschedparam(t->posix_thread, SCHED_OTHER,
&sparam));
*[TLazareva]: I think that "t" object should be cleaned before the end of
function: "delete t;"*
#endif /* PthreadDraftVersion */
#endif /* PthreadSupportThreadPriority */
}
*3) /omniORB-4.1.6/src/lib/omniORB/orbcore/portableserver.cc: line 320*
void*
PortableServer::ServantBase::_do_this(const char* repoId)
{
OMNIORB_ASSERT(repoId);
if (!omni::internalLock) {
// Not initalised yet
OMNIORB_THROW(OBJ_ADAPTER,OBJ_ADAPTER_POANotInitialised,
CORBA::COMPLETED_NO);
}
omniCurrent* current = omniCurrent::get(); *[TLazareva]: This is 320
line. This object is created in
/omniORB-4.1.6/include/omniORB4/internal/omniCurrent.h file at the 92 line
using "new" operator and this object is not cleaned in the code.*
if (current) {
omniCallDescriptor* call_desc = current->callDescriptor();
if (call_desc &&
call_desc->localId()->servant() == (omniServant*)this) {
// In context of an invocation on this servant
omniObjRef* ref = omniOrbPOACurrent::real_get_reference(call_desc);
OMNIORB_ASSERT(ref);*[TLazareva]: I think that "current" object
should be cleaned before the "return": "delete current;"*
return ref->_ptrToObjRef(repoId);
}
}
{
omni_tracedmutex_lock sync(*omni::internalLock);
if (_activations().size() == 1) {
// We only have a single activation -- return a reference to it.
omniObjTableEntry* entry = _activations()[0];
omniOrbPOA* poa = omniOrbPOA::_downcast(entry->adapter());
omniIORHints hints(poa ? poa->policy_list() : 0);
omniObjRef* ref = omni::createLocalObjRef(_mostDerivedRepoId(),
repoId,
entry, hints);
OMNIORB_ASSERT(ref);
return ref->_ptrToObjRef(repoId);
}
}
*
*
PortableServer::POA_var poa = this->_default_POA();
if( CORBA::is_nil(poa) )
OMNIORB_THROW(OBJ_ADAPTER,OBJ_ADAPTER_POANotInitialised,
CORBA::COMPLETED_NO);
return ((omniOrbPOA*)(PortableServer::POA_ptr) poa)->
servant__this(this, repoId);
}
*4) /omniORB-4.1.6/src/lib/omnithread/threaddata.cc: line 51*
omni_thread::value_t*
omni_thread::set_value(key_t k, value_t* v)
{
if (k == 0) return 0;
if (k > _value_alloc) {
next_id_mutex->lock();
key_t alloc = allocated_keys;
next_id_mutex->unlock();
if (k > alloc) return 0;
value_t** nv = new value_t*[alloc]; *[TLazareva]: This is 51 line.
"nv" object is not cleaned in the code.*
key_t i = 0;
if (_values) {
for (; i < _value_alloc; i++)
nv[i] = _values[i];
delete [] _values;
}
for (; i < alloc; i++)
nv[i] = 0;
_values = nv;*[TLazareva]: As I understand "nv" object is not needed
after this line, so it should be deleted: "delete [] nv;"*
_value_alloc = alloc;
}
if (_values[k-1]) delete _values[k-1];
_values[k-1] = v;
return v;
}
5) /omniORB-4.1.6/build/src/lib/omniORB/omniORB4/Naming.hh: line 404
static inline _ptr_type _unmarshalObjRef(cdrStream& s) {
This is 404 line.The object "o" is created using "new" operator in
/omniORB-4.1.6/build/src/lib/omniORB/omniORB4/NamingSK.cc file at the 2746
line (full stack you can find below). I think that "o" object should be
deleted before the "return" like this:*
*if (o) {*
* _ptr_type ptrObj = (_ptr_type) o->_ptrToObjRef(_PD_repoId);*
* delete o;*
* return ptrObj;*
*}*
*else ...*
if (o)
return (_ptr_type) o->_ptrToObjRef(_PD_repoId);
else
return _nil();
}
*Full stack:*
PLK: 1152 bytes potentially leaked in 18 blocks
malloc [rtlib.o]
operator new(unsigned) [libCrun.a]
void*operator new(unsigned) [rtlib.o]
* omniObjRef*CosNaming::_pof_NamingContextExt::newObjRef(omniIOR*,omniIdentity*)
[NamingSK.cc:2746]*
* omniObjRef*omni::createObjRef(const char*,omniIOR*,bool,omniIdentity*)
[omniInternal.cc:1069]*
* omniObjRef*omniObjRef::_unMarshal(const char*,cdrStream&)
[omniObjRef.cc:990]*
* CosNaming::_objref_NamingContext*CosNaming::NamingContext::_unmarshalObjRef(cdrStream&)
[Naming.hh:404]*
void
_0RL_cd_69CECA6A39F685B5_e0000000::unmarshalReturnedValues(cdrStream&)
[NamingSK.cc:1334]
void omniRemoteIdentity::dispatch(omniCallDescriptor&)
[remoteIdentity.cc:188]
void omniObjRef::_invoke(omniCallDescriptor&,bool) [omniObjRef.cc:783]
CosNaming::_objref_NamingContext*CosNaming::_objref_NamingContext::bind_new_context(const
CosNaming::Name&) [NamingSK.cc:1426]
_CORBA_ObjRef_Var<CosNaming::_objref_NamingContext,CosNaming::NamingContext_Helper>corba::Orb::_bindNewContext(_CORBA_ObjRef_Var<CosNaming::_objref_NamingContext,CosNaming::NamingContext_Helper>,const
CosNaming::Name&) [Orb.cc:154]
* Block of 64 bytes (18 times); last block at 0x27e8948
Could you please check the code above on the memory leak issue?
--
Cheers,
*T*atiana *L*azareva**
--
Cheers,

*T*atiana *L*azareva**

e-mail (regular): ****@gmail.com*

e-mail (office): ****@mera.ru*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20120123/5fefb4e2/attachment-0001.htm
Duncan Grisby
2012-01-26 00:37:56 UTC
Permalink
Post by Tatiana Lazareva
It seems that I find some memory leak bugs in omni4.1.6 code. These
memory leak bugs were detected using the purify tool on the Solaris10
OS.
That's a genuine leak. I'll fix it. It's a one-off thing, though, so it
doesn't build up over time.
Post by Tatiana Lazareva
2) /omniORB-4.1.6/src/lib/omnithread/posix.cc: line 376
omni_thread* t = new omni_thread; [TLazareva]: This is 376 line.
"t" object was not deleted at the end of function. Is it correct?
That code is correct. t is the omni_thread object corresponding to the
main thread. If you delete it, everything will break! The thread is
deleted when the very last module that #included omnithread.h is
unloaded. Presumably Purify is running before that.
Post by Tatiana Lazareva
3) /omniORB-4.1.6/src/lib/omniORB/orbcore/portableserver.cc: line 320
That is per-thread state, presumably attached to the omni_thread that
Purify incorrectly thinks is leaked. There is no leak here.
Post by Tatiana Lazareva
4) /omniORB-4.1.6/src/lib/omnithread/threaddata.cc: line 51
This is storage for the per-thread state. It is not leaked.
Post by Tatiana Lazareva
5) /omniORB-4.1.6/build/src/lib/omniORB/omniORB4/Naming.hh: line 404
static inline _ptr_type _unmarshalObjRef(cdrStream& s) {
omniObjRef* o =
omniObjRef::_unMarshal(_PD_repoId,s); [TLazareva]: This is 404
line.The object "o" is created using "new" operator
in /omniORB-4.1.6/build/src/lib/omniORB/omniORB4/NamingSK.cc file at
the 2746 line (full stack you can find below). I think that "o" object
if (o) {
_ptr_type ptrObj = (_ptr_type) o->_ptrToObjRef(_PD_repoId);
delete o;
return ptrObj;
}
That is not a leak in omniORB. The return value is a pointer into the
omniObjRef object, so you mustn't delete it there. There is probably a
leak in your code where it fails to release an object reference.

Cheers,

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