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 "Cornelius, Martin" <Ma...@softwareag.com> on 2002/01/25 14:37:40 UTC

Xerces in an application where fail of new must be tolerated : I mpossible ?

Hi there,

we are currently reasoning about whether it is possible to use Xerces in a
multithreaded server Application, whrere failure of memory allocation must
be tolerated. More exactly: failure of global operator new or malloc() may
always happen when the server is heavy loaded, but they will never terminate
the server. Of course, the particular client request in whose context the
failed allocation happened must be aborted in this case. However, this
abortion will proceed in a controlled way and MUST NEVER lead to memory
leaks.

AFAICS, the current coding of Xerces does not fulfill this requirement. E,g,
look at this code fragments from class QName:

class XMLUTIL_EXPORT QName
{
// ....
private :
    XMLCh*              fPrefix;
    XMLCh*              fLocalPart;
    XMLCh*              fRawName;
};

fPrefix, fLocalPart, and fRawname are initialized to zero, and later on
global operator new[] is used to allocate buffers. In the destructor,
cleanup() is called:

void QName::cleanUp()
{
    delete [] fLocalPart;
    delete [] fPrefix;
    delete [] fRawName;
}

So far, so good. But now look at another invocation of new in this member
function:

void QName::setLocalPart(const XMLCh* localPart)
{
    unsigned int newLen;

    newLen = XMLString::stringLen(localPart);
    if (!fLocalPartBufSz || (newLen > fLocalPartBufSz))
    {
        delete [] fLocalPart;
        fLocalPartBufSz = newLen + 8;
        fLocalPart = new XMLCh[fLocalPartBufSz + 1];
                          ^^^
    }
    XMLString::moveChars(fLocalPart, localPart, newLen + 1);
}

If this new fails and raises an exception, we run into trouble: If we call
Qname's destructor or call Qname::cleanUp directly, fLocalPart is deleted
twice, if we do not, we get two memory leaks for fPrefix and fRawname.
Unfortunately, code like this seems to be present many times in Xerces 8-(.
Worse, Qname is a basic building block, and all users of Qname seem to
ignore totally that Qname might throw bad_alloc.

These are several solutions i can currently imagine, orderded by my personal
preference:

1 - inspect the complete code for possible memory leaks caused by bad_alloc
execeptions, and try to fix this using try/catch statements. AFAICS, this is
a quite daunting and error-prone task, as basic classes like Qname are used
in many places and may throw bad_alloc in most operations. 

2 - Encourage users of Xerces to override global new and delete if they want
applications to survive bad_malloc. This does not require to modify Xerces,
but it may be undesirable or even impossible in many circumstances. IMHO, a
library designed for common use should not require it's users to do this.

3 - Throughout Xerces, replace ALL occurences of new and delete by calls to
suitable allocator classes/functions, and never use global new and delete
outside of this allocators. The IDOM has already made steps in this
direction by using IDDocumentImpl as some kind of arena allocator ( that
does not support deletion ). Of course, this is also a boring task, but in
contrast to solution 1 the effort can be easily estimated (simply count the
new and delete invocations) and a result that fulfills the requirement is
guaranteed. Currently i think, this is the way to go.

Please, send me your comments !  Martin


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