Closed Bug 809896 Opened 12 years ago Closed 12 years ago

AddonListener threw exception when calling onUninstalled: TypeError: can't access dead object

Categories

(Firefox :: Untriaged, defect)

17 Branch
x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: dbaldwin, Unassigned)

References

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11

Steps to reproduce:

Hi,

We've been testing our add-on in FF17 Beta and have run into a problem with capturing the uninstall event. This has worked fine in previous versions of FF, but no longer does.  Our add-on listener gets added in the following way:

var listener = {  
  onUninstalled: function(addon) {
    if(addon.id == "info@priceblink.com") {
      // Do cleanup here
    }
  }
}

try {
  var AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm").AddonManager;
  AddonManager.addAddonListener(listener);
} catch (ex) {console.log("exception: " + ex);}

Under normal circumstances this event is captured when the user removes our add-on and closes the add-on manager.

Thanks.




Actual results:

When the add-on manager is closed there's a warning that gets thrown:

Timestamp: 11/7/12 4:01:27 PM
Warning: WARN addons.manager: AddonListener threw exception when calling onUninstalling: TypeError: can't access dead object
Source File: resource://gre/modules/AddonManager.jsm
Line: 1180

So the onUninstalled event is never called.


Expected results:

The onUninstalled event should be called so that we can run our cleanup routines.
Looks like an issue with Huey's fix. CC'ing Kyle.
Whiteboard: [MemShrink]
Whiteboard: [MemShrink]
Where is this listener code running?  We should only be cutting references from chrome code to content code, but content code can't Cu.import the Addons Manager ...
Flags: needinfo?(dbaldwin)
Blocks: hueyfix
(In reply to Dennis Baldwin from comment #0)
> We've been testing our add-on in FF17 Beta and have run into a problem with
> capturing the uninstall event. This has worked fine in previous versions of
> FF, but no longer does.  Our add-on listener gets added in the following way:
> 
> var listener = {  
>   onUninstalled: function(addon) {
>     if(addon.id == "info@priceblink.com") {
>       // Do cleanup here
>     }
>   }
> }
> 
> try {
>   var AddonManager =
> Cu.import("resource://gre/modules/AddonManager.jsm").AddonManager;
>   AddonManager.addAddonListener(listener);
> } catch (ex) {console.log("exception: " + ex);}

Where does this code execute?
The onUninstalled listener shouldn't be called until after your add-on's modules have been destroyed, and are thus inaccessible. The nukeSandbox method that cuts the wrappers for sandbox compartments is only available as of 17, so prior to that the code would continue to function, though it shouldn't have.

I'm not entirely sure why your modules are being destroyed before onUninstalling is called, so someone from the SDK team might want to look into that, but regardless you should be using one of the SDK methods for catching uninstall events for your add-on:

https://addons.mozilla.org/developers/docs/sdk/latest/dev-guide/tutorials/load-and-unload.html
https://addons.mozilla.org/developers/docs/sdk/latest/packages/api-utils/unload.html
Hm. Mid-air collision.
Status: UNCONFIRMED → RESOLVED
Closed: 12 years ago
Resolution: --- → INCOMPLETE
Incidentally (and sorry for the bugspam), didn't I warn you once about adding those listeners and never removing them at shutdown? The AddonManager will continue attempt (and fail) to call the methods on your listener even after your add-on has been disabled or upgraded or uninstalled, and before the sandbox nuking code, it would have continued to hold live references to your module compartment, and therefore leak references to most of your add-on.

Mossop: In answer to your question: https://mxr.mozilla.org/addons/source/61771/resources/priceblink/lib/main.js#325
Flags: needinfo?(dbaldwin)
Resolution: INCOMPLETE → INVALID
Kris, thanks for the info. Will make sure to consider this with our next update.

So what I think I'm reading is that this will no longer be possible. While I'm using the add-on SDK I intentionally stayed away from using the unload listener due to this note:

"But note that due to bug 627432, your onUnload listener will never be called with uninstall: it will only be called with disable. See in particular comment 12 on that bug."
I see. That's an interesting problem. The best solution I can think of on your part is to Cu.import a JSM when your add-on is disabled (i.e., when that's the shutdown reason), and from there register an add-on listener that will run cleanup code on onUninstalled, and unregister itself on onEnabled or onUninstalling (or any other relevant callback), and then unload the module. It's certainly not ideal, but it may be your best recourse.
Depends on: 620541
You need to log in before you can comment on or make changes to this bug.