Closed
Bug 19183
Opened 25 years ago
Closed 25 years ago
Crash on shutdown... Service Manager was deleted too soon.
Categories
(Core :: XPCOM, defect, P2)
Tracking
()
RESOLVED
FIXED
M12
People
(Reporter: rpotts, Assigned: dp)
References
Details
(Keywords: crash)
Attachments
(1 file)
1.70 KB,
message/rfc822
|
Details |
I just hot this crash when exiting mozilla... It looks like a DLL is unloading a service in its shutdown routine :-( It looks like nsTextTransformer::Shutdown() requires the ServiceManager. Unfortunately, it has already been released when Shutdown() is called :-( Should the ServiceManager be Released *before* ComponentManager is shut down? Below is the stack trace: ========================== nsServiceManager::ReleaseService(const nsID & {...}, nsISupports * 0x011d15f0, nsIShutdownListener * 0x00000000) line 492 + 26 bytes nsTextTransformer::Shutdown() line 103 + 19 bytes nsLayoutModule::Shutdown() line 262 nsLayoutModule::~nsLayoutModule() line 172 nsLayoutModule::`scalar deleting destructor'(unsigned int 0x00000001) + 15 bytes nsLayoutModule::Release(nsLayoutModule * const 0x011bcfe0) line 174 + 134 bytes nsDll::Shutdown() line 394 + 18 bytes nsFreeLibrary(nsDll * 0x00c13560, nsIServiceManager * 0x00000000, int 0x00000003) line 353 nsFreeLibraryEnum(nsHashKey * 0x00c13450, void * 0x00c13560, void * 0x0012fdf4) line 401 + 64 bytes _hashEnumerate(PLHashEntry * 0x00c13410, int 0x00000005, void * 0x0012fddc) line 89 + 26 bytes PL_HashTableEnumerateEntries(PLHashTable * 0x00c056a0, int (PLHashEntry *, int, void *)* 0x10019760 _hashEnumerate(PLHashEntry *, int, void *), void * 0x0012fddc) line 368 + 15 bytes nsHashtable::Enumerate(int (nsHashKey *, void *, void *)* 0x10046cb0 nsFreeLibraryEnum(nsHashKey *, void *, void *), void * 0x0012fdf4) line 218 + 20 bytes nsNativeComponentLoader::UnloadAll(nsNativeComponentLoader * const 0x00c05c70, int 0x00000003) line 883 nsComponentManagerImpl::UnloadLibraries(nsIServiceManager * 0x00000000, int 0x00000003) line 1949 + 22 bytes nsComponentManagerImpl::Shutdown() line 272 NS_ShutdownXPCOM(nsIServiceManager * 0x00000000) line 539 + 11 bytes main(int 0x00000001, char * * 0x00c04900) line 699 + 8 bytes mainCRTStartup() line 338 + 17 bytes KERNEL32! 77f
Assignee | ||
Updated•25 years ago
|
Severity: normal → major
Priority: P3 → P2
Target Milestone: M12
Assignee | ||
Updated•25 years ago
|
Status: NEW → ASSIGNED
Assignee | ||
Comment 1•25 years ago
|
||
mmh! That is ok for a dll to access the servicemanager on shutdown. Got to see...
Assignee | ||
Comment 2•25 years ago
|
||
I dont get the crash at all. ReleaseService() is obsolete; all it does is NS_RELEASE anyway. So I dont know why this would ever be a problem. Are you still seeing this ?
Reporter | ||
Comment 3•25 years ago
|
||
No I haven't been seeing this crash, but I forget what I did to cause the nsTextTransformer to get loaded... I still think that the code is rather dubious... The call to NS_RELEASE2() will only null out the mGlobalServiceManager if the refcount is zero. If anyone else is holding a reference, mGlobalServiceManager will not be nulled. However, if those other references are released during the shutdown process, then mGlobalServiceManager will be a bogus pointer and calls through nsServiceManager::xxx() will crash...
Assignee | ||
Updated•25 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → WORKSFORME
Assignee | ||
Comment 4•25 years ago
|
||
Rick, it looks ok. The fact that we are hitting the release of the service manager means nonone is holding on to it.
Reporter | ||
Comment 5•25 years ago
|
||
Exactly. No one is holding onto it, but someone could still call though the *static* nsServiceManager:xxx() functions which would *try* to use mGlobalServiceManager which is now bogus!
Assignee | ||
Updated•25 years ago
|
Status: RESOLVED → REOPENED
Assignee | ||
Comment 6•25 years ago
|
||
I think now I understand where you are getting at. Let me try summarizing. NS_RELEASE2(mGlobalServiceManager, cnt) will set mGlobalServiceManager to NULL only after the completion of the release. So during the release mGlobalServiceManager holds its pointer value. And the question you ask is what if someone calls back into the nsServiceManager:: during the servicemanager release. Would we be ok as this would access mGlobalServiceManager ? One point though: mglobalservicemanager wont be garbage at any point. It will be either NULL or the right object that hasn't been completly deleted. I think we would be ok. But it is better to avoid this case. Here is what I think I will do. before calling release on the mGlobalServiceManager, we null the mGlobalServiceManager out. tmpServMgr = mGlobalServiceManager; mGlobalServiceManager = NULL; NS_RELEASE2(tmpServMgr, cnt);
Assignee | ||
Updated•25 years ago
|
Status: REOPENED → ASSIGNED
Assignee | ||
Comment 9•25 years ago
|
||
Can one of your seeing the problem try the patch out. Index: nsXPComInit.cpp =================================================================== RCS file: /cvsroot/mozilla/xpcom/build/nsXPComInit.cpp,v retrieving revision 1.49 diff -c -r1.49 nsXPComInit.cpp *** nsXPComInit.cpp 1999/11/30 04:50:26 1.49 --- nsXPComInit.cpp 1999/12/03 19:03:31 *************** *** 528,534 **** // here again: NS_IF_RELEASE(servMgr); ! NS_RELEASE2(nsServiceManager::mGlobalServiceManager, cnt); NS_ASSERTION(cnt == 0, "Service Manager being held past XPCOM shutdown."); // Release the global case converter --- 528,541 ---- // here again: NS_IF_RELEASE(servMgr); ! ! // Dont use COMPtr here. We want to delete the global service manager ! // and before that make the global serivce manager NULL so that while ! // deletion is in progress, no one will be able to use the global ! // servicemanager. ! nsIServiceManager *tmpServiceManager = nsServiceManager::mGlobalServiceManager; ! nsServiceManager::mGlobalServiceManager = NULL; ! NS_RELEASE2(tmpServiceManager, cnt); NS_ASSERTION(cnt == 0, "Service Manager being held past XPCOM shutdown."); // Release the global case converter
Comment 10•25 years ago
|
||
The crash is fixed now (I found a reproducible case). But I get the following assertions: "Service Manager being held past XPCOM shutdown." NTDLL! 77f7629c() nsDebug::Assertion(const char * 0x10090cf8, const char * 0x10090cec, const char * 0x10090cbc, int 538) line 284 + 13 bytes NS_ShutdownXPCOM(nsIServiceManager * 0x00000000) line 538 + 65 bytes main(int 1, char * * 0x01004e00) line 713 + 8 bytes mainCRTStartup() line 338 + 17 bytes KERNEL32! 77f1ba06() NS_ERROR("Setting main thread twice?"); NTDLL! 77f7629c() nsDebug::Error(const char * 0x1009d8a8, const char * 0x1009d878, int 309) line 309 + 13 bytes nsIThread::SetMainThread() line 309 + 20 bytes NS_InitXPCOM(nsIServiceManager * * 0x00000000, nsFileSpec * 0x00000000, nsFileSpec * 0x00000000) line 182 + 5 bytes nsServiceManager::GetGlobalServiceManager(nsIServiceManager * * 0x0012fb7c) line 474 + 11 bytes nsServiceManager::GetService(const nsID & {...}, const nsID & {...}, nsISupports * * 0x0012fba4, nsIShutdownListener * 0x00000000) line 498 + 9 bytes nsCharsetMenu::Done() line 232 + 22 bytes nsCharsetMenu::~nsCharsetMenu() line 186 nsCharsetMenu::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsCharsetMenu::Release(nsCharsetMenu * const 0x02df3c60) line 165 + 134 bytes DeleteEntry(nsHashKey * 0x02df4ae0, void * 0x02df32c0, void * 0x00000000) line 213 + 18 bytes _hashEnumerateRemove(PLHashEntry * 0x02df4aa0, int 32, void * 0x0012fc54) line 227 + 26 bytes PL_HashTableEnumerateEntries(PLHashTable * 0x01004980, int (PLHashEntry *, int, void *)* 0x1001bab0 _hashEnumerateRemove(PLHashEntry *, int, void *), void * 0x0012fc54) line 368 + 15 bytes nsHashtable::Reset(int (nsHashKey *, void *, void *)* 0x100469b0 DeleteEntry(nsHashKey *, void *, void *), void * 0x00000000) line 243 + 20 bytes nsObjectHashtable::Reset() line 344 nsObjectHashtable::~nsObjectHashtable() line 310 nsObjectHashtable::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsServiceManagerImpl::~nsServiceManagerImpl() line 240 + 31 bytes nsServiceManagerImpl::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsServiceManagerImpl::Release(nsServiceManagerImpl * const 0x01004a20) line 249 + 132 bytes nsVCardFactory::~nsVCardFactory() line 83 + 27 bytes nsVCardFactory::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsVCardFactory::Release(nsVCardFactory * const 0x03fea200) line 111 + 131 bytes nsCOMPtr<nsIFactory>::assign_assuming_AddRef(nsIFactory * 0x00000000) line 416 nsCOMPtr<nsIFactory>::assign_with_AddRef(nsISupports * 0x00000000) line 761 nsCOMPtr<nsIFactory>::operator=(nsIFactory * 0x00000000) line 516 nsFactoryEntry::~nsFactoryEntry() line 160 nsFactoryEntry::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsFactoryEntry_Destroy(nsHashKey * 0x010204e0, void * 0x0103b2d0, void * 0x00000000) line 180 + 28 bytes _hashEnumerateRemove(PLHashEntry * 0x010204a0, int 144, void * 0x0012fdc8) line 227 + 26 bytes PL_HashTableEnumerateEntries(PLHashTable * 0x01004590, int (PLHashEntry *, int, void *)* 0x1001bab0 _hashEnumerateRemove(PLHashEntry *, int, void *), void * 0x0012fdc8) line 368 + 15 bytes nsHashtable::Reset(int (nsHashKey *, void *, void *)* 0x10040cf0 nsFactoryEntry_Destroy(nsHashKey *, void *, void *), void * 0x00000000) line 243 + 20 bytes nsObjectHashtable::Reset() line 344 nsObjectHashtable::~nsObjectHashtable() line 310 nsObjectHashtable::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsComponentManagerImpl::Shutdown() line 272 + 31 bytes NS_ShutdownXPCOM(nsIServiceManager * 0x00000000) line 545 + 11 bytes main(int 1, char * * 0x01004e00) line 713 + 8 bytes mainCRTStartup() line 338 + 17 bytes KE nsDebug::Error(const char * 0x1009d8a8, const char * 0x1009d878, int 309) line 309 + 13 bytes nsIThread::SetMainThread() line 309 + 20 bytes NS_InitXPCOM(nsIServiceManager * * 0x00000000, nsFileSpec * 0x00000000, nsFileSpec * 0x00000000) line 182 + 5 bytes nsServiceManager::GetGlobalServiceManager(nsIServiceManager * * 0x0012fb18) line 474 + 11 bytes nsServiceManager::GetService(const nsID & {...}, const nsID & {...}, nsISupports * * 0x0012fb58, nsIShutdownListener * 0x00000000) line 498 + 9 bytes nsGetServiceByCID::operator()(const nsID & {...}, void * * 0x0012fb58) line 39 + 22 bytes nsCOMPtr<nsIAppShellService>::assign_from_helper(const nsCOMPtr_helper & {...}, const nsID & {...}) line 768 + 18 bytes nsCOMPtr<nsIAppShellService>::nsCOMPtr<nsIAppShellService>(const nsCOMPtr_helper & {...}) line 497 nsWebShellWindow::Close(nsWebShellWindow * const 0x023c67d0) line 421 + 30 bytes nsAppShellService::~nsAppShellService() line 163 nsAppShellService::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsAppShellService::Release(nsAppShellService * const 0x01023560) line 176 + 134 bytes DeleteEntry(nsHashKey * 0x01023460, void * 0x01023520, void * 0x00000000) line 213 + 18 bytes _hashEnumerateRemove(PLHashEntry * 0x01023420, int 56, void * 0x0012fc54) line 227 + 26 bytes PL_HashTableEnumerateEntries(PLHashTable * 0x01004980, int (PLHashEntry *, int, void *)* 0x1001bab0 _hashEnumerateRemove(PLHashEntry *, int, void *), void * 0x0012fc54) line 368 + 15 bytes nsHashtable::Reset(int (nsHashKey *, void *, void *)* 0x100469b0 DeleteEntry(nsHashKey *, void *, void *), void * 0x00000000) line 243 + 20 bytes nsObjectHashtable::Reset() line 344 nsObjectHashtable::~nsObjectHashtable() line 310 nsObjectHashtable::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsServiceManagerImpl::~nsServiceManagerImpl() line 240 + 31 bytes nsServiceManagerImpl::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsServiceManagerImpl::Release(nsServiceManagerImpl * const 0x01004a20) line 249 + 132 bytes nsVCardFactory::~nsVCardFactory() line 83 + 27 bytes nsVCardFactory::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsVCardFactory::Release(nsVCardFactory * const 0x03fea200) line 111 + 131 bytes nsCOMPtr<nsIFactory>::assign_assuming_AddRef(nsIFactory * 0x00000000) line 416 nsCOMPtr<nsIFactory>::assign_with_AddRef(nsISupports * 0x00000000) line 761 nsCOMPtr<nsIFactory>::operator=(nsIFactory * 0x00000000) line 516 nsFactoryEntry::~nsFactoryEntry() line 160 nsFactoryEntry::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsFactoryEntry_Destroy(nsHashKey * 0x010204e0, void * 0x0103b2d0, void * 0x00000000) line 180 + 28 bytes _hashEnumerateRemove(PLHashEntry * 0x010204a0, int 144, void * 0x0012fdc8) line 227 + 26 bytes PL_HashTableEnumerateEntries(PLHashTable * 0x01004590, int (PLHashEntry *, int, void *)* 0x1001bab0 _hashEnumerateRemove(PLHashEntry *, int, void *), void * 0x0012fdc8) line 368 + 15 bytes nsHashtable::Reset(int (nsHashKey *, void *, void *)* 0x10040cf0 nsFactoryEntry_Destroy(nsHashKey *, void *, void *), void * 0x00000000) line 243 + 20 bytes nsObjectHashtable::Reset() line 344 nsObjectHashtable::~nsObjectHashtable() line 310 nsObjectHashtable::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsComponentManagerImpl::Shutdown() line 272 + 31 bytes NS_ShutdownXPCOM(nsIServiceManager * 0x00000000) line 545 + 11 bytes main(int 1, char * * 0x01004e00) line 713 + 8 bytes mainCRTStartup() line 338 + 17 bytes KERNEL3 nsDebug::Error(const char * 0x1009d8a8, const char * 0x1009d878, int 309) line 309 + 13 bytes nsIThread::SetMainThread() line 309 + 20 bytes NS_InitXPCOM(nsIServiceManager * * 0x00000000, nsFileSpec * 0x00000000, nsFileSpec * 0x00000000) line 182 + 5 bytes nsServiceManager::GetGlobalServiceManager(nsIServiceManager * * 0x0012fa78) line 474 + 11 bytes nsServiceManager::GetService(const nsID & {...}, const nsID & {...}, nsISupports * * 0x0012fab8, nsIShutdownListener * 0x00000000) line 498 + 9 bytes nsGetServiceByCID::operator()(const nsID & {...}, void * * 0x0012fab8) line 39 + 22 bytes nsCOMPtr<nsIXPConnect>::assign_from_helper(const nsCOMPtr_helper & {...}, const nsID & {...}) line 768 + 18 bytes nsCOMPtr<nsIXPConnect>::nsCOMPtr<nsIXPConnect>(const nsCOMPtr_helper & {...}) line 497 nsJSContext::~nsJSContext() line 179 + 31 bytes nsJSContext::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsJSContext::Release(nsJSContext * const 0x026ff960) line 186 + 134 bytes nsWebShell::~nsWebShell() line 687 + 18 bytes nsWebShell::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsWebShell::Release(nsWebShell * const 0x023c64b0) line 764 + 137 bytes nsWebShellWindow::Close(nsWebShellWindow * const 0x023c67d0) line 435 + 18 bytes nsAppShellService::~nsAppShellService() line 163 nsAppShellService::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsAppShellService::Release(nsAppShellService * const 0x01023560) line 176 + 134 bytes DeleteEntry(nsHashKey * 0x01023460, void * 0x01023520, void * 0x00000000) line 213 + 18 bytes _hashEnumerateRemove(PLHashEntry * 0x01023420, int 56, void * 0x0012fc54) line 227 + 26 bytes PL_HashTableEnumerateEntries(PLHashTable * 0x01004980, int (PLHashEntry *, int, void *)* 0x1001bab0 _hashEnumerateRemove(PLHashEntry *, int, void *), void * 0x0012fc54) line 368 + 15 bytes nsHashtable::Reset(int (nsHashKey *, void *, void *)* 0x100469b0 DeleteEntry(nsHashKey *, void *, void *), void * 0x00000000) line 243 + 20 bytes nsObjectHashtable::Reset() line 344 nsObjectHashtable::~nsObjectHashtable() line 310 nsObjectHashtable::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsServiceManagerImpl::~nsServiceManagerImpl() line 240 + 31 bytes nsServiceManagerImpl::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsServiceManagerImpl::Release(nsServiceManagerImpl * const 0x01004a20) line 249 + 132 bytes nsVCardFactory::~nsVCardFactory() line 83 + 27 bytes nsVCardFactory::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsVCardFactory::Release(nsVCardFactory * const 0x03fea200) line 111 + 131 bytes nsCOMPtr<nsIFactory>::assign_assuming_AddRef(nsIFactory * 0x00000000) line 416 nsCOMPtr<nsIFactory>::assign_with_AddRef(nsISupports * 0x00000000) line 761 nsCOMPtr<nsIFactory>::operator=(nsIFactory * 0x00000000) line 516 nsFactoryEntry::~nsFactoryEntry() line 160 nsFactoryEntry::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsFactoryEntry_Destroy(nsHashKey * 0x010204e0, void * 0x0103b2d0, void * 0x00000000) line 180 + 28 bytes _hashEnumerateRemove(PLHashEntry * 0x010204a0, int 144, void * 0x0012fdc8) line 227 + 26 bytes PL_HashTableEnumerateEntries(PLHashTable * 0x01004590, int (PLHashEntry *, int, void *)* 0x1001bab0 _hashEnumerateRemove(PLHashEntry *, int, void *), void * 0x0012fdc8) line 368 + 15 bytes nsHashtable::Reset(int (nsHashKey *, void *, void *)* 0x10040cf0 nsFactoryEntry_Destroy(nsHashKey *, void *, void *), void * 0x00000000) line 243 + 20 bytes nsObjectHashtable::Reset() line 344 nsObjectHashtable::~nsObjectHashtable() line 310 nsObjectHashtable::`scalar deleting destructor'(unsigned int 1) + 15 bytes nsComponentManagerImpl::Shutdown() line 272 + 31 bytes NS_ShutdownXPCOM(nsIServiceManager * 0x00000000) line 545 + 11 bytes main(int 1, char * * 0x01004e00) line 713 + 8 bytes mainCRTStartup() line 338 + 17 bytes KERNEL32! 77f1ba06()
Reporter | ||
Comment 11•25 years ago
|
||
mGlobalServiceManager *will* be garbage... It is only cleared in nsServiceManager::ShutdownServiceManager() which is *never* called! So, when the service manager finally goes away, this *global* pointer is still non-null.
Assignee | ||
Comment 12•25 years ago
|
||
Rick, I was counting on NS_RELEASE2() to set it 0. #define NS_RELEASE2(_ptr,_rv) \ PR_BEGIN_MACRO \ _rv = NS_LOG_RELEASE_CALL((_ptr), (_ptr)->Release(),__FILE__,__LINE__); \ if (0 == (_rv)) (_ptr) = 0; \ PR_END_MACRO If the release returned an error, then there is a case where this pointer would have been garbage. Is that what you were refering to.
Comment 13•25 years ago
|
||
Looks like ShutdownGlobalServiceManager is doing about the same thing as NS_RELEASE2, but for some reason mGlobalServiceManager is public (!) and that's why it's accessible from NS_ShutdownXPCOM. Ideally, ShutdownGlobalServiceManager would be used instead. The real problem in the stack traces from Putterman is that the destruction of some of the services are indirectly causing the service manager to get recreated. It looks like the code in nsServiceManagerImpl::~nsServiceManagerImpl should be pulled out into a Shutdown/Cleanup/Close method and called explicitly before the service manager goes away. Or maybe the nsCharsetMenu::Done,d nsCharsetMenu::Done and nsJSContext::~nsJSContext that want the service manager should be changed (somehow) to not require it. ...I'm sure I remember fixing this exact problem once for rdf -- maybe the change got lost.
Assignee | ||
Comment 14•25 years ago
|
||
Me too. I remember fixes for similar reinit happening many times. I think we fixed a lot of the access to these via the nsIServiceManager object as opposed to the global. Now the module conversion caused more of the static object to get accessed. I was thinking of adding a state variable and handling this. {NOT_INIT, INIT, SHUTDOWN_HAPPENING, SHUTDOWN_DONE} and GetGlobalServiceManager() will obey this. And the caller might have to be fixed too.
Assignee | ||
Comment 15•25 years ago
|
||
Putternam, Can someone explain how I can reproduce this.
Comment 16•25 years ago
|
||
Comment 17•25 years ago
|
||
this message caused the problem for me every time. I just had to display it and then when I shut down I would crash. You could just add this to your mailbox. I just realized it would probably be easier for me to send you the message, so I will do that.
Comment 18•25 years ago
|
||
Is there a way to remove an attachment? I just realized what I attached.
Reporter | ||
Comment 19•25 years ago
|
||
hey dp, If you look closely at the NS_RELEASE2(...) macro it *only* zeros the pointer if the refcount goes to 0. The macro is a bit hard to read, but basically it says: rv = ptr->Release(); if (rv == 0) ptr = nsnull; Remember Release() does *not* return an error code, but the new refcount of the component... -- rick
Assignee | ||
Updated•25 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 25 years ago → 25 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 20•25 years ago
|
||
I fixed vcard to not hold servicemanager. Also, changed XPCOMShutdown to use nsServiceManager::ShutdownGlobalServiceManager()
You need to log in
before you can comment on or make changes to this bug.
Description
•