Open Bug 1811826 Opened 2 years ago Updated 1 year ago

`Services.intl` or `Services.clearData` may be undefined if the first instantiation is via devtools / debugger eager evaluation

Categories

(Core :: XPCOM, defect)

Firefox 105
defect

Tracking

()

People

(Reporter: 6k64x4ma, Unassigned, NeedInfo)

References

Details

Attachments

(1 file)

Attached image screenshot.webp (deleted) —

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0

Steps to reproduce:

  1. Launch Firefox with a new profile.
  2. Set devtools.chrome.enabled to true.
  3. Run Services.intl; and Services.clearData; in the Browser Console.

Actual results:

  • Services.intl or Services.clearData may be undefined.
uncaught exception: undefined debugger eval code:1:1
    <anonymous> debugger eval code:1
    getEvalResult resource://devtools/server/actors/webconsole/eval-with-debugger.js:245
    evalWithDebugger resource://devtools/server/actors/webconsole/eval-with-debugger.js:166
    evaluateJS resource://devtools/server/actors/webconsole.js:983
    evaluateJSAsync resource://devtools/server/actors/webconsole.js:874
    makeInfallible resource://devtools/shared/ThreadSafeDevToolsUtils.js:103
Uncaught 
Exception { name: "NS_ERROR_FAILURE", message: "", result: 2147500037, filename: "debugger eval code", lineNumber: 1, columnNumber: 0, data: null, stack: "@debugger eval code:1:1\ngetEvalResult@resource://devtools/server/actors/webconsole/eval-with-debugger.js:245:24\nexports.evalWithDebugger@resource://devtools/server/actors/webconsole/eval-with-debugger.js:166:14\nevaluateJS@resource://devtools/server/actors/webconsole.js:983:38\nevaluateJSAsync/<@resource://devtools/server/actors/webconsole.js:874:35\nexports.makeInfallible/<@resource://devtools/shared/ThreadSafeDevToolsUtils.js:103:22\n", location: XPCWrappedNative_NoHelper }
debugger eval code:1:1
    <anonymous> debugger eval code:1
  • This happens intermittently. Restarting Firefox will change the result.
    At least I can reproduce this issue on 2022-07-26's Nightly.

Expected results:

Services.intl and Services.clearData should be defined.

The Bugbug bot thinks this bug should belong to the 'Core::Internationalization' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Internationalization
Product: Firefox → Core

The severity field is not set for this bug.
:m_kato, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(m_kato)

devtools issue?

Component: Internationalization → General
Flags: needinfo?(m_kato)
Product: Core → DevTools
Flags: needinfo?(nchevobbe)
Status: UNCONFIRMED → NEW
Ever confirmed: true

I can only reproduce intermitently, mostly on clearData, sometimes I'll be able to evaluate just fine.
I wonder if there's some kind of race condition with the switch to esm files (both intl and clearData use esm)
Let's ask people handling xpcom

Component: General → XPCOM
Flags: needinfo?(nchevobbe)
Product: DevTools → Core

The severity field is not set for this bug.
:nika, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(nika)

I poked around with this a bit. It seems like there's something strange happening with how we end up initializing the service and performing the import during DevTools eager evaluation.

If e.g. Services.intl fails to import, it appears that happens with an undefined exception while evaluating the module. The module is then errored, and even calls to ChromeUtils.importESModule("resource://gre/modules/mozIntl.sys.mjs") will throw an exception.

In contrast, if you first call ChromeUtils.importESModule("resource://gre/modules/mozIntl.sys.mjs"), it will succeed, and then calling Services.intl will also succeed afterwards. However, the success is a bit odd. It seems like the first eager execution of the resolver to show the light gray predicted result text in the debugger will fail (though this time when trying to evaluate the object's constructor, rather than when evaluating the module, as the module's result was cached by the call to ChromeUtils.importESModule), and only the second (non-eager) call will succeed.

I'm thinking that this is a poor interaction between the way that the devtools eager evaluation code interacts with module imports under the hood. I'm guessing that we set some state when in this speculative evaluation which prevents some operations from succeeding (e.g. importing & evaluating a new ESModule), but this is unfortunately happening in such a way that the ESModule evaluation being errored out is actually being cached, meaning that not only does the failure during speculation occur, but the failure is cached for every future call as well.

I tested this a bit by accessing Services.intl but in a roundabout way which would not eagerly evaluate the access in the console (specifically ((y, x) => Services[x])(console.log("hi"), "intl")), and entering & running that prompt succeeded, which aligns with my assumption that an error when evaluating the ESModule when resolving Services.intl eagerly is occuring and then being cached.

Unfortunately I don't exactly know how the eager execution logic is handled off the top of my head. As far as I can tell it appears that the script is run with a special "side-effect free debugger" (https://searchfox.org/mozilla-central/rev/edccfac5746704da49c1551aed8b79f57003bd68/devtools/server/actors/webconsole/eval-with-debugger.js#369), which is supposed to prevent side-effects from being executed. I'm guessing that this fails to detect the resolver for Services as side-effectful, perhaps because it is neither a getter nor a function call so won't be caught by the onNativeCall method. We then end up instead preventing side-effects when evaluting the module, and caching that error.

Redirecting the ni? back to devtools.

Flags: needinfo?(nika) → needinfo?(jdescottes)
Flags: needinfo?(jdescottes) → needinfo?(nchevobbe)
Summary: `Services.intl` or `Services.clearData` may be undefined → `Services.intl` or `Services.clearData` may be undefined if the first instantiation is via devtools / debugger eager evaluation
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: