One of my Manifest V3 addons is not waking up when it should

Thanks for that. I’m also seeing the same set of persistent listeners – I just installed the extension for testing/debugging purposes and ostensibly everything is working as expected right now.

I was testing it at work too and it worked normally, as always.
But this is what I see now:
https://mega.nz/file/ZS50mLwa#MfvThAeoHtmwpS0t_yUkeSNVNVUqq840NiVg3unBieE

1 Like

Very curious, indeed. Thanks for sharing a concrete video of the repro.

Could you run another snippet to get a more readable form of the listener data for us?

function convertNestedMap(m) { const res = {}; for (const [k, v] of m) { res[k] = typeof v?.has === "function" ? convertNestedMap(v) : v; } return res; }

JSON.stringify(convertNestedMap(WebExtensionPolicy.getByID("admin@fastaddons.com_SendTabToDeviceEnhancer").extension.persistentListeners), null, 2)
'{
  "tabs": {
    "onCreated": {
      "[]": {
        "params": [],
        "nextPrimeId": 1,
        "listeners": [
          {
            "primeId": 0
          }
        ]
      }
    },
    "onUpdated": {
      "[null]": {
        "params": [
          null
        ],
        "nextPrimeId": 1,
        "listeners": [
          {
            "primeId": 0
          }
        ]
      }
    }
  }
}'

Interesting. That’s different than what I’m seeing locally when my extension is awake or asleep. I’ve passed this data on to the relevant engineers.

Sorry for the legginess of this process and thank you for the help so far!

1 Like

No problem :slight_smile:, this is actually super exciting for me, even though it’s almost 11PM here :slight_smile:. I plan to stay up at least one more hour.

I just hope it will help find the root cause. In the big picture, it will for sure help me too since I’ll receive less bug reports from my users :slight_smile:.

1 Like

The engineer I was working with so far had to leave, but it sounds like we got some useful data. I’m going to read through some relevant Firefox source and see if there’s any other data that might be useful to collect.

1 Like

OK, great.
I’ll try to keep my Firefox running over the weekend and even next week so feel free to write me if you need to run more experiments!

1 Like

Something unrelated that I noticed:
In background_sttd.js, the browser.windows.onFocusChanged listener gets registered inside the browser.tabs.onUpdated listener.
Doesn’t MV3 require that you register all listeners at the top level of the service worker?

Only if you want the listener to be able to wake up the worker. Otherwise it will work only until the worker is alive, which is more-less enough for the specific use case it handles :slight_smile:.

I’m going to keep poking around FF source for a bit longer, @juraj.masiar, but if you’re still up it’s probably best to call it a night. Thanks again for the help. I’ll be sure to follow up here as soon as I have an update over the next couple of days.

1 Like

OK, thanks for the help!
I’ll go sleep soon so good night and have a nice weekend :slight_smile:.

1 Like

Assuming the issue is still reproducing on your end, I have a pair of follow up questions for you, @juraj.masiar.

  1. Could you run the following snippet in Browser Toolbox and share the result? It should be a short string.
WebExtensionPolicy.getByID("admin@fastaddons.com_SendTabToDeviceEnhancer").extension.backgroundState
  1. Could you share the addonStartup.json.lz4 file from your profile directory with me? You can find the path to your profile directory by visiting about:profiles. I just sent you a message with my address.

Hello,
Yes, my Firefox is still running with addon still broken.

WebExtensionPolicy.getByID("admin@fastaddons.com_SendTabToDeviceEnhancer").extension.backgroundState
"stopped" 

I’m sending you the " addonStartup" now.

Thanks, @juraj.masiar! From what I’ve heard, so far everything looks pretty normal, so unfortunately we’re still digging. I’ll let you know if the team has any more questions for you.

I’m almost sure now this affects more addons.

I have another addon that I’ve migrated to non-persistent background script and since than, I’ve noticed a strange bug.

Sometimes, when I update storage (by marking a message as “read”), the badge number doesn’t update (it shows number of un-read messages).

The badge is updated in the background script and there is a event handler for it:

browser.storage.local.onChanged.addListener(updateBadge);

BUT the badge will update the moment I open popup window (I suspect this wakes up the background script). And then the issue doesn’t happen again, even when I wait for the background script to stop again.

I would like to test this with this broken addon - to see, if waking it up, even temporarily, fixes it.

Is there a way to wake up the background script of this addon? It doens’t have a popup and inspecting background script when it’s unloaded doesn’t wake it up.

@dotproto Good news!
I’ve just managed to reproduce the issue I’ve mentioned above (where the bade doesn’t update).

It’s super random, I had to wait for the script to stop and then update storage and repeat like 10 times and NOW I have a stack trace error:

Text version:

WebExtension context not found! ExtensionParent.sys.mjs:1362:13
    getContextById resource://gre/modules/ExtensionParent.sys.mjs:1362
    recvAPICall resource://gre/modules/ExtensionParent.sys.mjs:1181
    _recv resource://gre/modules/ConduitsChild.sys.mjs:90
    receiveMessage resource://gre/modules/ConduitsParent.sys.mjs:470
    (Async: JSActor query)
    _doSend resource://gre/modules/ConduitsChild.sys.mjs:64
    _send resource://gre/modules/ConduitsChild.sys.mjs:125
    callParentAsyncFunction resource://gre/modules/ExtensionChild.sys.mjs:900
    get chrome://extensions/content/child/ext-storage.js:318
    callAsyncFunction resource://gre/modules/ExtensionCommon.sys.mjs:1196
    callAsyncFunction resource://gre/modules/ExtensionChild.sys.mjs:726
    callAndLog resource://gre/modules/ExtensionChild.sys.mjs:706
    callAsyncFunction resource://gre/modules/ExtensionChild.sys.mjs:725
    stub resource://gre/modules/Schemas.sys.mjs:2954
    O moz-extension://6329fc15-83a7-467b-bd3d-f1a4a343afe0/background/background_sntd.js:1
    ae moz-extension://6329fc15-83a7-467b-bd3d-f1a4a343afe0/background/background_sntd.js:1
    InterpretGeneratorResume self-hosted:1417
    AsyncFunctionNext self-hosted:804
    (Async: async)
    <anonymous> moz-extension://6329fc15-83a7-467b-bd3d-f1a4a343afe0/background/background_sntd.js:1
    <anonymous> moz-extension://6329fc15-83a7-467b-bd3d-f1a4a343afe0/background/background_sntd.js:1

Something throws when the event should fire and that will fail to wake up the background script!

Please pass this to the devs, I’m still running 128.0b5 version.

I’ll go sleep now, good night :slight_smile:.

1 Like

Oh dang! Thanks for the update. Passing this on now.

Can you share the source of the extension that produced this error?

I’ve audited the code base to see if there is any way to end up in the state described in this thread. And the only explanation I can find is if the extension process has somehow crashed during the startup of the background script, which can be triggered by any of your extensions. When the extension process crashes, Firefox automatically tries to recover by starting it again, but gives up if there are more than 5 crashes within 30 seconds. After this, the extension process will only resume if there is a document load that needs to be hosted in the extension process, such as extension tabs, action popups, options pages.

When the extension process is revived successfully after the crash threshold had exceeded, the background page will still not restart automatically, with a few exceptions. One such exception is that the next runtime.sendMessage call (e.g. from an extension popup or a content script) will wake up the background page. This can explain your observed behavior with the Send Note to Device. The stack trace itself could be interpreted as the background page being terminated very suddenly, before Firefox has had a chance to process the browser.storage.sync.get() call (crxviewer link).

To check whether this is the case, could you report the outputs of the following three commands from the browser toolbox?

// Whether any crash has happened this browser session.
ChromeUtils.importESModule("resource://gre/modules/Extension.sys.mjs").ExtensionProcessCrashObserver.lastCrashedProcessChildID

// Whether there have been recent crashes.
ChromeUtils.importESModule("resource://gre/modules/Extension.sys.mjs").ExtensionProcessCrashObserver.lastCrashTimestamps

// Whether we stopped reviving the extension process due to too many crashes.
ChromeUtils.importESModule("resource://gre/modules/Extension.sys.mjs").ExtensionProcessCrashObserver.processSpawningDisabled

And also check about:crashes for any crashes, and if there are recent crashes, submit them and share the crash IDs here.

1 Like