"can't access dead object" from devtools/server/actors/tab.js when reloading extension options page

RESOLVED FIXED in Firefox 59

Status

P3
normal
RESOLVED FIXED
a year ago
a month ago

People

(Reporter: mkaply, Assigned: rickychien)

Tracking

unspecified
Firefox 59

Firefox Tracking Flags

(firefox57 wontfix, firefox59 fixed)

Details

Attachments

(1 attachment)

(Reporter)

Description

a year ago
There does not appear to be a documented way to remove listeners in a WebExtension options page.

As a result, whenever you click reload on the options page, you get:

TypeError: can't access dead object

There needs to be some event when the page goes away so event listeners can be properly removed.

Updated

a year ago
status-firefox57: --- → wontfix
Priority: -- → P3
I'm not sure exactly what type of listeners you're talking about?  Listeners for DOM events added with addEventListener() or listeners for webextension events added with addListener()?  But regardless, an options page is just like any other content page, anything created by scripts on the page gets cleaned up by the browser when the page is unloaded.
However, we should still get to the bottom of the error message you're seeing, I tried reproducing this with various webextensions' option pages and don't see this error, can you provide a specific extension (and any other relevant details) so I can reproduce this?
Flags: needinfo?(mozilla)
(Reporter)

Comment 2

a year ago
Interesting. Looks like the dead object error only happens if the add-ons is loaded via about:debugging and then you hit reload in preferences.

I checked by loading my keyword search from AMO:

https://addons.mozilla.org/en-US/firefox/addon/keyword-search-webextension/

directly from AMO and via about:debugging.

I don't understand why that would make a difference...
Flags: needinfo?(mozilla)
I can reproduce this console error, but its coming from devtools, this line in particular:
http://searchfox.org/mozilla-central/rev/40e8eb46609dcb8780764774ec550afff1eed3a5/devtools/server/actors/tab.js#1647

It's basically the same error as what's described in bug 1391940 even though the STR are completely different.
Component: WebExtensions: General → Developer Tools: Framework
Product: Toolkit → Firefox
Summary: No way to remove listeners in WebExtension options pages (Can't access dead object) → "can't access dead object" from devtools/server/actors/tab.js when reloading extension options page
See also https://bugzilla.mozilla.org/show_bug.cgi?id=1429365#c3
Assignee: nobody → rchien
Status: NEW → ASSIGNED
See https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Errors/Dead_object

We have to use Components.utils.isDeadWrapper(window) to avoid accessing dead object before access them.
Comment hidden (mozreview-request)
Duplicate of this bug: 1391940
Comment on attachment 8941777 [details]
Bug 1409705 - Adding Cu.isDeadWrapper(window) to avoid accessing dead object

https://reviewboard.mozilla.org/r/212026/#review218084

Looks reasonable

R+

Thanks,
Honza
Attachment #8941777 - Flags: review?(odvarko) → review+

Comment 9

a year ago
Pushed by rchien@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/8b29651a367a
Adding Cu.isDeadWrapper(window) to avoid accessing dead object r=Honza

Comment 10

a year ago
mozreview-review
Comment on attachment 8941777 [details]
Bug 1409705 - Adding Cu.isDeadWrapper(window) to avoid accessing dead object

https://reviewboard.mozilla.org/r/212026/#review218108

::: devtools/server/actors/tab.js:1639
(Diff revision 1)
>        this._tabActor._willNavigate(window, newURI, request);
>      }
>      if (isWindow && isStop) {
>        // Don't dispatch "navigate" event just yet when there is a redirect to
>        // about:neterror page.
>        if (request.status != Cr.NS_OK) {

I think the issue is rather here.
request.status is equal to Cr.NS_BINDING_ABORTED when it throws.
When we reload the page or load another, while one is still loading, pending request will be cancelled and status will be set to NS_BINDING_ABORTED.
Here it looks like we should stop doing anything whenever status is set to that value. There is no need to dispatch navigate event as the document will be a dead wrapper anyway.
It is better to not register any DOMContentLoaded. In the current patch we may leak the added listener.
Oh, it sounds promising. And then we can stop dispatching navigate event and gain some perf. I'll file a follow-up soon.
Blocks: 1430117

Comment 12

a year ago
bugherder
https://hg.mozilla.org/mozilla-central/rev/8b29651a367a
Status: ASSIGNED → RESOLVED
Last Resolved: a year ago
status-firefox59: --- → fixed
Resolution: --- → FIXED
Target Milestone: --- → Firefox 59

Updated

7 months ago
Product: Firefox → DevTools

Comment 13

a month ago
I am having this same problem ("can't access dead object" in webconsole.js or other places). I can't find anyplace where I am holding onto a DOM reference, but as a result of this problem I cannot develop my WebExtension code.

All of the postings I can find on this topic are too complicated for me to understand. Is there someone who can look at my code and help me? If not, can there be some clear examples of doing WebExtension code correctly and incorrectly? The only examples I can find do not show anything that I am doing. I am NOT saving window, document, or any other DOM node. I do call functions like browser.contextMenus.onClicked.addListener and browser.runtime.onMessage.addListener . The documentation says to do this, and does not say that any "remove listener" function must be called.

I have been successful in creating an "unload" handler for my background code that is executed, but I don't know what I am supposed to put there to clean up my dead objects, mostly because the debugger does not list them.

I have tried writing very simple code, but as soon as I add one more piece of code it breaks. I have filed reports at Stack Overflow and received no useful replies. Nobody seems to understand the obscure WebExtension rules except people who are remaining silent and unhelpful.

I understand the reasoning that memory leaks need to be prevented, but why not track where the memory was allocated so a clear error message, giving the location in my code where the object was allocated, can be provided?

WebExtensions are very hard to learn because of this poor debugging design. Please, can someone help? The people who really understand this stuff are not helping others to learn proper WebExtensions programming idioms. It doesn't have to have been made so hard to program WebExtensions! Please help.
You need to log in before you can comment on or make changes to this bug.