Bug 1797558 Comment 23 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

Following on from Jeff's good work in comment 22: I'm not sure if there's a clever way to follow a callstack from C++ to java. But naively we can see the places in javascript which could call `FrameLoader_Binding::get_loadContext()` are quite few: https://searchfox.org/mozilla-central/search?q=symbol:%23loadContext&redirect=false

And with some `dump()`s we can narrow it down to [here](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#997).

With the devtools debugger I can see the javascript callstack is:

```
construct (chrome://global/content/elements/browser-custom-element.js#983)
connectedCallback (chrome://global/content/elements/browser-custom-element.js#324)
init (chrome://geckoview/content/geckoview.js#88)
startup (chrome://geckoview/content/geckoview.js#546)
<anonymous> (chrome://geckoview/content/geckoview.xhtml#12)
```

In [geckoview.xhtml](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/mobile/android/chrome/geckoview/geckoview.xhtml#12) we can see this comes from a "DOMContentLoaded" event. Which matches the `dom::Document::DispatchContentLoadedEvents()` call in the stacktrace just before it goes into javascript code. Neat!

Interestingly, when opening the broken tab, browser-custom-element.js' `construct()` function does in fact get called! But with a slightly different stacktrace:
```
construct (chrome://global/content/elements/browser-custom-element.js#983)
connectedCallback (chrome://global/content/elements/browser-custom-element.js#324)
init (chrome://geckoview/content/geckoview.js#89)
startup (chrome://geckoview/content/geckoview.js#548)
handleNewSession (resource://gre/modules/GeckoViewNavigation.jsm#379)
createContentWindow (resource://gre/modules/GeckoViewNavigation.jsm#414)
```

And crucially, `this.isRemoteBrowser` is `false` [here](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#984), meaning we never call `loadContext` (which eventually leads to calling `GetWindowRenderer()` / `CreateCompositor()`).

I guess (though haven't verified) that the reason this worked when `extensions.webextensions.remote` was `true` is that `isRemoteBrowser` would therefore be true.

One last thing to note is that when loading the other ublock pages in the steps to reproduce this bug, (eg the panel and the dashboard), when `construct()` is initially called the browser remoteness is `true`, meaning we create the compositor successfully, and then immediately afterwards `finishChangeRemoteness()` is called to make it false. But with the broken page, it is false from the beginning.

This is getting really far outside my sphere of knowledge now.. perhaps somebody else might know:
a) Why we don't call [this](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#995-998) code (which leads to creating the compositor) when `isRemoteBrowser` is false.
b) Why for the broken page `isRemoteBrowser` is initially false, whereas for other pages it starts off as true and is later switched to false.
Following on from Jeff's good work in comment 22: I'm not sure if there's a clever way to follow a callstack from C++ to javascript. But naively we can see the places in javascript which could call `FrameLoader_Binding::get_loadContext()` are quite few: https://searchfox.org/mozilla-central/search?q=symbol:%23loadContext&redirect=false

And with some `dump()`s we can narrow it down to [here](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#997).

With the devtools debugger I can see the javascript callstack is:

```
construct (chrome://global/content/elements/browser-custom-element.js#983)
connectedCallback (chrome://global/content/elements/browser-custom-element.js#324)
init (chrome://geckoview/content/geckoview.js#88)
startup (chrome://geckoview/content/geckoview.js#546)
<anonymous> (chrome://geckoview/content/geckoview.xhtml#12)
```

In [geckoview.xhtml](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/mobile/android/chrome/geckoview/geckoview.xhtml#12) we can see this comes from a "DOMContentLoaded" event. Which matches the `dom::Document::DispatchContentLoadedEvents()` call in the stacktrace just before it goes into javascript code. Neat!

Interestingly, when opening the broken tab, browser-custom-element.js' `construct()` function does in fact get called! But with a slightly different stacktrace:
```
construct (chrome://global/content/elements/browser-custom-element.js#983)
connectedCallback (chrome://global/content/elements/browser-custom-element.js#324)
init (chrome://geckoview/content/geckoview.js#89)
startup (chrome://geckoview/content/geckoview.js#548)
handleNewSession (resource://gre/modules/GeckoViewNavigation.jsm#379)
createContentWindow (resource://gre/modules/GeckoViewNavigation.jsm#414)
```

And crucially, `this.isRemoteBrowser` is `false` [here](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#984), meaning we never call `loadContext` (which eventually leads to calling `GetWindowRenderer()` / `CreateCompositor()`).

I guess (though haven't verified) that the reason this worked when `extensions.webextensions.remote` was `true` is that `isRemoteBrowser` would therefore be true.

One last thing to note is that when loading the other ublock pages in the steps to reproduce this bug, (eg the panel and the dashboard), when `construct()` is initially called the browser remoteness is `true`, meaning we create the compositor successfully, and then immediately afterwards `finishChangeRemoteness()` is called to make it false. But with the broken page, it is false from the beginning.

This is getting really far outside my sphere of knowledge now.. perhaps somebody else might know:
a) Why we don't call [this](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#995-998) code (which leads to creating the compositor) when `isRemoteBrowser` is false.
b) Why for the broken page `isRemoteBrowser` is initially false, whereas for other pages it starts off as true and is later switched to false.
Following on from Jeff's good work in comment 22 finding the stacktrace for when the compositor is created in the working case: I'm not sure if there's a clever way to follow a callstack from C++ to javascript. But naively we can see the places in javascript which could call `FrameLoader_Binding::get_loadContext()` are quite few: https://searchfox.org/mozilla-central/search?q=symbol:%23loadContext&redirect=false

And with some `dump()`s we can narrow it down to [here](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#997).

With the devtools debugger I can see the javascript callstack is:

```
construct (chrome://global/content/elements/browser-custom-element.js#983)
connectedCallback (chrome://global/content/elements/browser-custom-element.js#324)
init (chrome://geckoview/content/geckoview.js#88)
startup (chrome://geckoview/content/geckoview.js#546)
<anonymous> (chrome://geckoview/content/geckoview.xhtml#12)
```

In [geckoview.xhtml](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/mobile/android/chrome/geckoview/geckoview.xhtml#12) we can see this comes from a "DOMContentLoaded" event. Which matches the `dom::Document::DispatchContentLoadedEvents()` call in the native stacktrace just before it goes into javascript code. Neat!

Interestingly, when opening the broken tab, browser-custom-element.js' `construct()` function does in fact get called! But with a slightly different stacktrace:
```
construct (chrome://global/content/elements/browser-custom-element.js#983)
connectedCallback (chrome://global/content/elements/browser-custom-element.js#324)
init (chrome://geckoview/content/geckoview.js#89)
startup (chrome://geckoview/content/geckoview.js#548)
handleNewSession (resource://gre/modules/GeckoViewNavigation.jsm#379)
createContentWindow (resource://gre/modules/GeckoViewNavigation.jsm#414)
```

And crucially, `this.isRemoteBrowser` is `false` [here](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#984), meaning we never call `loadContext` (which eventually leads to calling `GetWindowRenderer()` / `CreateCompositor()`).

I guess (though haven't verified) that the reason this worked when `extensions.webextensions.remote` was `true` is that `isRemoteBrowser` would therefore be true.

One last thing to note is that when loading the other ublock pages in the steps to reproduce this bug, (eg the panel and the dashboard), when `construct()` is initially called the browser remoteness is `true`, meaning we create the compositor successfully, and then immediately afterwards `finishChangeRemoteness()` is called to make it false. But with the broken page, it is false from the beginning.

This is getting really far outside my sphere of knowledge now.. perhaps somebody else might know:
a) Why we don't call [this](https://searchfox.org/mozilla-central/rev/fb9a504ca73529fa550efe488db2a012a4bf5169/toolkit/content/widgets/browser-custom-element.js#995-998) code (which leads to creating the compositor) when `isRemoteBrowser` is false.
b) Why for the broken page `isRemoteBrowser` is initially false, whereas for other pages it starts off as true and is later switched to false.

Back to Bug 1797558 Comment 23