flypig.co.uk

Gecko-dev Diary

Starting in August 2023 I'll be upgrading the Sailfish OS browser from Gecko version ESR 78 to ESR 91. This page catalogues my progress.

Latest code changes are in the gecko-dev sailfishos-esr91 branch.

There is an index of all posts in case you want to jump to a particular day.

Gecko RSS feed Click the icon for the Gecko-dev Diary RSS feed.

Gecko

5 most recent items

16 Oct 2023 : Day 61 #
This morning I've woken up to two things I like. The autumn rain pouring down on the world outside (while I stay cosy and warm inside) and a completed build from yesterday. There's no better way to meet the day!

During the community meeting last week Raine pointed out that it might be sensible to comment out loading of embedhelper.js; so I thought I'd give that a go today. The code that does this is in qtmozembed:
    loadFrameScript(QStringLiteral("chrome://embedlite/content/embedhelper.js"));
After commenting this out the browser now crashes almost immediately on start up. We got ourselves a backtrace:
Thread 8 "GeckoWorkerThre" received signal SIGSEGV, Segmentation fault.
[Switching to LWP 31158]
mozilla::embedlite::BrowserChildHelper::DispatchMessageManagerMessage
    (this=0x7f8894f540, aMessageName=..., aJSONData=...)
    at mobile/sailfishos/utils/BrowserChildHelper.cpp:219
219	  RefPtr mm = kungFuDeathGrip->GetMessageManager();
(gdb) bt
#0  mozilla::embedlite::BrowserChildHelper::DispatchMessageManagerMessage
    (this=0x7f8894f540, aMessageName=..., aJSONData=...)
    at mobile/sailfishos/utils/BrowserChildHelper.cpp:219
#1  0x0000007fbcc861f4 in mozilla::embedlite::EmbedLiteViewChild::RecvAsyncMessage
    (this=0x7f885d83b0, aMessage=..., aData=...)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/RefPtr.h:313
#2  0x0000007fba30b5b8 in mozilla::embedlite::PEmbedLiteViewChild::
    OnMessageReceived (this=0x7f885d83b0, msg__=...) at PEmbedLiteViewChild.cpp:2560
#3  0x0000007fba2f6e24 in mozilla::embedlite::PEmbedLiteAppChild::
    OnMessageReceived (this=, msg__=...)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/ipc/
    ProtocolUtils.h:675
#4  0x0000007fba1e3630 in mozilla::ipc::MessageChannel::DispatchAsyncMessage
    (this=this@entry=0x7f888b7658, aProxy=aProxy@entry=0x7ec4001b40, aMsg=...)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/ipc/
    ProtocolUtils.h:675
#5  0x0000007fba1f20ac in mozilla::ipc::MessageChannel::DispatchMessage
    (this=this@entry=0x7f888b7658, aMsg=...)
    at ipc/glue/MessageChannel.cpp:2001
#6  0x0000007fba1f3504 in mozilla::ipc::MessageChannel::RunMessage
    (this=0x7f888b7658, aTask=...)
    at ipc/glue/MessageChannel.cpp:1860
#7  0x0000007fba1f3664 in mozilla::ipc::MessageChannel::MessageTask::Run
    (this=0x5555e39de0)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/ipc/
    MessageChannel.h:588
#8  0x0000007fb9e03bc0 in mozilla::RunnableTask::Run (this=0x55559588f0)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/RefPtr.h:313
[...]
#30 0x0000007fb79cf89c in ?? () from /lib64/libc.so.6
(gdb) p kungFuDeathGrip
$1 = {mRawPtr = 0x0}
(gdb) p mBrowserChildMessageManager
$2 = {mRawPtr = 0x0}
(gdb) 
The reason for the crash is pretty clear from those null pointers at the end. So why is mBrowserChildMessageManager null? It's supposed to be instantiated in InitBrowserChildHelperMessageManager() like this:
bool
BrowserChildHelper::InitBrowserChildHelperMessageManager()
{
  mShouldSendWebProgressEventsToParent = true;

  if (mBrowserChildMessageManager) {
    return true;
  }

  nsCOMPtr window = do_GetInterface(WebNavigation());
  NS_ENSURE_TRUE(window, false);
  RefPtr chromeHandler(window->GetChromeEventHandler());
  NS_ENSURE_TRUE(chromeHandler, false);

  RefPtr scope = mBrowserChildMessageManager =
      new BrowserChildHelperMessageManager(this);

  MOZ_ALWAYS_TRUE(nsMessageManagerScriptExecutor::Init());

  nsCOMPtr root = do_QueryInterface(chromeHandler);
  if (NS_WARN_IF(!root)) {
    mBrowserChildMessageManager = nullptr;
    return false;
  }
  root->SetParentTarget(scope);

  RefPtr wasvc = JSActorService::GetSingleton();
  wasvc->RegisterChromeEventTarget(scope);

  return true;
}
By stepping through the code I can see that it's not getting as far as constructing the BrowserChildHelperMessageManager() because do_GetInterface(WebNavigation()) is returning null and the method is being exited on this line:
  NS_ENSURE_TRUE(window, false);
This line is the Mozilla way (NS stands for "Netscape" I think) "Ensure window is non-zero; if it isn't, then leave the method with a return value of false".

The underlying problem then, is that mWebNavigation isn't being set, and the only way that can happen is through a call to BrowserChildHelper::SetWebNavigation().

It turns out that this is being called, but too late in the day. So it may be that this can be fixed by tightening up the ordering. Or it may be that the null value just needs to be masked out.

These two are in the wrong order. Here's the first call that should be setting the value:
Thread 8 "GeckoWorkerThre" hit Breakpoint 1, mozilla::embedlite::
    BrowserChildHelper::InitBrowserChildHelperMessageManager
    (this=this@entry=0x7f885d8780)
    at mobile/sailfishos/utils/BrowserChildHelper.cpp:253
253	{
(gdb) bt
#0  mozilla::embedlite::BrowserChildHelper::InitBrowserChildHelperMessageManager
    (this=this@entry=0x7f885d8780)
    at mobile/sailfishos/utils/BrowserChildHelper.cpp:253
#1  0x0000007fbcc9c80c in mozilla::embedlite::BrowserChildHelper::
    BrowserChildHelper (this=0x7f885d8780, aView=,
    aId=)
    at mobile/sailfishos/utils/BrowserChildHelper.cpp:103
#2  0x0000007fbcc912f4 in mozilla::embedlite::EmbedLiteViewChild::InitGeckoWindow
    (this=0x7f885d6960, parentId=, parentBrowsingContext=
    0x0, isPrivateWindow=false, isDesktopMode=false)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/cxxalloc.h:33
#3  0x0000007fbcc829f4 in mozilla::detail::RunnableMethodArguments::
    applyImpl, StoreRefPtrPassByPtr
    , StoreCopyPassByConstLRef,
    StoreCopyPassByConstLRef, 0ul, 1ul, 2ul, 3ul>
    (args=..., m=, o=)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/RefPtr.h:280
[...]
#28 0x0000007fb79cf89c in ?? () from /lib64/libc.so.6
(gdb) 
And here's the second one that's the trigger that allows the first call to work successfully:
Thread 8 "GeckoWorkerThre" hit Breakpoint 2, mozilla::embedlite::
    BrowserChildHelper::SetWebNavigation
    (this=0x7f885d8780, aWebNavigation=0x7f885d9878)
    at mobile/sailfishos/utils/BrowserChildHelper.cpp:702
702	void BrowserChildHelper::SetWebNavigation(nsIWebNavigation *aWebNavigation) {
(gdb) bt
#0  mozilla::embedlite::BrowserChildHelper::SetWebNavigation (this=0x7f885d8780,
    aWebNavigation=0x7f885d9878)
    at mobile/sailfishos/utils/BrowserChildHelper.cpp:702
#1  0x0000007fbcc91474 in mozilla::embedlite::EmbedLiteViewChild::InitGeckoWindow
    (this=0x7f885d6960, parentId=, 
    parentBrowsingContext=0x0, isPrivateWindow=,
    isDesktopMode=false)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/RefPtr.h:313
#2  0x0000007fbcc829f4 in mozilla::detail::RunnableMethodArguments
    ::applyImpl, StoreRefPtrPassByPtr,
    StoreCopyPassByConstLRef, StoreCopyPassByConstLRef,
    0ul, 1ul, 2ul, 3ul> (args=..., m=, o=)
    at ${PROJECT}/..//obj-build-mer-qt-xr/dist/include/mozilla/RefPtr.h:280
[...]
#27 0x0000007fb79cf89c in ?? () from /lib64/libc.so.6
(gdb) 
From the backtraces we can see that both are being called from inside EmbedLiteViewChild::InitGeckoWindow(). The first on line 267, then the second on line 322.

I've made just a small tweak to the code, so that the value now gets set slightly later at a position where it's more likely to succeed. In fact it attempts to set it twice. First on line 267 as before, but now also directly after line 322, in the hope that the second time it will succeed.
  mHelper->SetWebNavigation(mWebNavigation);
  
  // Attempt this again, just in case it failed the first time
  mChrome->SetBrowserChildHelper(mHelper.get());
None of this should be necessary to get a working browser, but it will help at this still early stage to get things working before we re-establish the proper loading of embedhelper.js.

But now I'm having to build another version, so that's it for today.

Here's hoping tomorrow morning starts as well as today with a completed build!

As always, if you'd like to read more about all this gecko stuff, do take a look at my full Gecko Dev Diary.

Comments

Uncover Disqus comments