Closed Bug 59526 Opened 24 years ago Closed 24 years ago

Webclient crashes on exit.

Categories

(Core Graveyard :: Embedding: APIs, defect, P3)

x86
Windows NT
defect

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: edburns, Assigned: jud)

References

Details

(Keywords: topembed+)

Hello,

Using Mozilla RTM Branch build from 11/02/00 and Webclient RTM branch from 
11/08/00.

At app exit, we are calling NS_TermEmbedding(), and it returs successfully, 
however, I get an access violation crash in nsThread::Exit().  It appears a 
thread instance's exit is getting called twice, as evidenced by the debug 
output:

[...]
PREF_Cleanup()
267[91d5890]: nsIThread 91d5a00 end run 91d5bb0
267[91d5890]: nsIThread 91d5a00 exited
0[91d4120]: nsIThread 91d5a00 start join
0[91d4120]: nsIThread 91d5a00 end join
0[91d4120]: nsIThread 91d5a00 destroyed
0[91d4120]: nsIThread 91d5f20 exited
0[91d4120]: nsIThread 91d5f20 destroyed
0[91d4120]: ###!!! ASSERTION: null atom hashtable: 'nsnull != gAtomHashTable', 
file E:\Projects\mozilla\xpcom\ds\nsAtomTable.cpp, line 76
###!!! ASSERTION: null atom hashtable: 'nsnull != gAtomHashTable', file 
E:\Projects\mozilla\xpcom\ds\nsAtomTable.cpp, line 76
WEBSHELL- = 0
0[91d4120]: nsIThread 91d5f20 exited

Note that nsIThread 91d5f20 exits twice.  Why is this?

Here's the complete output:

E:\Projects\mozilla\java\webclient\src_moz>.\runem

E:\Projects\mozilla\java\webclient\src_moz>perl.exe ..\src_share\runem.pl 
org.mozilla.webclient.test.EmbeddedMozilla ..\..\..
C:\jdk1.3.0_01\bin\java -Djava.library.path=%MOZILLA_HOME%\dist\win32_d.obj\bin
-classpath C:\jdk1.3.0_01\lib\tools.jar;C:\jdk1.3.0_01
\lib\rt.jar;;..\..\..\dist\classes org.mozilla.webclient.test.EmbeddedMozilla %
MOZILLA_HOME%\dist\win32_d.obj\bin

E:\Projects\mozilla\java\webclient\src_moz>Creating new EmbeddedMozilla window
constructed with binDir: E:\Projects\mozilla\dist\win32_d.obj\bin url: 
file:///E|/Projects/tmp/5105.html
in BrowserControlCanvas setBounds: x = 0 y = 0 w = 640 h = 480
native library does implement webclient.WindowControl
Can't setBounds(java.awt.Rectangle[x=0,y=0,width=639,height=479]) null
0[91d4120]: nsIThread 91d5a00 created
267[91d5890]: nsIThread 91d5a00 start run 91d5bb0
Type Manifest File: E:\Projects\mozilla\dist\win32_d.obj\bin\components\xpti.dat

nsNativeComponentLoader: autoregistering begins.
nsNativeComponentLoader: autoregistering succeeded
nNCL: registering deferred (0)
0[91d4120]: nsIThread 929e190 created
0[91d4120]: nsIThread 929a3b0 created
134[929aeb0]: nsIThread 929e190 start run 929e734
184[929a240]: nsIThread 929a3b0 start run 929a754
0[91d4120]: WARNING: chrome: failed to get base url for 
chrome://necko/locale/necko.properties -- using wacky default, file 
E:\Projects\mozilla\rdf\chrome\src\nsChromeRegistry.cpp, line 507
WARNING: chrome: failed to get base url for 
chrome://necko/locale/necko.properties -- using wacky default, file 
E:\Projects\mozilla\rdf\chrome\src\nsChromeRegistry.cpp, line 507
0[91d4120]: InitMozillaStuff(91d4330): Create the Event Queue for the UI thread.
..
InitMozillaStuff(91d4330): Create the action queue
Init the baseWindow
Create the BaseWindow...
WEBSHELL+ = 1
Creation Done.....
Show the webBrowser
0[91d4120]: InitMozillaStuff(91d4330): enter event loop
in BrowserControlCanvas setBounds: x = 4 y = 88 w = 632 h = 384
native library does implement webclient.Navigation
native library does implement webclient.CurrentPage
in BrowserControlCanvas setBounds: x = 4 y = 88 w = 632 h = 384
native library does implement webclient.History
native library does implement webclient.EventRegistration
native library does implement webclient.Bookmarks
debug: edburns: got Bookmarks instance
0[91d4120]: ###!!! ASSERTION: HTTP cannot send practical requests without this 
much: '(!mAppName.IsEmpty() || !mAppVersion.IsEmpty() || !mAppPlatform.IsEmpty()
|| !mAppSecurity.IsEmpty() || !mAppOSCPU.IsEmpty())', file 
E:\Projects\mozilla\netwerk\protocol\http\src\nsHTTPHandler.cpp, line 1288
###!!! ASSERTION: HTTP cannot send practical requests without this much: '(!
mAppName.IsEmpty() || !mAppVersion.IsEmpty() || !mAppPlatform.IsEmpty() || !
mAppSecurity.IsEmpty() || !mAppOSCPU.IsEmpty())', file 
E:\Projects\mozilla\netwerk\protocol\http\src\nsHTTPHandler.cpp, line 1288
CSSLoaderImpl::LoadAgentSheet: Load of 
URL 'file:///C:/WINNT/PROFILES/ADMINISTRATOR/APPLICATION%
20DATA/Mozilla/Users50/default/chrome/userChrome.css' failed.  Error code: 18
CSSLoaderImpl::LoadAgentSheet: Load of 
URL 'file:///C:/WINNT/PROFILES/ADMINISTRATOR/APPLICATION%
20DATA/Mozilla/Users50/default/chrome/userContent.css' failed.
Error code: 18
Start reading in bookmarks.html
Finished reading in bookmarks.html  (70000 microseconds)
0[91d2380]: Native URL = "file:///E|/Projects/tmp/5105.html"
debug: edburns: Currently Viewing: file:///E|/Projects/tmp/5105.html
0[91d4120]: nsIThread a32c670 created
0[91d4120]: nsIThreadPool adding new thread a32c670 (1 total)
274[a32c500]: nsIThread a32c670 start run a32c6c0
0[91d4120]: nsIThreadPool thread 91d5f20 dispatched a32b2c4 status 0
274[a32c500]: nsIThreadPool thread a32c670 got request a32b2c4
274[a32c500]: nsIThreadPool thread a32c670 running a32b2c4
274[a32c500]: nsIThreadPool thread a32c670 completed a32b2c4 status=0
274[a32c500]: nsIThreadPool thread a32c670 waiting (1 threads in pool)
plugins at: E:\Projects\mozilla\dist\win32_d.obj\bin\plugins
Setting Preference Style Rules:
CreatePrefStyleSheet completed: error=0
 - Creating rules for link and visited colors
 - Creating rules for enabling link underlines
Preference Style Rules set: error=0
Enabling Quirk StyleSheet
Note: verifyreflow is disabled
Enabling Quirk StyleSheet
Note: styleverifytree is disabled
Note: frameverifytree is disabled
0[91d4120]: nsIThreadPool thread 91d5f20 dispatched ab9c524 status 0
0[91d4120]: nsIThread ab9d560 created
0[91d4120]: nsIThreadPool adding new thread ab9d560 (2 total)
269[ab9d3f0]: nsIThread ab9d560 start run ab9d5b0
0[91d4120]: nsIThreadPool thread 91d5f20 dispatched ab9dc64 status 0
274[a32c500]: nsIThreadPool thread a32c670 got request ab9c524
274[a32c500]: nsIThreadPool thread a32c670 running ab9c524
274[a32c500]: nsIThreadPool thread a32c670 completed ab9c524 status=0
269[ab9d3f0]: nsIThreadPool thread ab9d560 got request ab9dc64
269[ab9d3f0]: nsIThreadPool thread ab9d560 running ab9dc64
269[ab9d3f0]: nsIThreadPool thread ab9d560 completed ab9dc64 status=0
0[91d4120]: nsIThreadPool thread 91d5f20 dispatched ab9d134 status 0
274[a32c500]: nsIThreadPool thread a32c670 got request ab9d134
274[a32c500]: nsIThreadPool thread a32c670 running ab9d134
274[a32c500]: nsIThreadPool thread a32c670 completed ab9d134 status=0
269[ab9d3f0]: nsIThreadPool thread ab9d560 waiting (2 threads in pool)
0[91d4120]: nsIThreadPool thread 91d5f20 dispatched ab63314 status 0
274[a32c500]: nsIThreadPool thread a32c670 got request ab63314
274[a32c500]: nsIThreadPool thread a32c670 running ab63314
274[a32c500]: nsIThreadPool thread a32c670 completed ab63314 status=0
269[ab9d3f0]: nsIThreadPool thread ab9d560 waiting (2 threads in pool)
274[a32c500]: nsIThreadPool thread a32c670 waiting (2 threads in pool)
has multiple monitor apis is 0
0[91d4120]: nsIThreadPool thread 91d5f20 dispatched ab710a4 status 0
269[ab9d3f0]: nsIThreadPool thread ab9d560 got request ab710a4
269[ab9d3f0]: nsIThreadPool thread ab9d560 running ab710a4
269[ab9d3f0]: nsIThreadPool thread ab9d560 completed ab710a4 status=0
269[ab9d3f0]: nsIThreadPool thread ab9d560 waiting (2 threads in pool)
Got windowClosing
destroying the BrowserControl
ImplObjectNative.delete()
ImplObjectNative.delete()
ImplObjectNative.delete()
ImplObjectNative.delete()
PrefStyleSheet removed
killing plugin host
CanUnload_enumerate: skipping native
PREF_Cleanup()
267[91d5890]: nsIThread 91d5a00 end run 91d5bb0
267[91d5890]: nsIThread 91d5a00 exited
0[91d4120]: nsIThread 91d5a00 start join
0[91d4120]: nsIThread 91d5a00 end join
0[91d4120]: nsIThread 91d5a00 destroyed
0[91d4120]: nsIThread 91d5f20 exited
0[91d4120]: nsIThread 91d5f20 destroyed
0[91d4120]: ###!!! ASSERTION: null atom hashtable: 'nsnull != gAtomHashTable', f
ile E:\Projects\mozilla\xpcom\ds\nsAtomTable.cpp, line 76
###!!! ASSERTION: null atom hashtable: 'nsnull != gAtomHashTable', file E:\Proje
cts\mozilla\xpcom\ds\nsAtomTable.cpp, line 76
WEBSHELL- = 0
0[91d4120]: nsIThread 91d5f20 exited

E:\Projects\mozilla\java\webclient\src_moz>
It looks like the first time this thread instance's Exit is called is
here:

nsThread::Exit(void * 0x091d4030) line 103
nsThread::Shutdown() line 339 + 11 bytes
NS_ShutdownXPCOM(nsIServiceManager * 0x00000000) line 676
NS_TermEmbedding() line 203 + 13 bytes

Like this:

void 
nsThread::Shutdown()
{
    if (gMainThread) {
        // XXX nspr doesn't seem to be calling the main thread's destructor
        // callback, so let's help it out:
        nsThread::Exit(NS_STATIC_CAST(nsThread*, gMainThread));
        nsrefcnt cnt;
        NS_RELEASE2(gMainThread, cnt);
        NS_WARN_IF_FALSE(cnt == 0, "Main thread being held past XPCOM 
shutdown.");
    }
}

gMainThread is 0x091df4030.

The second time gMainThread->Exit() is called is here:

nsThread::Exit(void * 0x091d4030) line 103
_PR_DestroyThreadPrivate(PRThread * 0x091d5eb0) line 244 + 16 bytes
_PR_CleanupThread(PRThread * 0x091d5eb0) line 45 + 9 bytes
_PRI_DetachThread() line 1489 + 9 bytes
DllMain(HINSTANCE__ * 0x30000000, unsigned long 3, void * 0x00000000) line 51
_DllMainCRTStartup(void * 0x30000000, unsigned long 3, void * 0x00000000) line 
273 + 17 bytes
NTDLL! 77f69d4f()
KERNEL32! 77f1cbcc()
MSVCRT! 780020dd()
KERNEL32! 77f04f2c()

Is there any way to prevent this second invocation of Exit()?
nsThread::Exit(void * 0x091d4030) line 103
_PR_DestroyThreadPrivate(PRThread * 0x091d5eb0) line 244 + 16 bytes

I dont understand this - if in _PR_DestroyThreadPrivate, the Thread id is
0x091d5eb0, why is Exit being called on Thread id 0x091d4030. Is it that the
nsThread object is a private ivar of the PRThread object? If so, it seems the
NS_ShutdownXPCOM should be calling _PR_DestroyThreadPrivate instead of
nsThread::Shutdown, since all that ::Shutdown does is call exit and release the
xpcom thread object.
Here is a trivial fix to this problem.  Unfortunately, it has exposed another 
problem, in bookmarks, but I think that problem is unrelated.  

cvs diff -u nsThread.cpp (in directory E:\Projects\mozilla\xpcom\threads)
Index: nsThread.cpp
===================================================================
RCS file: /cvsroot/mozilla/xpcom/threads/nsThread.cpp,v
retrieving revision 1.26
diff -u -r1.26 nsThread.cpp
--- nsThread.cpp	2000/04/21 05:32:59	1.26
+++ nsThread.cpp	2000/11/08 21:49:42
@@ -100,6 +100,9 @@
 nsThread::Exit(void* arg)
 {
     nsThread* self = (nsThread*)arg;
+    if (self->mDead) {
+        return;
+    }
     self->mDead = PR_TRUE;
     PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
            ("nsIThread %p exited\n", self));

*****CVS exited normally with code 1*****

Fix looks good - shouldn't cause any side effects. Maybe you should cc
warren@netscape.com on this bug. He seems to have cvs blame on this file.
Blocks: 59530
Doug, any thoughts?
r=valeski was given.
Could we dig a little deeper into this problem to figure out why we're calling
nsThread::Exit() twice? edburns's code looks reasonable as "bulletproofing", but
I don't want to wallpaper over the real problem.

edburns: I'll give you sr= waterson on your change *if* you add...

  NS_ERROR("attempt to Exit() thread twice");

...before returning. Let's leave this bug open, and assigned to jud or dougt
until we figure out who's calling this routine twice.
Chris, here is where Exit is being called:

The second time gMainThread->Exit() is called is here:

nsThread::Exit(void * 0x091d4030) line 103
_PR_DestroyThreadPrivate(PRThread * 0x091d5eb0) line 244 + 16 bytes
_PR_CleanupThread(PRThread * 0x091d5eb0) line 45 + 9 bytes
_PRI_DetachThread() line 1489 + 9 bytes
DllMain(HINSTANCE__ * 0x30000000, unsigned long 3, void * 0x00000000) line 51
_DllMainCRTStartup(void * 0x30000000, unsigned long 3, void * 0x00000000) line
273 + 17 bytes
NTDLL! 77f69d4f()
KERNEL32! 77f1cbcc()
MSVCRT! 780020dd()
KERNEL32! 77f04f2c()
This checkin got messed up somehow... This is the code currently:

  self->mDead = PR_TRUE;

  if (self->mDead) {
    NS_ERROR("attempt to Exit() thread twice");
    return;
  }

Oops. That PR_TRUE assignment should've been below that if.
(It showed up in the byte-size leak stats, is why I found it).
Checked in the obvious fix.
Fix checked in to trunk.
Status: NEW → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
Updating QA Contact
QA Contact: jrgm → mdunn
Correction: Changing QA contact for the Embed API bugs to David Epstein.
QA Contact: mdunn → depstein
no crash on exit. Code checked into nsThread.cpp
Status: RESOLVED → VERIFIED
Keywords: topembed+
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.