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=5238>. 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=5238 static void DOMStringTerminate() is not atomic and can crash rarely Summary: static void DOMStringTerminate() is not atomic and can crash rarely Product: Xerces-C++ Version: 1.5.1 Platform: PC OS/Version: Windows NT/2K Status: NEW Severity: Critical Priority: Other Component: DOM AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] I observed crashes of Xerces-C 1.5.1. These crashes occurred only in highly multithreaded applications on a Dual-Pentium machine (2x750MHz Pentium III, 1GB RAM, Windows 2000 Server). On a single-processor machine I was not able to reproduce these crashes. The application concurrently parses small XMLs. The maximum number of threads concurrently parsing is 20, but the acutal number varies between 0 and 20. I tried to debug Xerces-C and found out why the application crashed: The static function DOMStringTerminate() is only called by DOMStringHandle::operator delete. The comments there say that "This will generally only happen on PlatFormUtils::Terminate(), since any use of the DOM will cache some commonly used DOMStrings forever (until Terminate)." But this is in fact not the case. In a simple application which executes the following steps 1. Initialize 2. Parse an XML 3. Parse another XML 4. Terminate DOMStringTerminate is called after step 2 AND after step 3. In a multithreaded application this can cause the application to crash. The reasons are the following: 1. DOMStringTerminate() deletes the synchronization mutex and sets its value to NULL: delete DOMStringHandleMutex; // Delete the synchronization mutex, DOMStringHandleMutex = 0; 2. A different thread might access this mutex using XMLMutex& DOMStringHandle::getMutex() which is called from DOMStringHandle::operator new or DOMStringHandle::operator delete. XMLMutex& DOMStringHandle::getMutex() { if (!DOMStringHandleMutex) { XMLMutex* tmpMutex = new XMLMutex; if (XMLPlatformUtils::compareAndSwap((void**)&DOMStringHandleMutex, tmpMutex, 0)) { // Someone beat us to it, so let's clean up ours delete tmpMutex; } } return *DOMStringHandleMutex; } 3. Now let a multithreaded process execute the following code: a) Thread 1: enter DOMStringTerminate() b) Thread 1: call delete DOMStringHandleMutex; c) Thread 2: enter DOMStringHandle::getMutex() d) Thread 2: calling if (!DOMStringHandleMutex) yields FALSE als DOMStringHandleMutex is still != NULL, though already deleted e) Thread 2: call return *DOMStringHandleMutex; f) Thread 1: call DOMStringHandleMutex = 0; In this case DOMStringHandleMutex is used by Thread 2 although it is concurrently deleted by Thread 1. This is due to the fact that DOMStringTerminate() is not atomic, but it should be. DOMStringHandle::getMutex is atomic. While debugging I found out that the scenario a) to f) in fact occurs, consequently Thread 2 crashes when trying to use the just deleted DOMStringHandleMutex. Please contact me directly when more questions occur. I hope I can help you then. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]