Closed Bug 203774 Opened 21 years ago Closed 21 years ago

Fix crashes from accessibility rewrite

Categories

(Core :: Disability Access APIs, defect)

x86
Windows 2000
defect
Not set
critical

Tracking

()

RESOLVED FIXED

People

(Reporter: aaronlev, Assigned: aaronlev)

References

Details

(Keywords: crash)

Attachments

(1 file, 1 obsolete file)

The accessibility rearchitecturing caused some new crashes. People who have rare
utilities such as the iFeel mouse are experiencing some of them.

This is a set of fixes designed to fix all of the problems I see in recent
talkback reports.
Flags: blocking1.4b?
1. Don't allow accessible tree to be walked from dead node
2. Don't allow dead accessibles to be retrieved for IAccessible getters
3. Check for dead nodes in nsAccessible methods
4. Fix select accessible crashes resulting from late addref in getter
5. Create doc accessible on demand if necessary, when initializing a new
accessible in that document, so the new accessible can be cached
6. Check for null scroll watch timer in scroll watch callback 
7. Fix missing null check in nsAccessNode::GetComputedStyleDeclaration
Attachment #122000 - Flags: review?(kyle.yuan)
Comment on attachment 122000 [details] [diff] [review]
Fix crashes from talkback reports and by looking at code

r=kyle
Attachment #122000 - Flags: review?(kyle.yuan) → review+
Attachment #122000 - Flags: superreview?(alecf)
before I review this, please answer peterv (and now myself) as to whether bug
149654 recieved approval. There is no evidence in the bug itself and if it
caused these crashes then drivers needs to decide if this bug will land or the
other bug will be backed out.
No one approved bug 149654, during my move to Germany I didn't realize the tree
had changed status.

Bug 149654 did not cause these crashes, those were caused by the accessibility
rewrite in general. Bug 149654 actually fixes some crashes, because it ensures
we shutdown all accessibles, even those that get added in dynamic pages.
Comment on attachment 122000 [details] [diff] [review]
Fix crashes from talkback reports and by looking at code

+  if (!docAccessible) {
+    // No doc accessible yet for this node's document. 
+    // There was probably an accessible event fired before the 
+    // current document was finished loading.
+    // Create a doc accessible so we can cache this node

it sounds like we have code for doing this elsewhere.. (like, after the doc
finishes loading) is this a common pattern that can/should be consolidated into
a helper function?
+	 nsCOMPtr<nsIAccessibilityService> accService = 
+	   do_GetService("@mozilla.org/accessibilityService;1");
+	 NS_ASSERTION(accService, "No accessibility service");
+	 nsCOMPtr<nsIAccessible> accessible;

if this is fatal, and there is a possibility of the service not being there,
should we handle this with a if (!accService)...?

stuff like this:
   if (mNextSibling) {
-    *aAccNextSibling = mNextSibling;
+    NS_ADDREF(*aAccNextSibling = mNextSibling);
   }
   else {
     *aAccNextSibling = new nsHTMLComboboxListAccessible(mParent, mDOMNode,
mWeakShell);
     if (!*aAccNextSibling)
       return NS_ERROR_OUT_OF_MEMORY;
+    NS_ADDREF(*aAccNextSibling);
     nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(*aAccNextSibling));
     accessNode->Init();
   }
-  NS_ADDREF(*aAccNextSibling);
   return NS_OK;


it seems wrong to be distributing the addref throughout the code - can't you
just NS_IF_ADDREF at the end? setting up vtable calls is potentially expensive,
I don't see any need to duplicate calls in this case... (make sure the *retval
is null in each case of course)

(you have this in a whole bunch of methods)

+#ifdef DEBUG
+  printf("\nATTENTION: New doc accessible for weak shell %x\n", mWeakShell);
+#endif

DEBUG_aaronl instead
[My comments in brackets]

(From update of attachment 122000 [details] [diff] [review])
+  if (!docAccessible) {
+    // No doc accessible yet for this node's document. 
+    // There was probably an accessible event fired before the 
+    // current document was finished loading.
+    // Create a doc accessible so we can cache this node
[I've changed this comment to be more accurate, "before the current document has
been asked for by the assistive technology"]

it sounds like we have code for doing this elsewhere.. (like, after the doc
finishes loading) is this a common pattern that can/should be consolidated into
a helper function?
[That won't save any code, because the other place where it happens all of the
necessary variables already happen to exist. I can turn it into a helper for
readability anyway, if that's preferred]

+	 nsCOMPtr<nsIAccessibilityService> accService = 
+	   do_GetService("@mozilla.org/accessibilityService;1");
+	 NS_ASSERTION(accService, "No accessibility service");
+	 nsCOMPtr<nsIAccessible> accessible;

if this is fatal, and there is a possibility of the service not being there,
should we handle this with a if (!accService)...?
[fixed in new patch]

stuff like this:
   if (mNextSibling) {
-    *aAccNextSibling = mNextSibling;
+    NS_ADDREF(*aAccNextSibling = mNextSibling);
   }
   else {
     *aAccNextSibling = new nsHTMLComboboxListAccessible(mParent, mDOMNode,
mWeakShell);
     if (!*aAccNextSibling)
       return NS_ERROR_OUT_OF_MEMORY;
+    NS_ADDREF(*aAccNextSibling);
     nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(*aAccNextSibling));
     accessNode->Init();
   }
-  NS_ADDREF(*aAccNextSibling);
   return NS_OK;


it seems wrong to be distributing the addref throughout the code - can't you
just NS_IF_ADDREF at the end? setting up vtable calls is potentially expensive,
I don't see any need to duplicate calls in this case... (make sure the *retval
is null in each case of course)
(you have this in a whole bunch of methods)
[Splitting this into 2 NS_ADDREFs actually fixes a crash. The reason I need this
in both places is that since it's not addref'd, and there is an
nsCOMPtr<nsIAccessNode> variable there, it gets released when the block ends,
but before my NS_IF_ADDREF, causing the return argument for the getter to be
wrecked. Alternatively, I could use an NS_STATIC_CAST(nsIAccessNode*, blah) and
avoid the nsCOMptr. That would allow me to have just 1 NS_IF_ADDREF at the end
of each method].

+#ifdef DEBUG
+  printf("\nATTENTION: New doc accessible for weak shell %x\n", mWeakShell);
+#endif

DEBUG_aaronl instead
[fixed]
*** Bug 203843 has been marked as a duplicate of this bug. ***
Attachment #122000 - Attachment is obsolete: true
Comment on attachment 122126 [details] [diff] [review]
With changes after IM'ing with alecf

Carrying Kyle's r=
Attachment #122126 - Flags: superreview?
Attachment #122126 - Flags: review+
Attachment #122126 - Flags: superreview? → superreview?(alecf)
Attachment #122000 - Flags: superreview?(alecf)
Comment on attachment 122126 [details] [diff] [review]
With changes after IM'ing with alecf

sr=alecf
Attachment #122126 - Flags: superreview?(alecf) → superreview+
Attachment #122126 - Flags: approval1.4b?
Blocks: 203843
Comment on attachment 122126 [details] [diff] [review]
With changes after IM'ing with alecf

a=sspitzer, since we are talking about crash fixes.
Attachment #122126 - Flags: approval1.4b? → approval1.4b+
checked in
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Flags: blocking1.4b?
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: