Bug 282660 Crash [@ jsds_NotifyPendingDeadScripts] ds->script is null r=jst a=beltzner
authortimeless@mozdev.org
Wed, 05 Mar 2008 13:10:01 -0800
changeset 12615 805fa26e63a8a10a94a002130a2aa43b454501af
parent 12614 c8b948020a91e9367f73fd6370b04928d6749696
child 12616 1525c19f1455385437b03edb9b70fbbb1822a237
push idunknown
push userunknown
push dateunknown
reviewersjst, beltzner
bugs282660
milestone1.9b5pre
Bug 282660 Crash [@ jsds_NotifyPendingDeadScripts] ds->script is null r=jst a=beltzner
js/jsd/jsd_xpc.cpp
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -471,64 +471,68 @@ jsds_NotifyPendingDeadScripts (JSContext
      * If there's no gJsds, then we can't do anything.
      */
     if (!gJsds)
         return;
 
     nsCOMPtr<jsdIScriptHook> hook = 0;   
     gJsds->GetScriptHook (getter_AddRefs(hook));
 
-    DeadScript *ds;
 #ifdef CAUTIOUS_SCRIPTHOOK
     JSRuntime *rt = JS_GetRuntime(cx);
 #endif
     gJsds->Pause(nsnull);
-    while (gDeadScripts) {
-        ds = gDeadScripts;
-        
+    DeadScript *deadScripts = gDeadScripts;
+    gDeadScripts = nsnull;
+    while (deadScripts) {
+        DeadScript *ds = deadScripts;
+        /* get next deleted script */
+        deadScripts = reinterpret_cast<DeadScript *>
+                                       (PR_NEXT_LINK(&ds->links));
+        if (deadScripts == ds)
+            deadScripts = nsnull;
+
         if (hook)
         {
             /* tell the user this script has been destroyed */
 #ifdef CAUTIOUS_SCRIPTHOOK
             JS_UNKEEP_ATOMS(rt);
 #endif
             hook->OnScriptDestroyed (ds->script);
 #ifdef CAUTIOUS_SCRIPTHOOK
             JS_KEEP_ATOMS(rt);
 #endif
         }
-        /* get next deleted script */
-        gDeadScripts = reinterpret_cast<DeadScript *>
-                                       (PR_NEXT_LINK(&ds->links));
-        if (gDeadScripts == ds) {
-            /* last script in the list */
-            gDeadScripts = nsnull;
-        }
-        
-        /* take ourselves out of the circular list */
+
+        /* take it out of the circular list */
         PR_REMOVE_LINK(&ds->links);
+
         /* addref came from the FromPtr call in jsds_ScriptHookProc */
         NS_RELEASE(ds->script);
         /* free the struct! */
         PR_Free(ds);
     }
 
     gJsds->UnPause(nsnull);
 }
 
 JS_STATIC_DLL_CALLBACK (JSBool)
 jsds_GCCallbackProc (JSContext *cx, JSGCStatus status)
 {
-    gGCStatus = status;
 #ifdef DEBUG_verbose
     printf ("new gc status is %i\n", status);
 #endif
-    if (status == JSGC_END && gDeadScripts)
-        jsds_NotifyPendingDeadScripts (cx);
-    
+    if (status == JSGC_END) {
+        /* just to guard against reentering. */
+        gGCStatus = JSGC_BEGIN;
+        while (gDeadScripts)
+            jsds_NotifyPendingDeadScripts (cx);
+    }
+
+    gGCStatus = status;
     if (gLastGCProc)
         return gLastGCProc (cx, status);
     
     return JS_TRUE;
 }
 
 JS_STATIC_DLL_CALLBACK (uintN)
 jsds_ErrorHookProc (JSDContext *jsdc, JSContext *cx, const char *message,