You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@xerces.apache.org by Graham Bennett <gr...@simulcra.org> on 2004/10/31 00:20:41 UTC

possible memory bug

Hi all,

I'm seeing a crash when an IGXMLScanner held statically is destroyed.
I'm using Xerces 2.3.0 on linux compiled with gcc 3.2.  The stack 
trace is as follows:

#0  0x4123e679 in chunk_free (ar_ptr=0x412f2500, p=0x810da08) at
malloc.c:3243
#1  0x4123e424 in __libc_free (mem=0x810da10) at malloc.c:3155
#2  0x08072783 in operator delete(void*) (ptr=0xbbaa050) at
#3  0x40d38c39 in xercesc_2_3::MemoryManagerImpl::deallocate(void*) ()
#4  0x40dd6991 in xercesc_2_3::XMemory::operator delete(void*) ()
#5  0x40d2b4e3 in xercesc_2_3::RefVectorOf<xercesc_2_3::KVStringPair>::~RefVectorOf() ()
#6  0x40d25806 in xercesc_2_3::IGXMLScanner::cleanUp() ()
#7  0x40d24dfd in xercesc_2_3::IGXMLScanner::~IGXMLScanner() ()

I don't know if this is the cause of the crash, but it seems that the 
wrong type of delete is called on the memory in fRawAttrList.  It's 
allocated using placement new with fMemoryManager (in buildAttList), 
but it's deleted with the normal delete operator (in ~RefVectorOf),
which doesn't seem correct.  I'm not customising the memory management 
in any way.

Any insight would be appreciated.

cheers,

Graham.

-- 
Graham Bennett

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


Re: possible memory bug

Posted by Graham Bennett <gr...@simulcra.org>.
On Sun, Oct 31, 2004 at 05:21:29PM -0800, david_n_bertoni@us.ibm.com wrote:
> > Afaik, when overloading 'placement' new and delete
> > like that, the only time the corresponding overload
> > of delete will be called is if the constructor throws.
> > All other times you have to call the destructor and
> > the right version of delete yourself.
> 
> This is not true.  If a class implements operator new and delete, they are 
> called to allocate and deallocate memory.  Don't forget you can overload 
> "placement" new (a term which itself is "overloaded") with arbitrary 
> parameters, and this is what Xerces-C does.

Ah, I hadn't seen that the KVStringPair inherited an operator delete
from XMemory, that explains it all, thanks.
 
> Take a look at the file XMemory.hpp and note the various overloads for 
> operator new.  You will see there is one that takes a size_t and a pointer 
> to a MemoryManager instance.  This is the one that's called when doing 
> "placement" new with a pointer to a MemoryManager instance.
> 
> This overload of operator delete is the one that's called if the 
> constructor throws:
> 
>     void operator delete(void* p, MemoryManager* memMgr);
> 
> This is the one that's called by the delete expression, and is the one 
> that retrieves the pointer the MemoryManager instance, and frees the 
> allocated memory:
> 
>     void operator delete(void* p, MemoryManager* memMgr);

Presumably you mean void operator delete(void* p) here, but yes this
makes sense.
 
> The implementation of these functions in XMemory.cpp will clarify what is 
> happening.
> 
> > > Often, when I see a crash in freeing memory, I discover that the crash
> > > is a symptom of a previous bad transaction with the heap, like
> > > deleting a pointer that's already been deleted.
> > 
> > True, but in this case Purify isn't showing anything suspicious.
> 
> Can you should set some breakpoints and make note of the address that's 
> returned from MemoryManagerImpl::allocate() for this object, and verify 
> the same address is passed to MemoryManagerImpl::deallocate()?
> 
> You might also want to try a small test program that creates an instance 
> of IGXMLScanner, then deletes it, to verify something is completely broken 
> with the code.  I used Xerces-C 2.3 extensively, and never had this 
> problem, but perhaps you have a corrupted library, or you're using a 
> different compiler and there's a bug.

I will do some more investigation and get back to the list if I turn up
anything useful.

On a slightly different note, I was wondering what the use case for the
pluggable memory manager structure is?  From my cursory look at it, it
seems to add some non-trivial time and space overhead to the usual use
of the library where one doesn't care about plugging in a custom memory
manager.

Thanks very much for your help,

Graham.

-- 
Graham Bennett

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


Re: possible memory bug

Posted by da...@us.ibm.com.
> Afaik, when overloading 'placement' new and delete
> like that, the only time the corresponding overload
> of delete will be called is if the constructor throws.
> All other times you have to call the destructor and
> the right version of delete yourself.

This is not true.  If a class implements operator new and delete, they are 
called to allocate and deallocate memory.  Don't forget you can overload 
"placement" new (a term which itself is "overloaded") with arbitrary 
parameters, and this is what Xerces-C does.

Take a look at the file XMemory.hpp and note the various overloads for 
operator new.  You will see there is one that takes a size_t and a pointer 
to a MemoryManager instance.  This is the one that's called when doing 
"placement" new with a pointer to a MemoryManager instance.

This overload of operator delete is the one that's called if the 
constructor throws:

    void operator delete(void* p, MemoryManager* memMgr);

This is the one that's called by the delete expression, and is the one 
that retrieves the pointer the MemoryManager instance, and frees the 
allocated memory:

    void operator delete(void* p, MemoryManager* memMgr);

The implementation of these functions in XMemory.cpp will clarify what is 
happening.

> > Often, when I see a crash in freeing memory, I discover that the crash
> > is a symptom of a previous bad transaction with the heap, like
> > deleting a pointer that's already been deleted.
> 
> True, but in this case Purify isn't showing anything suspicious.

Can you should set some breakpoints and make note of the address that's 
returned from MemoryManagerImpl::allocate() for this object, and verify 
the same address is passed to MemoryManagerImpl::deallocate()?

You might also want to try a small test program that creates an instance 
of IGXMLScanner, then deletes it, to verify something is completely broken 
with the code.  I used Xerces-C 2.3 extensively, and never had this 
problem, but perhaps you have a corrupted library, or you're using a 
different compiler and there's a bug.

Dave

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


Re: possible memory bug

Posted by Graham Bennett <gr...@simulcra.org>.
On Sun, Oct 31, 2004 at 10:18:54AM -0800, david_n_bertoni@us.ibm.com
wrote:
> > > All classes that derive from XMemory use "placement" new with a
> > > MemoryManager instance, and the normal delete expression.  The
> > > call 
> stack 
> > > you posted looks fine. 
> > 
> > But is this the correct behaviour?  I think the destructor for the
> > object should be called, then the operator delete from the
> > MemoryManager interface called explicitly.
> 
> It's the correct behavior.  XMemory has a class-specific operator new
> and operator delete.  Operator new allocates memory for the object,
> plus enough memory to store a pointer the supplied MemoryManager
> instance, which it places at the beginning of the block.  It then
> returns a pointer into the block after the pointer to the
> MemoryManager.  The delete expression runs the destructor for the
> object, then calls the class-specific operator delete, which retrieves
> the pointer, then calls the MemoryManager's deallocate() function.
> 
> For more details, take a look at the implementations of XMemory::new()
> and XMemory::delete().

Afaik, when overloading 'placement' new and delete like that, the only
time the corresponding overload of delete will be called is if the
constructor throws.  All other times you have to call the destructor and
the right version of delete yourself.

> Often, when I see a crash in freeing memory, I discover that the crash
> is a symptom of a previous bad transaction with the heap, like
> deleting a pointer that's already been deleted.

True, but in this case Purify isn't showing anything suspicious.

cheers,

Graham.

-- 
Graham Bennett

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


Re: possible memory bug

Posted by da...@us.ibm.com.
Hi Graham,

> > All classes that derive from XMemory use "placement" new with a 
> > MemoryManager instance, and the normal delete expression.  The call 
stack 
> > you posted looks fine. 
> 
> But is this the correct behaviour?  I think the destructor for the
> object should be called, then the operator delete from the MemoryManager
> interface called explicitly.

It's the correct behavior.  XMemory has a class-specific operator new and 
operator delete.  Operator new allocates memory for the object, plus 
enough memory to store a pointer the supplied MemoryManager instance, 
which it places at the beginning of the block.  It then returns a pointer 
into the block after the pointer to the MemoryManager.  The delete 
expression runs the destructor for the object, then calls the 
class-specific operator delete, which retrieves the pointer, then calls 
the MemoryManager's deallocate() function.

For more details, take a look at the implementations of XMemory::new() and 
XMemory::delete().

Often, when I see a crash in freeing memory, I discover that the crash is 
a symptom of a previous bad transaction with the heap, like deleting a 
pointer that's already been deleted.

Dave

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


Re: possible memory bug

Posted by Graham Bennett <gr...@simulcra.org>.
On Sat, Oct 30, 2004 at 09:20:46PM -0400, david_n_bertoni@us.ibm.com wrote:
> > I'm seeing a crash when an IGXMLScanner held statically is destroyed.
> > I'm using Xerces 2.3.0 on linux compiled with gcc 3.2.
> 
> Can you elaborate on what you mean by "held statically?"  You shouldn't 
> have any static instance of Xerces-C classes, as they cannot be created 
> before the library is initialized with PlatformUtils::Initialize().

Hi,

The Xerces objects are held by pointer (basically a singleton), and are
only constructed after XMLPlatformUtils::Initialize() has been called,
so I don't think this is the problem.
 
> > I don't know if this is the cause of the crash, but it seems that the 
> > wrong type of delete is called on the memory in fRawAttrList.  It's 
> > allocated using placement new with fMemoryManager (in buildAttList),
> > but it's deleted with the normal delete operator (in ~RefVectorOf),
> > which doesn't seem correct.  I'm not customising  the memory management
> > in any way.
> 
> All classes that derive from XMemory use "placement" new with a 
> MemoryManager instance, and the normal delete expression.  The call stack 
> you posted looks fine.  

But is this the correct behaviour?  I think the destructor for the
object should be called, then the operator delete from the MemoryManager
interface called explicitly.

> Have you tried using a newer version of Xerces-C 
> to see if the problem persists?

Not yet, as it involves rebuilding many dependencies, but I will give it
a try at some point.
 
> One possibility is you've already shut down the library, through 
> PlatformUtils::Terminate(), before you've freed this IGXMLScanner 
> instance, although I would expect a different stack trace, if that were 
> the case.

We never call XMLPlatformUtils::Terminate, because we can't guarantee
it's going to be called in the right order as you say.

Thanks for the suggestions,

Graham.

-- 
Graham Bennett

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


Re: possible memory bug

Posted by da...@us.ibm.com.
> I'm seeing a crash when an IGXMLScanner held statically is destroyed.
> I'm using Xerces 2.3.0 on linux compiled with gcc 3.2.

Can you elaborate on what you mean by "held statically?"  You shouldn't 
have any static instance of Xerces-C classes, as they cannot be created 
before the library is initialized with PlatformUtils::Initialize().

> I don't know if this is the cause of the crash, but it seems that the 
> wrong type of delete is called on the memory in fRawAttrList.  It's 
> allocated using placement new with fMemoryManager (in buildAttList),
> but it's deleted with the normal delete operator (in ~RefVectorOf),
> which doesn't seem correct.  I'm not customising  the memory management
> in any way.

All classes that derive from XMemory use "placement" new with a 
MemoryManager instance, and the normal delete expression.  The call stack 
you posted looks fine.  Have you tried using a newer version of Xerces-C 
to see if the problem persists?

One possibility is you've already shut down the library, through 
PlatformUtils::Terminate(), before you've freed this IGXMLScanner 
instance, although I would expect a different stack trace, if that were 
the case.

Dave

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org