Bug 1205476 - crash in mozilla::a11y::DocAccessible::ProcessInvalidationList(), r=smaug
authorAlexander Surkov <surkov.alexander@gmail.com>
Fri, 18 Sep 2015 08:52:46 -0400
changeset 295838 b6db43f49b67b732235d58977fe4b836e47e20a0
parent 295837 1ef643c92a6be6a06ff23cf2c62b01b7cf8e7503
child 295839 b2956e60f8255e24a0f5686f19d6cefae382abf4
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1205476
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1205476 - crash in mozilla::a11y::DocAccessible::ProcessInvalidationList(), r=smaug
accessible/generic/DocAccessible.cpp
accessible/generic/DocAccessible.h
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -111,26 +111,34 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(DocAccess
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DocAccessible, Accessible)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotificationController)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVirtualCursor)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildDocuments)
   tmp->mDependentIDsHash.EnumerateRead(CycleCollectorTraverseDepIDsEntry, &cb);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAccessibleCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnchorJumpElm)
+  for (uint32_t i = 0; i < tmp->mARIAOwnsInvalidationList.Length(); ++i) {
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mARIAOwnsInvalidationList[i].mOwner)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mARIAOwnsInvalidationList[i].mChild)
+  }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DocAccessible, Accessible)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mNotificationController)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mVirtualCursor)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildDocuments)
   tmp->mDependentIDsHash.Clear();
   tmp->mNodeToAccessibleMap.Clear();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAccessibleCache)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnchorJumpElm)
+  for (uint32_t i = 0; i < tmp->mARIAOwnsInvalidationList.Length(); ++i) {
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(mARIAOwnsInvalidationList[i].mOwner)
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(mARIAOwnsInvalidationList[i].mChild)
+  }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DocAccessible)
   NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIAccessiblePivotObserver)
@@ -1335,16 +1343,20 @@ DocAccessible::ProcessInvalidationList()
     }
   }
 
   mInvalidationList.Clear();
 
   // Alter the tree according to aria-owns (seize the trees).
   for (uint32_t idx = 0; idx < mARIAOwnsInvalidationList.Length(); idx++) {
     Accessible* owner = mARIAOwnsInvalidationList[idx].mOwner;
+    if (owner->IsDefunct()) { // eventually died until we've got here
+      continue;
+    }
+
     Accessible* child = GetAccessible(mARIAOwnsInvalidationList[idx].mChild);
     if (!child) {
       continue;
     }
 
     // XXX: update context flags
     {
       Accessible* oldParent = child->Parent();
--- a/accessible/generic/DocAccessible.h
+++ b/accessible/generic/DocAccessible.h
@@ -676,18 +676,18 @@ protected:
   struct ARIAOwnsPair {
     ARIAOwnsPair(Accessible* aOwner, nsIContent* aChild) :
       mOwner(aOwner), mChild(aChild) { }
     ARIAOwnsPair(const ARIAOwnsPair& aPair) :
       mOwner(aPair.mOwner), mChild(aPair.mChild) { }
     ARIAOwnsPair& operator =(const ARIAOwnsPair& aPair)
       { mOwner = aPair.mOwner; mChild = aPair.mChild; return *this; }
 
-    Accessible* mOwner;
-    nsIContent* mChild;
+    nsRefPtr<Accessible> mOwner;
+    nsCOMPtr<nsIContent> mChild;
   };
   nsTArray<ARIAOwnsPair> mARIAOwnsInvalidationList;
 
   /**
    * Used to process notification from core and accessible events.
    */
   nsRefPtr<NotificationController> mNotificationController;
   friend class EventQueue;