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 bu...@apache.org on 2001/12/11 17:35:28 UTC
DO NOT REPLY [Bug 5359] New: -
Document reference counting fails in multi-threaded multi-processor environment
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=5359>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=5359
Document reference counting fails in multi-threaded multi-processor environment
Summary: Document reference counting fails in multi-threaded
multi-processor environment
Product: Xerces-C++
Version: 1.5.2
Platform: Sun
OS/Version: Solaris
Status: NEW
Severity: Critical
Priority: Other
Component: DOM
AssignedTo: xerces-c-dev@xml.apache.org
ReportedBy: mikael.carlstedt@st.se
The error occurs infrequently, and so far never on a single-processor machine.
It always occurs at the same point in the source code. The symptoms suggest
that somehow the reference counter for a DocumentImpl object is corrupted so
that the object is deleted while it is still in use.
The error occurs in ParentNode::removeChild():
387 //fix other ranges for change before deleting the node
388 if (getOwnerDocument() != null) {
389 typedef RefVectorOf<RangeImpl> RangeImpls;
390 RangeImpls* ranges = this->getOwnerDocument()->getRanges();
>> ranges != null here, which means the owner document has not yet been deleted
391 if (ranges != null) {
392 unsigned int sz = ranges->size();
393 if (sz != 0) {
394 for (unsigned int i =0; i<sz; i++) {
395 if (ranges->elementAt(i) != null)
396 ranges->elementAt(i)->updateRangeForDeletedNode
(oldChild);
>> This is when the shit hits the fan (already when i = 0), because elementAt()
returns a whacko pointer. The reason for this is that the owner document has
now been deleted, indicated by a null-valued ranges member variable.
397 }
398 }
399 }
400 }
Brief explanation of how we are using Xerces-C++ in our application:
DOMParser objects are pooled, and access to the pool is synchronized. Before a
DOMParser object is returned to the pool the DOMParser::reset() is always
called to make sure that the DOM_Document object is released by the parser.
Thus, the environment is multi-threaded in the sense that different DOMParser
objects and different DOM_Document objects are accessed concurrently by
different threads, but each object is only accessed by one thread at a time. We
use the DOM_Document::importNode() method to copy nodes from one DOM_Document
object into another, and the error occurs when the original object is deleted.
In the test environment, we parse the exact same XML document several thousand
times before the error occurs, so it could hardly be data related.
Xerces-C++ was compiled on solaris using g++ (gcc version 2.95.3).
Call stack (note: this was generated with Xerces-C++ 1.6.0, but the resulting
call stack is essentially identical in 1.5.2):
#0 0xfc1561a0 in DOM_Node::operator== (this=0x84, other=@0xfd1014f8) at
DOM_Node.cpp:160
#1 0xfc1e45d4 in RangeImpl::updateRangeForDeletedNode (this=0x60,
node=0x1c26f8) at RangeImpl.cpp:1623
#2 0xfc1d0a78 in ParentNode::removeChild (this=0x1ef7a0, oldChild=0x1c26f8) at
ParentNode.cpp:396
#3 0xfc1c6f9c in NodeImpl::deleteIf (thisNode=0x1ef7a0) at NodeImpl.cpp:209
#4 0xfc1c787c in NodeImpl::unreferenced (this=0x1ef7a0) at NodeImpl.cpp:353
#5 0xfc1ea968 in RefCountedImpl::removeRef (thisNode=0x1ef7a0) at
RefCountedImpl.cpp:117
#6 0xfc156124 in DOM_Node::~DOM_Node (this=0x101180, __in_chrg=2) at
DOM_Node.cpp:144
#7 0xfc1545b0 in DOM_Element::~DOM_Element (this=0x101180, __in_chrg=2) at
DOM_Element.cpp:111
#8 <destructor in our wrapper class>
Local variables in ParentNode::removeChild():
*this = {<ChildNode> = {<NodeImpl> = {<NodeListImpl> = {<RefCountedImpl> =
{nodeRefCount = 0, _vptr. = 0xfc4c5c50}, <No data fields>}, ownerNode =
0x14c7c8, flags = 0, static READONLY = 1, static SYNCDATA = 2, static
SYNCCHILDREN = 4, static OWNED = 8, static FIRSTCHILD = 16, static SPECIFIED =
32, static IGNORABLEWS = 64, static SETVALUE = 128, static ID_ATTR = 256,
static USERDATA = 512, static HASSTRING = 1024, static gLiveNodeImpls = 404,
static gTotalNodeImpls = 262196}, previousSibling = 0x0, nextSibling = 0x0},
ownerDocument = 0x14c7c8, firstChild = 0x1c26f8, fCachedLength = 3,
fCachedChild = 0x1d41c8, fCachedChildIndex = 2}
*ownerDocument = {<ParentNode> = {<ChildNode> = {<NodeImpl> = {<NodeListImpl> =
{<RefCountedImpl> = {nodeRefCount = 2006649, _vptr. = 0xfc4cb258}, <No data
fields>}, ownerNode = 0x0, flags = 0, static READONLY = 1, static SYNCDATA = 2,
static SYNCCHILDREN = 4, static OWNED = 8, static FIRSTCHILD = 16, static
SPECIFIED = 32, static IGNORABLEWS = 64, static SETVALUE = 128, static ID_ATTR
= 256, static USERDATA = 512, static HASSTRING = 1024, static gLiveNodeImpls =
404, static gTotalNodeImpls = 262196}, previousSibling = 0x0, nextSibling =
0x0}, ownerDocument = 0x0, firstChild = 0x0, fCachedLength = -1, fCachedChild =
0x0, fCachedChildIndex = -1}, docType = 0x0, docElement = 0x0, namePool =
0x179b20, fNodeIDMap = 0x0, iterators = 0x0, treeWalkers = 0x0, userData = 0x0,
ranges = 0x0, fChanges = 46, errorChecking = 1361856}
*ranges = {fAdoptedElems = false, fCurCount = 88, fMaxCount = 0, fElemList =
0x1e9e79}
ranges->elementAt(i) = 0x60
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org